GithubHelp home page GithubHelp logo

Comments (67)

ChasLui avatar ChasLui commented on May 31, 2024 10
var let const
变量提升 Y N N
覆盖全局变量 Y N N
重复声明 Y N N
暂时性死区 N Y Y
块作用域 N Y Y
只声明不初始化 Y Y N
重新赋值 Y Y N

from step-by-step.

0uzu0 avatar 0uzu0 commented on May 31, 2024 7

表

from step-by-step.

xdandsl avatar xdandsl commented on May 31, 2024 2

1,什么时候提出的?

var是ES5提出的,let和const是ES6提出的。

2,是否存在变量提升?

var声明的变量存在变量提升(将变量提升到当前作用域的顶部)。即变量可以在声明之前调用,值为undefined。
let和const不存在变量提升。即它们所声明的变量一定要在声明后使用,否则报错。

3,是否存在暂时性死区?

let和const存在暂时性死区。即只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
**在代码块内,使用let命令声明变量之前,该变量都是不可用的。**这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。

4,是否允许重复声明变量?

var允许重复声明变量。let和const在同一作用域不允许重复声明变量。

5,是否存在块级作用域?

var不存在块级作用域。let和const存在块级作用域。
到底什么叫块级作用域呢,
JS中作用域有:全局作用域、函数作用域。没有块作用域的概念。ECMAScript 6(简称ES6)中新增了块级作用域。块作用域由 { } 包括,if语句和for语句里面的{ }也属于块作用域。

6,是否能修改声明的变量?

var和let可以。
const声明一个只读的常量。一旦声明,常量的值就不能改变。const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。

from step-by-step.

YvetteLau avatar YvetteLau commented on May 31, 2024 2

1.let/const 定义的变量不会出现变量提升,而 var 定义的变量会提升。

a = 10;
var a; //正常
a = 10;
let a; //ReferenceError

2.let 和 const 不允许重复声明,var 允许重复声明。

let a = 10;
var a = 20;
//抛出异常:SyntaxError: Identifier 'a' has already been declared

3.const 声明一个只读的常量,这个常量不可改变。const声明变量时必须赋值。

这里有一个非常重要的点即是:复杂数据类型,存储在栈中的是堆内存的地址,存在栈中的这个地址是不变的,但是存在堆中的值是可以变得。有没有相当常量指针/指针常量~

const a = 20;
const b = {
    age: 18,
    star: 500
}

一图胜万言,如下图所示,不变的是栈内存中 a 存储的 10,和 b 中存储的 0x0012ff21(瞎编的一个数字)。而 {age: 18, star: 200} 是可变的。思考下如果想希望一个对象是不可变的,应该用什么方法?

4.let/const 声明的变量仅在块级作用域中有效。而 var 声明的变量在块级作用域外仍能访问到。

{
    let a = 10;
    const b = 20;
    var c = 30;
}
console.log(a); //ReferenceError
console.log(b); //ReferenceError
console.log(c); //30

在 let/const 之前,最早学习JS的时候,也曾被下面这个问题困扰:

var a = [];
for (var i = 0; i < 10; i++) {
    a[i] = function () {
        console.log(i);
    };
}
a[6](); // 10

虽然后来知道了为什么,但是想要得到自己需要的结果,还得整个闭包,我...我做错了什么,要这么对我...

var a = [];
for (var i = 0; i < 10; i++) {
    a[i] = (function(j){
        return function () {
            console.log(j);
        }
    })(i)
}
a[6](); // 6

有了 let 之后,终于不要这么麻烦了。

var a = [];
for (let i = 0; i < 10; i++) {
    a[i] = function () {
        console.log(i);
    };
}
a[6](); // 6

美滋滋,有没有~

美是美了,但是总得问自己为什么吧~

第一个 var i 为什么输出的是 10,这是因为 i 在全局范围内都是有效的,相当于只有一个变量 i,等执行到 a[6]() 的时候,这个 i 的值是什么?请大声说出来。

再看 let , 我们说 let 声明的变量仅在块级作用域内有效,变量i是let声明的,当前的 i 只在本轮循环有效,所以每一次循环的 i 其实都是一个新的变量。有兴趣的小伙伴可以使用看一下 babel 编译后的代码。

5.顶层作用域中 var 声明的变量挂在window上(浏览器环境)

var a = 10;
console.log(window.a);//10

6.let/const有暂时性死区的问题,即let/const 声明的变量,在定义之前都是不可用的。如果使用会抛出错误。

只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。

var a = 10;
if (true) {
  a = 20; // ReferenceError
  let a;
}

在代码块内,使用 let/const 命令声明变量之前,该变量都是不可用的,也就意味着 typeof 不再是一个百分百安全的操作。

console.log(typeof b);//undefined

console.log(a); //ReferenceError
let a = 10;

from step-by-step.

yuzhang9804 avatar yuzhang9804 commented on May 31, 2024 1
  • let 和 var 声明一个变量, const 声明一个只读的常量
  • let 和 const 不存在变量提升, var会发生变量提升
  • let和const存在暂时性死区, 凡是在声明之前使用这些变量就会报错
  • let 和 const 不允许在相同作用域内, 重复声明一个变量
  • let 和 const 存在块级作用域
  • const 保证的变量保存的数据不得改动, 但如果将一个对象声明为变量, const只能保证这个指针是固定的, 对于它指向的数据结构就不能控制
const person = {
	name: `zhang`
}
person.name = `yu`;
console.log(person.name);		// `yu`

from step-by-step.

jodiezhang avatar jodiezhang commented on May 31, 2024 1

let 和 const都是ES6新增的
在let和const没有出来的时候,JS没有块级作用域,只有全局作用域函数作用域

  for(var i=0;i<10;i++){
          var a = 'a';
    }

    console.log(a);

比如上面这个例子,已经不在for循环中了,已经跳出这个块了,我们还是能打印出 a
再看下面这个例子

for (var i = 0; i < 3; i++) {
      setTimeout(function () {
        console.log(i)
      }, 1000);
 }


3 3 3 而不是 1 2 3
循环本身以及三次timeout回调共享了变量i

let的出现让变量拥有块级作用域,把上面的var 换成 let 可以完美解决问题。

我们总结一下var ,let, const 的区别
1.变量提升
var

console.log(a);//undefined
var a=2;

let

console.log(a);//Uncaught ReferenceError: Cannot access 'a' before initialization
var a=2;

const

console.log(a);//Uncaught ReferenceError: Cannot access 'a' before initialization
const a=2;

2.暂时性死区
作用域中声明了let变量,但是let变量的使用却在声明之前,这通常叫做变量提升。
但是let并不像var一样,var变量声明前使用,会打印出undefined.但是let变量直到被赋值才会被初始化。
在变量被初始化前访问这个变量会报reference error.我们称这个变量在作用域开始到被初始化之间为暂时性死区。

function do_something() {
  console.log(bar); // undefined
  console.log(foo); // ReferenceError

  var bar = 1;
  let foo = 2;

}

3.重复声明

 let a=1;
 let a=2;

//报错

 const a=1;
 const a=2;

//报错

 var a=1;
 var a=2;

//不报错

4.重新赋值

var和let可以重新赋值,但是const不可以,而且const 必须声明的时候就初始化。

from step-by-step.

jackluson avatar jackluson commented on May 31, 2024 1
  1. var是js申明变量最原始的一种,let,const是es6新语法,主要是弥补了类似其他语言申明常量,变量,块作用域方面的不足,
  2. let可以让变量有块级作用域,比如这个例子
for (var i = 0; i < 3; i++) {
     setTimeout(function () {
       console.log(i) // 0,1,2 如果用var 打印出来就是333
     }, 1000);
}
3. const定义常量(申明时必须有初始值),let定义变量,两者不存在变量提升,先申明在使用,而且不能重复申明

from step-by-step.

jiangtao avatar jiangtao commented on May 31, 2024 1

最近在读<深入理解ES6>一书中,提起 let/const 这也是平常工作用的比较多,最近需要给公司做培训. 重新复习下以往的知识点.

本文首发自 github 个人博客.

let/const

再聊 let/const之前, 让我们回顾下我们的老朋友 var, 他有什么特点或特性

var

通过下面的例子, 可以复习下, 关键字var声明带来的影响.

console.log(typeof A) // 'function'
console.log(a) // undefined
console.log(typeof a) // 'undefined'
console.log(typeof Date) // 'function'
console.log(window.Date) // function Date() {}
function A() {
    console.log(new Date())
}
var a = 10
var Date = 1000
console.log(window.Date) // 1000

由于变量提升的缘故, function 优先于 var提升且定义,此时 a只声明,未赋值,函数已声明且赋值.

同样的代码,把window改成global放在node里面运行发现结果又不一样, global.Date没有被重新赋值, 是因为在node运行环境里面, node 出于代码安全考虑, 每一个文件最终变成了由 require('module').wrapper方法包裹起来, 每一个node的 js 文件, 需要 通过exports或module.exports暴露出模块的方法和属性才能使用.

由此可见 var声明会带来以下影响

  • 变量提升 (一不小心就掉坑, 非前端开发者会很郁闷)
  • 会覆盖/污染 (当前)作用域的变量

通常的习惯可能是, 放在 top scope 的位置, 作为一个规范来约束自己或团队.

但并不是每个人都能很好的按照规范来做, 于是ES6 推出了 let/const来解决var声明的弊端

let/const

把上面的代码换成 let

console.log(a) // Uncaught ReferenceError: Cannot access 'a' before initialization
console.log(typeof a) // 'undefined'
console.log(typeof Date) // 'function'
console.log(window.Date) // function Date() {}

之前执行的 console.log(a) 直接报错, 阻止程序运行.

直接运行console.log(typeof a) 也一样, 而不做任何声明的时候, 会输出 'undefined'.

let a = 10
let Date = 1000
console.log(window.Date) // function Date() {}
console.log(a) // 10
console.log(Date) // 1000
console.log(window.a) // undefined

正常逻辑执行后, 并没有想象中, window.aa相等. 产生上面现象的原因是什么呢??

暂时性死区(temporal dead zone, TDZ)

let/const声明前访问其变量会造成初始化之前不能访问,这种现象叫做 TDZ.

let/const不会对 scope 域名做覆盖/污染

上述例子中, aDate声明后并没有污染 window.awindow.Date, 因此当使用的时候需要覆盖的时候使用 let/const 声明的变量, 需要手动覆盖.

循环中形成新的块级绑定

早年有一个经典的面试题, 叫做 创建10 个 div.点击输出对应的索引.

笔者在初次写 js 的时候, 写成了这种错误形式

// bad way
for(var i = 0; i < 10; i++) {
    var div = document.createElement('div')
    div.className = 'item'
    div.innerHTML = i
    div.onclick = function() {
        alert(i)
    }
    document.body.appendChild(div)
}

输出的结果也往往是 10, 需求是点击索引啊. 造成这种结果的原因是

var变量提升, 当点击的时候此时 i 是 10

因此我们常常用 IIFE(即时执行函数)

// good way
for(var i = 0; i < 10; i++) {
    var div = document.createElement('div')
    div.className = 'item'
    div.innerHTML = i
    div.onclick = (function(i) {
        return function() {
            alert(i)
        }
    })(i)
    document.body.appendChild(div)
}

那有木有更好的方案, 能不能每次 循环的时候创建一个新的 i, let具备这一特性

// better way
for (let i = 0; i < 10; i++) {
    let div = document.createElement("div");
    div.className = "item";
    div.innerHTML = i;
    div.onclick = function() {
        alert(i)
    }
    document.body.appendChild(div);
}

其他

const用来保存常量, let 在修改的使用. const 对对象处理的时候, 对象/数组属性赋值还可以修改.

关于对象的常量问题, 放到后面章节整理.

from step-by-step.

Jinminrui avatar Jinminrui commented on May 31, 2024

let 和 const 都是块级声明的一种。
块级声明用于声明在指定块的作用域之外无法访问的变量。
let 和 const 不同于 var 的特点如下:

  1. 不存在变量提升
  2. 不可以重复声明
  3. 不绑定全局作用域

let 和 const 的区别:
const 用于声明常量,其值一旦被设定不能再被修改,否则会报错。
此外,const 声明不允许修改绑定,但允许修改值。这意味着可以修改const声明的对象中的属性。

from step-by-step.

shenanheng avatar shenanheng commented on May 31, 2024

var的作用:
a:可以声明变量以及常量
b:可以变量提升,默认为undefined,当运行到给变量赋值才会赋值
c:作用域为函数作用域
d:允许在相同作用域内, 重复声明一个变量

let与const:

相同点:
a:作用域为块作用域
b:没有函数提升
c:不允许在相同作用域内, 重复声明一个变量

异同点:
a:let一般声明的是变量(也可以弄为常量,不建议);const声明的是常量(必须初始化),当为对象的时候属性的值是可以改变的

from step-by-step.

mcDullLi avatar mcDullLi commented on May 31, 2024

let和const声明都在代码块内有效。不存在变量提升。相同作用域内,不能重复命名。
const声明的是只读常量,指向的内存地址不能改动。一旦声明,必须立即初始化。
var用于声明在函数作用域内有效,允许变量提升。相同作用域内,可以重复声明

from step-by-step.

lianbo666 avatar lianbo666 commented on May 31, 2024

全局声明的var变量会挂载到window上,而let和const不会;
var声明变量存在变量提升,let和const不会;
let,const的作用范围是块级作用域,而var的作用范围是函数作用域;
同一作用域下let和const不能同时声明同名变量,而var可以;
同一作用域下在let和const声明前使用会存在暂时性死区;
对于const来说:一旦声明必须赋值,不能使用null占位,声明后不能再修改,如果声明的是复合类型数据,可以修改其属性

from step-by-step.

killbymywind avatar killbymywind commented on May 31, 2024

let和const都是作用于代码块的声明,var 的作用域是当前 scope 的所有子作用域,包括当前作用域中声明或调用的函数或是 while / for / if / try-catch 语法区块。let和const都是es5,es6新版本的js语言规范出来的定义,在这以前定义一个变量只能用var。var存在变量提升,let,const不存在。let,const不允许重复声明同一变量,而var可以

from step-by-step.

freeshineit avatar freeshineit commented on May 31, 2024

var [ECMAScript 1st Edition (ECMA-262)规范]

  • var 存在变量提升(可以在使用之后定义,值为undefined)
  • 作用在函数作用域上

let [ECMAScript 2015 (6th Edition, ECMA-262)规范]

  • let 语句声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
  • let 定义的变量 必须先定义后使用

const[ECMAScript 2015 (6th Edition, ECMA-262)规范]

  • 作用在块级作用域上
  • 定义时就要赋值
  • 一般是用来定义常量(变量值不允许重新赋值)

var vs let vs const in JavaScript

JavaScript中var、let、const区别?

from step-by-step.

zihuasunshine avatar zihuasunshine commented on May 31, 2024
  1. let、const是块级作用域
  2. let、const不存在变量提升,要先声明才能使用, 如果在声明之前使用,会报错,被称为‘暂时性死区’,这意味typeof不再是一个百分之百的操作
  3. let、const在相同作用域不允许重复声明
  4. const声明不赋值会报错,一旦赋值就不允许改变,对于复杂数据类型,不允许改变是指不能改变引用类型的指向。
    5.顶层let、const声明的变量,不会成为global对象的属性;

from step-by-step.

woyiweita avatar woyiweita commented on May 31, 2024

var

  • 声明变量
  • 可以重复多次声明,后声明的会覆盖先声明的
  • 没有块级作用域
  • 变量可以被改写
  • 变量可提升,提前访问返回undefined

let

  • ES6新提出的变量声明关键字,用于声明变量
  • 有块级作用域
  • 不可重复多次声明
  • 变量可以被改写
  • 变量不提升,先声明再应用,提前访问提示错误信息

const

  • ES6新提出的常量声明关键字,用于声明常量
  • 有块级作用域
  • 不可重复多次声明
  • 常量值如果是基础数据类型,不可改写,如果是引用数据类型,不可改写常量指针,但可修改对象属性及属性值
  • 常量不提升,需要先声明再应用,提前访问提示错误信息
  • 常量声明时就需要完成赋值操作

from step-by-step.

daibin0809 avatar daibin0809 commented on May 31, 2024
  • var与let/const的区别
    1. var声明在在方法内为全局变量,声明在方法外为局部变量;let/const无法声明为全局变量。
    2. var存在变量提升,在赋值前为undefinedlet存在暂时性死区,块级作用域中使用了let声明就会'绑定'区域,声明前不能使用;const声明时必须赋值。
    3. var不存在块级作用域;let/const存在。
    4. for循环中计数变量为var时,只存在一个变量;let/const每次循环都是一个新的变量,与循环体为不同作用域。
    5. var可重复声明,let/const在作用域中不允许重复声明。
  • let与const的区别
    1. const声明时必须赋值。
    2. const声明后不可改变。不可改变指的是地址,而不是值。

from step-by-step.

xiatiandenixi avatar xiatiandenixi commented on May 31, 2024
  1. const和let存在块级作用域,var不存在。
  2. const和let存在暂时性死区,var不存在。
  3. var存在变量提升,const和let木有。
  4. const 声明变量时需要赋值,var和let不需要。
  5. const和let不可重复声明变量,var可以。

from step-by-step.

AILINGANGEL avatar AILINGANGEL commented on May 31, 2024

1.变量提升

var会进行变量提升,let和const不会进行提升

2.暂存死区

因为var会进行变量提升,所以可以在声明之前访问,不会形成暂存死区。let 和const 不会进行变量提升,在声明之前不能使用,形成暂存死区

3.重复声明

var可以进行重复声明,但是let和const不能进行重复声明

4.块作用域

var不会形成块作用域,let和const可以形成块作用域

5.重新赋值

var和let声明的变量可以重新赋值,const不可以。如果const 声明的变量存储的是引用地址, 是可以修改这个引用对应的对象的值的,但是这个变量不能被赋予其他值

from step-by-step.

riluocanyang avatar riluocanyang commented on May 31, 2024

let、const、var的区别有哪些?

js本身只有全局作用域和函数作用域,let和const的出现,使得js有了块级作用域。
1、var 声明的变量可以重复,而let、const则不可以;
2、var 声明的变量可以提升,而let、const则不可以;
3、let声明的变量的值可以更改,而const声明的是常量,则不可以,如果const声明的一个对象,则对象中的属性值可以改变;
4、for循环中用var 声明的变量可以在for循环外访问到,而let则不可以。

for(var i = 0; i < 10; i++) {
}
console.log(i)    // 10
for(let j = 0; j < 10; j++) {
}
console.log(j)   // Uncaught ReferenceError: j is not defined

from step-by-step.

shenshuangdao avatar shenshuangdao commented on May 31, 2024

1、var和let声明一个变量, const 声明一个只读的常量;
const保存对象时保存的是一个地址的指针,所以可以修改对象的值:

2、const必须在声明的时候就初始化,var和let不用;

3、var可以重复声明,let和const不可以;

4、var会声明提前,let和const不会声明提前,let 和 const 存在暂时性死区, 凡是在声明之前使用这些变量就会报错;

----暂时性死区:当程序的控制流程在新的作用域进行实例化时,在此作用域中用let/const声明的变量会先在作用域中被创建出来,但因此时还未进行词法绑定(对声明语句进行求值运算),所以不能被访问(访问就会抛出错误)。所以在这运行流程进入作用域创建变量,到变量开始被访问之间的一段时间,就称之为temporal dead zone,简称TDZ。

5、let和const 是块级作用域,var不是

6、var声明最外层是在全局下建一个变量,let和const不会

7、let和const 是ES6新命令

(本来也想画个图发现前面的图已经很好了果然都是大佬。。。)

from step-by-step.

Liruimin2 avatar Liruimin2 commented on May 31, 2024
  • var 定义变量变量会提升,let const不会变量提升let 和 const 存在块级作用域
  • let 和 var 声明一个变量, const 声明一个只读的常量,const一旦定义了不能修改
  • let和const存在暂时性死区, 凡是在声明之前使用这些变量就会报错
  • let 和 const 不允许在相同作用域内, 重复声明一个变量

from step-by-step.

xiaokinglong avatar xiaokinglong commented on May 31, 2024
  1. var 声明的变量会提升, 而letconst不会提升变量
console.log(a) // 打印的是undefined
var a = 10
console.log(b) // 直接报错
let b = 10
console.log(c) // 直接报错
const c = 10
  1. 使用var声明的变量的没有块级作用域, 而使用的letconst是有块级作用域的
{
var a = 10
}
console.log(a) // 10
{
let b = 10
}
console.log(a) // 直接报错 b 未定义
{
const c = 10
}
console.log(c) // 和let一样
  1. var可以相同的作用域中重复定义的一个变量,而letconst使用不可以的
  2. 在相同的作用域中let声明的变量是可以重新的赋值的, 而使用的const声明的变量时候就给变量赋值, 之后也不能重新赋值
{
let a = 100;
a = 10;
console.log(a) // 10
}

{
const b; // 直接报错
console.log(b)
const c = 10;
c = 100 ;// 直接报错
}

from step-by-step.

callmebetter avatar callmebetter commented on May 31, 2024

let、const是ES6声明变量的方式,与var相比:

  • const、let声明的变量具有块级作用域
  • const、let声明的变量无法在当前作用域范围内重复声明
  • const、let只能先声明再使用

let、const对比

  • const声明的变量不能再次赋值,但是引用类型的值依然可以改变
  • const声明的变量必须初始化

from step-by-step.

gaoluona avatar gaoluona commented on May 31, 2024
  • let 声明一个变量,仅可在声明变量的块级作用域使用

  • const 声明一个只读常量,不可修改,与 let 同存在块级作用域

  • var 声明一个变量,变量可提升,在声明前就可以使用,变量可重复声明

from step-by-step.

lqzo avatar lqzo commented on May 31, 2024
  1. 作用域
    let 声明的变量 和 const 声明的常量只在声明所在的块级作用域内有效;var 声明的变量的作用域是函数作用域。
if (true) {
  const MAX = 5;
  let a = 10;
  var b = 1;

  MAX // 5
  a // 10
  b // 1
}
MAX // Uncaught ReferenceError: MAX is not defined
a // ReferenceError: a is not defined.
b // 1
  1. 重复声明
    let 和 const 不允许在相同作用域内重复声明;var 可以。
let foo;
let foo; // TypeError thrown.
  1. 声明提前(变量提升)
    var 声明会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined;let 和 const 不会。

  2. 暂时性死区
    let 和 const 存在暂时性死区, 凡是在声明之前使用这些变量就会报错;var 不存在。

function do_something() {
  console.log(bar); // undefined
  console.log(foo); // ReferenceError: foo is not defined
  var bar = 1;
  let foo = 2;
}

ES6 规定暂时性死区和let、const语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。
暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。

  1. 重新赋值
    let 和 var 声明的变量可以重新赋值;
    const 声明的是常量,不得改变值,这意味着,const一旦声明,就必须立即初始化,不能留到以后赋值。
const foo;
// SyntaxError: Missing initializer in const declaration
// 对于const来说,只声明不赋值,就会报错。

let 和 const 作为 ES6 新增的命令,相较 var 有更多的特性,更多内容可以点击下面链接查看:
var - JavaScript | MDN
let - JavaScript | MDN
const - JavaScript | MDN
let 和 const 命令 - ECMAScript 6 入门

from step-by-step.

0xe69e97 avatar 0xe69e97 commented on May 31, 2024

let 局部作用域变量,有暂时性死区特性
const 局部作用域常量,有暂时性死区特性
var 变量提升特性

from step-by-step.

darlingyz avatar darlingyz commented on May 31, 2024

let const 是es6引入的新的语法。
var 存在语法提升,会造成内存泄漏
并且 在一个函数总var 可以声明多个一样的变量 eg:var a=1, a=2, a=3;
let 在函数中声明的时候不存在语法提升,不会造成内存泄漏 并且存在块级作用域,只有在块级作用域中才能生效
let 的语法比较严格,如果是声明的相同的变量就会报错(如果是在不同的块级作用域中,即使声明一样的也不会报错)
eg://想了个简单的例子,不知道妥不妥当 :-)
function hello() {
let a = 0;
console.log(a, 'hello')
if (true) {
let a = 0;
console.log(a, 'obj')
}
}
let b = new hello()
console.log(b)
const定义的变量不可以修改,而且必须初始化
如果const 声明的是对象,那么是可以改变的
const obj ={
name:'Hello',
age:18
}
obj.name='Hello world'
console.log(obj)

from step-by-step.

liangchengxiaohuo avatar liangchengxiaohuo commented on May 31, 2024

1、var声明的变量会存在变量提升,let和const不存在变量提升
2、var声明的变量会挂载在windows上,let和const声明的变量不会
3、同一个作用域下let和const声明的变量不能同名,但是var可以
4、const一旦声明就必须赋值不能使用null占位,并且声明的不能被修改
5、let和const声明的变量会形成块作用域

from step-by-step.

yangyiqiqia avatar yangyiqiqia commented on May 31, 2024

var 和 let 用来声明变量,const 只能声明一个只读的常量
let 和 const 具有块级作用域,在作用域之外不可被访问
var 声明的变量存在变量提升,let和const的不存在变量提升 ,在声明之前访问用var定义的变量返回undefined,let和const会直接报错
var 定义的变量可以重复多次声明,后者会覆盖前者,let 和 const 重复声明会报错

from step-by-step.

Diamondjcx avatar Diamondjcx commented on May 31, 2024

var 和 let都是用来定义变量的,而const 是用来定义常量的

  • 1.变量提升: var声明的变量会被提升,let和const不会。let 和 const 存在暂时性死区, 凡是在声明之前使用这些变量就会报错;
consle.log(a)  // 可以直接打印
var a = 10; =》 会直接提升为
var a ;
a=10;
consolelog(a);

console.log(b) // 直接是报错,没有提升变量,没有定义,直接报错
let b = 1; // const同样

  • 2.作用域不同:var声明变量没有块级作用域,let和const有
fun () {
  var a = 1;
  let b = 2;
  const c = 3;
}
console.log(a);  // 1
console.log(b);  // 访问不到报错
console.log(c);  // 访问不到报错
  • 3.重新赋值
var a = 1;
let b = 2;
const c  = 3;

var a = 10; //ok
let b = 20; // 不可以
const c = 30; // 不可以
  • 4.只声明不初始化 var、let可以,const不可以
var a; // 可
let b; // 可
const c; //不可以  定义常量

from step-by-step.

dashengzi avatar dashengzi commented on May 31, 2024

var、 let 用来声明变量,const 声明一个只读的常量
①let 和 const 在作用域之外不可被访问。
②var 声明的变量会让变量声明提前,let和const的不存在。
③在声明之前访问用var定义的变量返回undefined,let和const会直接报错
④var 定义的变量可以重复多次声明,let 和 const 不能重复声明

from step-by-step.

tianyuandsb avatar tianyuandsb commented on May 31, 2024
  1. var 属于es5关键字
  2. let const 属于es6关键字
  3. var a; console.log(a); var定义没有赋值打印出来是undefined
  4. let a; console.log(a); let定义没有赋值打印出来是undefined
  5. const a; console.log(a); const定义没有赋值打印出来是"报错"
  6. for(let i=0;i<10;i++){
    console.log(i) // 0,1,2,3,4,5,6,7,8,9
    }
    console.log(i); // i is not defined
    let 属于块级作用域,即其在整个大括号 {} 之内可见
  7. for(var i=0;i<10;i++){
    console.log(i) // 0,1,2,3,4,5,6,7,8,9
    }
    console.log(i); // 10 提升作用域
  8. const 和 let 的作用域是一致的,不同的是 const 变量一旦被赋值,就不能再改变了;
    const a = 1 ; a = 2; // Assignment to constant variable.
    但是也不是能改变的
    // 改变的一种方式
    let person = {
    name : '娘子'
    };
    person.name = '啊哈'
    console.log(person.name) // 啊哈

from step-by-step.

Cain-kz avatar Cain-kz commented on May 31, 2024

1.js本身只有全局作用域和函数作用域,let和const的出现,使得js有了块级作用域。
2.var和let可以用来申明变量,const是申明一个只读的常量。
3.let 和 const 在块级作用域可以获取到对象,出了这个范围就会报错。
4.var 声明的变量可以重复,而let、const则不可以;
5.var 声明的变量可以提升,而let、const则不可以;
6.let声明的变量的值可以更改,而const声明的是常量,则不可以,如果const声明的一个对象,则对象中的属性值可以改变;

from step-by-step.

lydfree avatar lydfree commented on May 31, 2024

let是es6 新增的语法,类似var,却跟var 有所不同

  • let存在块作用域,仅在块内有效
  • let不存在变量提升,一定要在声明后才能使用,不然会报错
  • let存在暂时性死区,即全局声明temp,块级内再用let声明temp,temp这个变量绑定了块级作用域,这时候在块级作用域的赋值语句要写在声明语句后面,不然会报错。
  • let不允许在相同作用域下重复声明

const 是es6新增语法,用来声明常量。

  • const声明后需要立即初始化,即赋值
  • const和let一样,存在块作用域,变量不提升,存在暂时性死区

关键点:
const声明的值不能改变?不一定。const保证的是变量指向的内存地址的值不变。如果const变量指向的是内存地址的值是string等基本数据类型,那么值是不变的;如果指向的是一个指针(存放着一个地址),那么const变量的值,就有可能发生改变。

from step-by-step.

zhangxianhui avatar zhangxianhui commented on May 31, 2024

var 是es5推出的声明方式 let const 是es6 推出的

块级作用域(const let)

function fn() {
var a = 5;
if (true) {
var a = 10;
}
console.log(a); // 10
}
fn()
var 声明的结果就10 因为 var 是全局的 如果是let const 声明就存在块级作用 只存在于当前代码块

let 声明变量 并且只作用于当前代码块

var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function() {
console.log(i);
}
}
a1; //1
此时的值会是1 如果是var 声明的 新值 会覆盖旧值 最后结果会为10
let不存在变量提升,一定要在声明后才能使用,不然会报错

暂时性死区

快级作用域内存在let命令,它所声明的变量就绑定在这个区域,不再受外部影响,如果在在块级作用内声明一个局部变量就会报错
var arg = "123";
if (true) {
arg = '456';
let arg;
console.log(arg);
}

let 不允许在相同作用域内,重复声明同一个变量

const 用来声明常量的 声明后需要赋值

const和let 作用域 不可重复声明 暂时性死区 是一样的

from step-by-step.

MagicConch-Cenwer avatar MagicConch-Cenwer commented on May 31, 2024

let和const声明的变量不存在变量提升,而var会
let,var声明的变量能重新赋值,const用来声明常量,不能重新赋值
let和const有自己的作用域,且不能重复声明

from step-by-step.

cute1baby avatar cute1baby commented on May 31, 2024

Evilsay和ChasLui两位回答的最简单立体,作为通用知识点,图像更利于分点记忆。

from step-by-step.

xinran1013 avatar xinran1013 commented on May 31, 2024
  1. const一般声明常量,只读属性,而且必须初始化,就是在声明的同时赋值
    2.var定义的变量可以修改,如果不初始化会输出undefined,不会报错。
    3.let是let是es6新增的声明变量的方式,作用域是块级作用域,不存在变量声明提前,存在暂时性死区,函数内部使用let定义后,对函数外部无影响。

from step-by-step.

ZadaWu avatar ZadaWu commented on May 31, 2024

var

我现在已经养成看东西直接去MDN看的习惯,var的文档在这里

变量声明,无论发生在何处,都在执行任何代码之前进行处理。用 var 声明的变量的作用域是它当前的执行上下文,它可以是嵌套的函数,也可以是声明在任何函数外的变量。如果你重新声明一个 JavaScript 变量,它将不会丢失其值。

将赋值给未声明变量的值在执行赋值时将其隐式地创建为全局变量(它将成为全局对象的属性)。声明和未声明变量之间的差异是:

  1. 声明变量的作用域限制在其声明位置的上下文中,而非声明变量总是全局的
  2. 声明变量在任何代码执行前创建,而非声明变量只有在执行赋值操作的时候才会被创建
  3. 声明变量是在它所在上下文环境的不可配置属性,非声明变量是可配置的(如非声明变量可以被删除)
    由于这三个差异,未能声明变量将很可能导致意想不到的结果。因此,建议始终声明变量,无论它们是在函数还是全局作用域内。

变量提升

由于变量声明(以及其他声明)总是在任意代码执行之前处理的,所以在代码中的任意位置声明变量总是等效于在代码开头声明。这意味着变量可以在声明之前使用,这个行为叫"hoisting"."hoisting"就像是把所有的变量声明移动到函数或者全局代码的开头位置。
类似于:

var bla;
bla = 2;

建议始终在做用用顶部声明变量(全局代码的顶部和函数代码的顶部),这可以清楚知道哪些变量是函数作用域(本地), 哪些变量在作用域链上解决。
重要的是,提升将影响变量声明,而不会影响其值的初始化。当到达赋值语句时,该值被分配。

let

let允许你声明一个作用域被限制在块级中的变量、语句或者表达式。与var关键字不同的是,var声明的变量只能是全局或者整个函数块的。
使用let可以使代码更简单,在某些情景下能代替闭包来实现需求
在同一个函数或块作用域中重复声明同一个变量会引起SyntaxError。

作用域规则

let声明的变量自在其声明的块或子块中可用,这一点,与var相似。二者之间最主要的区别在于var声明的变量的作用域是整个封闭函数。

function varTest() {
  var x = 1;
  if (true) {
    var x = 2;  // 同样的变量!
    console.log(x);  // 2
  }
  console.log(x);  // 2
}

function letTest() {
  let x = 1;
  if (true) {
    let x = 2;  // 不同的变量
    console.log(x);  // 2
  }
  console.log(x);  // 1
}

暂存死区

let 被创建在包含该声明的(块)作用域顶部,一般被称为“提升”。与通过 var 声明的有初始化值 udefined 的变量不同, 通过let 声明的变知道它们的定义被执行时猜才初始化。在变量初始化之前访问该变量会导致 ReferenceError。该变量处在一个自块顶部到初始化处理的”暂存死区“中

function do_something() {
  console.log(bar); // undefined
  console.log(foo); // ReferenceError
  var bar = 1;
  let foo = 2;
}

let与var的区别

let的作用域是块,而var的作用域是函数

let块

let块提供了一种在块的范围内获取变量的值,而不会影响块外面名字相同的变量的值的方法。

var x = 5;
var y = 0;

let (x = x + 10, y = 12) {
  console.log(x + y); // 27
}

console.log(x + y); // 5

const

const是块级作用域,很像使用let语句定义的变量。变量的值不能通过重新赋值来改变,并且不能重新声明。

此声明创建一个常量,其作用域可以是全局或本地声明的块。 与var变量不同,全局常量不会变为窗口对象的属性。需要一个常数的初始化器;也就是说,您必须在声明的同一语句中指定它的值(这是有道理的,因为以后不能更改)。

const声明创建一个值的只读引用。但这并不意味着它所持有的值是不可变的,只是变量标识符不能重新分配。例如,在引用内容是对象的情况下,这意味着可以改变对象的内容(例如,其参数)。

关于“暂存死区”的所有讨论都适用于let和const。

from step-by-step.

sinaine avatar sinaine commented on May 31, 2024

let和const
es6新增了let命令,使用方式类似var ,均用作声明变量,但是let和var也是有很大的区别的。
1.var存在变量提升,let不存在。会存在暂时性死区
2.var不声明使用,相当于在全局声明变量。let不声明使用会报错。
3.let声明为块级作用域,es5中只有全局作用域和函数作用域,没有块级作用域。
4.let不能重复声明回报错。var重复声明时,会去内存中查找声明的这个变量,如果找到了就把值覆盖,没找到就开辟内存来存放这个变量。
使用let可以解决闭包的问题 ,
const命令是常量的声明,声明时就要赋值,一旦声明则不能改变,对于基本类型则是不能改变值,对于复杂数据类型如object类型数据,则是不能修改地址。

from step-by-step.

yeyeyess avatar yeyeyess commented on May 31, 2024

1、let/const是es6的新属性,只在所在的代码块内有效,即暂时性死区,凡是在声明之前就使用这些变量,就会报错。var命令声明的,在全局范围内都有效。
image

2、let/const不存在变量提升,一定要在声明后使用,否则报错。而var存在变量提升,即变量可以在声明之前使用,值为undefined。
image

3、let/const不允许在相同作用域内,重复声明同一个变量。而var可以。
image

4、const在声明时必须赋值,对于简单类型的数据,变量指向的那个内存地址所保存的数据不可改,即常量。而对于复杂型的数据,如对象和数组,保存的是指针,const只能保证指针是固定的,但数据结构可变。
image

from step-by-step.

Link-Fight avatar Link-Fight commented on May 31, 2024

复习下MDN

  • var:(声明语句声明一个变量,并可选地将其初始化为一个值),存在变量提升(无论发生在何处,都在执行代码之前进行处理),在函数作用域内都可以重复声明,作用域范围是函数作用域

  • let:(声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。),不存在变量提升,在同一块级作用域内不能重复声明,存在暂存死区,作用域范围是块级作用域

  • const :声明变量的物理地址不能变,不能通过重新赋值来改变其值,在声明的同时必须要初始化,不存在变量提升,在同一块级作用域内不能重复声明,存在暂存死区,作用域范围是块级作用域

from step-by-step.

muyiweibo avatar muyiweibo commented on May 31, 2024

var,let声明变量,const声明常量,var能重复声明
let,const重复声明会报错
let,const都是声明后使用,不会变量提升
const赋值会报错,如果const声明的是对象,改变对象的属性不会报错。

from step-by-step.

MissWXiang avatar MissWXiang commented on May 31, 2024

首先var,let,const都是定义变量的方式,
其实const是定义常量,当定义常量的时候,就不能对常量的值进行改变,
let就是定义块级作用域。
(微信名:RUN)

from step-by-step.

plane-hjh avatar plane-hjh commented on May 31, 2024

let、const、var 的区别有哪些?

let、var的区别?

  1. var命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined。let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。
console.log(a);    // undefined
var a = 8;

console.log(b);
let b = 10;    //Uncaught ReferenceError: Cannot access 'b' before initialization
  1. let存在暂时性死区,即只要块级作用域存在let,那么let就会绑定到这个块级作用域里面不收外界的影响。var则不会。
var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”。

  1. let 不允许在相同作用域内,重复声明同一个变量。而 var 则可以
let a = 10;
let a = 20;
// Uncaught SyntaxError: Identifier 'a' has already been declared

var b = 10;
var b =20;

const 与 let、var的区别?

  1. const声明一个只读的常量。一旦声明,常量的值就不能改变。
  2. const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。
  3. const的作用域与let命令相同:只在声明所在的块级作用域内有效。
  4. const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

最后附上:
阮一峰老师的let,const

from step-by-step.

yelin1994 avatar yelin1994 commented on May 31, 2024

let const 与 var 的区别

let

  • 声明的变量,有块作用域,比如 {}, if 、for等
  • 不存在变量提升
  • 不允许重复声明
  • 暂时性死区,只要块级作用域中存在let, 声明的变量就被绑定在这个区域,不在受外部影响, 在let声明之前使用该变量会报错(第二点)

const

  • 一旦声明,常量的值就不能再改变,且必须立刻赋值
  • 变量不会提升也会存在死区
  • 块作用域

var

  • 变量提升,不存在死区
  • 没有块作用域

from step-by-step.

MissNanLan avatar MissNanLan commented on May 31, 2024

var 声明的变量会存在变量提升
let 有块级作用域的概念
const 声明的变量不能被改变,而且必须要初始化

 const b; // 错误
 const b=2; // 正确

下面看一道经典的例子

for (var i = 0; i < 3; i++) {
      setTimeout(function () {
        console.log(i)
      }, 1000);
 }
// 3 3 3

改成

for (let i = 0; i < 3; i++) {
      setTimeout(function () {
        console.log(i)
      }, 1000);
 }
// 0 1 2

三次setTimeout 的回调共享同一变量,循环结束的时候i为3,let 就是解决这个问题

from step-by-step.

ccvaille avatar ccvaille commented on May 31, 2024
  • 定义
    • let var 定义一个变量
    • const 定义一个常量
  • 作用域
    • let const 声明在代码块有效,不存在变量提升,相同作用域中,不能重复声明
    • var 声明在函数作用域内有效,存在变量提升,相同作用域中,可以重复声明
  • 初始化
    • const 一旦声明,必须立即初始化
    • var let 声明则不需要

from step-by-step.

huangsiyuan2015 avatar huangsiyuan2015 commented on May 31, 2024

变量提升

var 声明的变量存在变量提升,也就是说 var 声明的变量可以在声明之前使用;
let 和 const 声明的变量不存在变量提升,使用 let 和 const 声明的变量都必须先声明后使用,在声明之前使用都会报错(暂时性死区)。

重复声明

var 命令可以重复声明同名变量,然后覆盖掉之前声明的变量;
let 和 const 命令不允许重复声明同名变量。

声明时赋值,修改

var 和 let 命令在声明变量时可以赋值,也可以不赋值,赋值后还可以修改;
const 命令在声明变量时必须要赋值,否则报错;严格来说 const 声明的是一个常量,赋值后不允许修改。

块级作用域

var 命令声明的变量不存在块级作用域,即在大括号 { } 中声明会变量提升到当前作用域(全局作用域或函数作用域)的头部;
let 和 const 命令声明的变量存在块级作用域,在大括号({})中声明变量会绑定在当前的作用域内,外部访问不到;
另外,for 循环中的 ( ) 使用 let 声明也会形成块级作用域,与 for 循环体中的 { } 块级作用域是父子关系。

from step-by-step.

wkxiaweb avatar wkxiaweb commented on May 31, 2024

es5中只有全局作用域和函数作用域,并没有块级作用域,因此在es6中就增加了 let和const两个命令来改善var的一些不合理,不严谨的地方。下面我就就进行一一的对比,比较一些他们之间的区别 (step-by-step)
let 命令
- 不存在变量提示
如果不知道什么是变量提升,可以具体看下,艳的昨天的问题,js的执行上下文,里面有详细的解释,简单的例子

  console.log(a1)
  console.log(a2)
  var a1 = 1;
  let a2 = 2;

- 作用域是块级作用域
es5中只有函数作用域和全局作用域,let声明的变量只在所声明的代码块内有效。块级作用域由 { } 包括,if语句和for语句里面的{ }也属于块作用域。

  if (true) {
        var b1 = 1;
        let b2 = 2;
    }
    console.log(b1)
   console.log(b2)

- let不允许在同一作用域内重复声明同一个变量
在同一作用域内,如果使用var声明同一个变量,则后面的覆盖前面的,但是用let 重复声明同一个变量会发什么什么呢,请看代码

    var c1 = 1;
    var c1 = 2;
    console.log(c1); // 2
    let c2 = 1;
    let c2 = 2;
    console.log(c2); // 报错 “Identifier 'c2' has already been declared”
    let c3 = 3
    if (true) {
        let c3 = 33;   // 没有在同一作用域是可以的
    }
    console.log(c3); // 3

- 存在暂时性死区
暂时性死区的本质就是,只要一进入当前作用域,所使用的变量就已存在,但是不可获取,只有等到声明变量的哪一行代码的出现,在可以获取和使用该变量。
// 理解暂时性死区

    let d = 10;
    function fn() {
        // console.log(d);
        let d = 5;
    }
    fn(); //  ReferenceError: Cannot access 'd' before initialization

const 命令
const命令和let相似,但也有不同之处
- const用来声明常量,一旦声明,其值就不能更改

 const f1 = 1;
 var f1 = 2;  
    console.log(f1); // Identifier 'f1' has already been declared

那么如果使用const声明对象呢?

const obj = {
        name:"xixi",
        age :28
    }
    obj.name = "xiaxia"
    console.log(obj.name + obj.age)  // xiaxia28

我们可以看到,使用const声明的对象的属性是可以修改。 因为Object类型是引用类型。用const声明常量保存的是对象的地址,不可变的是地址,在上面的代码中就是,不能把 b指向另一个对象。而修改对象的属性,并不会改变对象的地址,因此用const声明对象的属性是可以修改的

from step-by-step.

DazhiFe avatar DazhiFe commented on May 31, 2024

let

let是ES6新增的命令,用来声明变量。它的用法和var类似,但是它所声明的变量,只在let命令所在的代码块内有效,即只在它所在的块级作用域内有效。

{
    let a = 1;
    var b = 2;
}

console.log(a); // ReferenceError: a is not defined
console.log(b); // 2

不存在变量提升

var命令会存在变量提升现象,即变量可以在声明之前使用,值为undefined

let命令,一定要变量先声明后,才可以使用,否则报错。

console.log(a);  // undefined
var a = 10;

console.log(b);  // ReferenceError: b is not defined
let b = 20;

var在全局作用域下声明的变量会挂载在window上,let不会。

var a = 10;
let b = 20;
console.log(window.a); // 10
console.log(window.b) // undefined

暂时性死区

只要块级作用域内存在let命令,它所声明的变量就“绑定”了这个区域,不再受外部的影响。

var a = 10;

if (true) {
    console.log(a);  // ReferenceError: a is not defined
    let a;
}

上面代码中,虽然存在全局变量a,但是在块级作用域内又用let命令声明了一个局部变量a,导致a跟这个块级作用域绑定了,所以let命令在声明变量之前是无法使用的。

不允许重复声明

let命令不允许在相同作用域内,重复声明同一个变量。

function f1() {
    let a = 10;
    var a = 20;
}

f1();
// 报错:SyntaxError: Identifier 'a' has already been declared

因此,也不能在函数内部重复声明参数。

function f2(arg) {
    let arg;
}

f2();
// 报错:SyntaxError: Identifier 'arg' has already been declared
function f2(arg) {
    {
        let arg;
    }
}

f2(); // 不报错

const

const也是ES6新增的命令,用来声明一个只读的常量,一旦声明,常量的值就不能被改变。

const PI = 3.1415;
PI; // 3.1415;
PI = 3;
// TypeError: Assignment to constant variable.

const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。

const a;
// SyntaxError: Missing initializer in const declaration

const的作用域与let相同:只在声明所在的块级作用域内有效。

const命令声明的常量也不存在变量提升,同样存在暂时性死区,只能在声明的位置后才能使用。

const声明的常量也与let一样不可重复声明。

const声明的常量跟let一样不会挂载在window

本质

const实际上保证的,并不是变量的值不可改动,而是变量所指向的那个内存地址所保存的数据不得改动。

对于简单类型的数据(数值、字符串、布尔值),值就保存在变量所指向的那个地址,因此等同于常量。

但对于复杂类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

const obj = {};
// 为obj添加一个属性,可以成功
obj.prop = 10;
obj.prop; // 10

// 将obj指向另一个对象就会报错
obj = {}; // Assignment to constant variable.

看下数组的例子:

const arr = [];
arr.push(1);  // 可以执行
arr; // [1]
// 把另外一个数组赋值给它就会报错
arr = [2,3]; // Assignment to constant variable.

总结

  • var声明的变量存在变量提升;
  • letconst声明的变量/常量不存在变量提升,不可以在声明之前使用,存在暂时性死区;
  • letconst不可以重复声明同一个变量/常量;
  • var在全局作用域下声明的变量会挂载在window上,letconst不会;
  • const声明的常量必须立即初始化且不能再被重新赋值;

参考:http://es6.ruanyifeng.com/#docs/let

from step-by-step.

tpxiang avatar tpxiang commented on May 31, 2024

let const不会存在变量提升,而var会存在变量提升。
let const 是块级作用域。
let const不允许重复声明。
const声明的是常量,一旦声明,值就不能改变。
let const定义的变量必须在语句执行之前,否则就会报错,而var则不会。

from step-by-step.

gitluck1314 avatar gitluck1314 commented on May 31, 2024

let 、const、var的区别:

  • let 和 var 声明一个变量, const 声明一个只读的常量
  • let 和 const 不存在变量提升, var会发生变量提升
  • 在全局作用域下,var声明的变量会被挂在到Windows上,而let、const不会
  • let 和 const 不允许在相同作用域内, 重复声明一个变量
  • let和const存在暂时性死区, 凡是在声明之前使用这些变量就会报错
    而var可以在声明之前使用变量,因为变量提升
  • let 和 const 存在块级作用域
  • var、let声明的对象可以重新赋值
    const 保证的变量保存的数据不得改动, 但如果将一个对象声明为变量, const只能保证这个指针是固定的, 对于它指向的数据结构就不能控制
  • for循环中用var 声明的变量可以在for循环外访问到,而let则不可以。

from step-by-step.

taoyaoyaoa avatar taoyaoyaoa commented on May 31, 2024

1、let是es6新增的声明变量的方式
(1)作用域是块级作用域
( 2 )不存在变量声明提前;
(3) 不能重复定义;
(4)存在暂时性死区;
2、 const一般用来声明常量,且声明的常量是不允许改变的,只读属性,因此就要在声明的同时赋值。const与let一样,都是块级作用域,存在暂时性死区,不存在变量声明提前,不允许重复定义
3、var 是es6之前 js用来声明变量的方法
(1)var的作用域是函数作用域,在一个函数内利用var声明一个变量,则这个变量只在这个函数内有效
(2)存在变量声明提前(虽然变量声明提前,但变量的赋值并没有提前,因此下面的程序不会报错,但a的值为undefined)

from step-by-step.

clairing avatar clairing commented on May 31, 2024

1、var 变量作用域为函数作用域,可以提前声明,可以修改,如果使用未赋值的变量,默认未undefined;存在变量提升。
2、const作用域为块级作用域, 用作常量变量,不能重复定义和提前声明,定义之后不能修改,不代表其内部不允许修改。
const obj = {a:1,b:2};
console.log(obj.a);//1
obj.a = 3;
console.log(obj.a);//3
const 创建的是一个值的引用,不允许其变量标识符重新分配
3、let 作用域块级作用域

from step-by-step.

web-data-MrLi avatar web-data-MrLi commented on May 31, 2024

var 和let/const的区别:
1.块级作用域
2.不存在变量的提升
3.暂时性死去
4.不可重复申明
5.let const 声明的全局变量不会挂在顶层对象下面

以下注意两点;
1.let可以声明后再赋值,const在声明之后必须马上赋值,否则会报错
2.const的简单类型一当声明就不能改正,复杂类型的指针方向不能改变,内部可以改变,
let const的使用场景;
1.let的使用场景;变量,用以替代var
2.const使用场景。常量。声明匿名函数,箭头函数的时候。
以下是简单的案列操作;
第一; ES5只有全局作用域和函数作用域, 没有块级作用域。
这带来很多不合理的场景:
1. 内层变量可能覆盖外层变量
2.用来计数的循环变量泄露为全局变量
var tmp = new Date();
function f() {
console.log(tmp); // 想打印外层的时间作用域
if(false) {
var tmp = 'hello world'; // 这里声明的作用域为整个函数
}
}
f(); // undefined
var s = 'hello';
for(var i = 0; i < s.length; i++) {
console.log(s[i]); // i应该为此次for循环使用的变量
}
console.log(i); // 5 全局范围都可以读到
第二:块级作用域
function f1() {
let n = 5;
if (true) {
let n = 10;
console.log(n); // 10 内层的n
}
console.log(n); // 5 当前层的n
}

第三;不存在变量提升
// var 的情况
console.log(foo); // 输出undefined
var foo = 2;

// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;

第四;暂时性死区
var tmp = 123; // 声明
if (true) {
tmp = 'abc'; // 报错 因为本区域有tmp声明变量
let tmp; // 绑定if这个块级的作用域 不能出现tmp变量
}

from step-by-step.

zyq503454535 avatar zyq503454535 commented on May 31, 2024

let:存在变量提升
const: 声明时必须复制,且值的引用地址不能被修改,存在暂时性死区,形成块级作用域
let: 存在暂时性死区,不存在变量提升,形成块级作用域

from step-by-step.

ITHcc avatar ITHcc commented on May 31, 2024

let和const不会变量提升,var会
let和const存在暂时性死区,未声明前使用变量会报错
var在一个作用域里可以重复声明同一个变量
const声明的是一个只读变量

const声明的对象,不可操作栈(重新初始化对象obj=123),但可以操作堆(对象属性赋值obj.name=123)

from step-by-step.

yaxinlove avatar yaxinlove commented on May 31, 2024

1.不存在变量提升

let和const不存在变量提升;例:
a = 10 let a //打印a==>undefined b = 20 var b //打印b==> 20

2.let 、const 声明存在块级作用域

function log() { for(var i=0;i<3;i++) { // } console.log(i) }
log() //即便是循环结束之后,仍然可以访问i,会打印出来 3;
如果换成let:
function log(){ for(let i=0;i<3;i++) { } console.log('---'+i) }
log() //会报错ReferenceError,因为let存在块级作用域,当for循环执行完毕之后,i就不在存在;

3.不允许在同一作用域重复声明同一变量

let a=1; var a = 2; //报错:Uncaught SyntaxError: Identifier 'a' has already been declared 同样: let b = 1 let b = 2 //报错:Uncaught SyntaxError: Identifier 'a' has already been declared
但是可以let声明变量后可以更改值:
let b = 1; b = 2; //
const 一般用于声明常量;声明常量变量后,不允许更改值:
const a =1; a = 2; // Uncaught TypeError: Assignment to constant variable.
const如果声明一个 对象后,可以更改对象中的属性:
const obj = { age:10 } obj.age = 20; console.log(obj.age) //20

4. 暂时性死区

在代码块内,使用let声明变量之前,该变量都是不可以使用;只要在同一作用域内存在let命令,它所声明的变量,就绑定在该作用域中,不管外部有没有声明此变量;例:
let a=10; function fn() { console.log(a) let a = 5; } fn() // Uncaught ReferenceError: Cannot access 'a1' before initialization
ES6规定,如果在区块中存在let和const声明的变量,则这个区块对这些声明的变量从一开始就形成一个封闭的作用域。不管在外部有没有声明这个变量。必须遵守“先声明,后使用”的原则,否则报错;
ES6规定暂时性死区和不存在变量提升,主要是为了减少运行程序的错误,防止出现“先使用(变量),后声明(变量)”的情况,从而导致意料之外的行为

from step-by-step.

chongyangwang avatar chongyangwang commented on May 31, 2024

let const var的区别

es5 提出了var 声明变量的方式
es6 新增了 let const 两种声明方式
let 声明变量 const声明常量

var
1.var 可以先引用 后声明 也就是常说的变量声明提声
2.var 可以在作用域内 被重复声明多次 let 和const则不能

let 与const

1.let 与const 都拥有块级作用域 什么是块级作用域?
块级作用域由 { } 包括,if语句和for语句里面的{ }也属于块作用域。
块级作用域只在当前范围内有效
2.const 用来定义常量 使用前必须先声明且赋值
3. let const不存在声明提声
4. let 声明变量可以在块级作用域进行修改 const则不能 此外 const 声明的常量 不允许修改绑定 但允许修改值 通俗讲就是可以修改const声明对象中的属性。

from step-by-step.

954545647 avatar 954545647 commented on May 31, 2024

var 定义变量变量会提升,let const不会变量提升let 和 const 存在块级作用域
let 和 var 声明一个变量, const 声明一个只读的常量,const一旦定义了不能修改
let和const存在暂时性死区, 凡是在声明之前使用这些变量就会报错
let 和 const 不允许在相同作用域内, 重复声明一个变量

from step-by-step.

KRISACHAN avatar KRISACHAN commented on May 31, 2024

let、const、var 的区别有哪些?

什么是提升?(hoisting)

首先我们来看一段代码

console.log(变量) // undefined
var 变量 = 1

从上面的代码来看,虽然变量还没有被声明,但是我们却可以使用,这种情况就叫做提升,并且是声明提升。

再来一段代码

console.log(变量) // ƒ 变量() {}
function 变量() {}
var 变量 = 1

上面的代码叫做函数提升,函数提升跟变量提升差不多,就是函数提升优先级比变量高。

从上可知,使用 var 声明的变量会被提升到作用域的顶部。

区别

首先我们再来看一段代码

var a = 1
let b = 1
const c = 1
console.log(window.b) // undefined
console.log(window.c) // undefined

function test(){
  console.log(a)
  let a
}
test()

首先在全局作用域下使用 letconst 声明变量,变量并不会被挂载到 window上,这一点就和 var 声明有了区别。

再者当我们在声明 a 之前如果使用了 a,就会出现报错的情况。

首先报错的原因是因为存在暂时性死区,我们不能在声明前就使用变量,这也是 letconst 优于 var 的一点。然后这里你认为的提升和 var 的提升是有区别的,虽然变量在编译的环节中被告知在这块作用域中可以访问,但是访问是受限制的。

let、const、var 创建的不同

letconst 声明定义了作用于 正在运行的执行上下文(running execution context)词法环境(LexicalEnvironment) 的变量。

letconst 声明的变量是在词法环境实例化时创建的,但是给变量赋值的原生功能 LexicalBinding 以及变量初始化的功能 Initializer 是在之后执行的,而不是在创建变量时,所以在执行之前无法以任何方式访问它们,这就是 暂时性死区

var语句声明了作用于 正在运行的执行上下文(running execution context)变量环境(VariableEnvironment) 的变量。

var 声明的变量同样是在词法环境实例化时创建的,并且创建时就赋值有 undefined,在任何的 变量环境(VariableEnvironment)中,var变量 的绑定可以出现多个,但是最终值是由 赋值时确定的,而不是创建变量时。

from step-by-step.

CCZX avatar CCZX commented on May 31, 2024

var、let、const都是用来声明变量的。

  1. var:
    存在变量提升,允许重复声明,在全局声明的变量会默认成为window的属性。
  2. let
    不存在变量提升,不允许重复声明,在全局声明的变量不会成为window的属性;
    let声明的变量存在暂时性死区:在一个作用域中,不能在let声明之前调用该变量。
    这意味者typeof不再是一个绝对安全的操作。
  3. const
    const和let类似,区别是const声明的变量不允许重新赋值,但是如果const声明的变量
    是引用类型的存在栈内存的地址是不可以改变的,但存在堆内存中的值可以改变。

from step-by-step.

TTTTTTTZL avatar TTTTTTTZL commented on May 31, 2024

let

  • let 类似于 var ,但是所声明的变量只在let 命令所在的代码块有效;

  • 不会存在变量提升,var可以在未声明的时候调用,会被赋值为undefined。但是let在未声明前调用会报错。所以也引申出一个慨念。
    暂时性死区

  • 只要在块级作用域内存在 let 声明,就会形成一个封闭的作用域,凡是在声明前使用这个变量就会报错。

  • 不允许在同一个块级作用域下重复声明一个变量。

  • 形成一个块级作用域。

const

const声明一个只读的常量,表示一旦使用const声明变量,就必须初始化。不能等到以后才赋值

  • const也存在变量不提升,暂时性死区,只在声明的块级作用域有效。不可重复声明变量。

  • const声明的简单类型的值可以进行改动。但是声明的类似于数组、对象。要是改变了内存中的结构就会报错。

var

  • 存在变量提升,在代码执行前会对变量进行赋值undefined。遇到赋值代码才会对变量重新赋值。

  • 在浏览器全局代码中声明变量会被挂载到window,在node环境中挂载到global对象上。

  • 可以随意修改赋值,甚至可以从简单类型重新赋值为复杂类型。

  • 不存在暂时性死区,也不会形成块级作用域

from step-by-step.

luohong123 avatar luohong123 commented on May 31, 2024

(一)var

  • var 命令会发生“变量提升”现象,即变量可以在声明之前使用,值为 undefined
  • 内层变量可能覆盖外层变量
  • 用来计数的循环变量泄露为全局变量

(二)let

  • 声明的�全局变量不会挂在顶层对象下面
  • 所声明的变量一定要在声明后使用,否则报错,报错 ReferenceError
  • 暂时性死区,只要块级作用域内存在 let 命令,它所声明的变量就“绑定”( binding )这个区域,不再受外部的影响,在代码块内,使用 let 命令声明变量之前,该变量都是不可用的。
  • 不允许重复声明

(三)const

  • 声明的�全局变量不会挂在顶层对象下面
  • const 声明之后必须马上赋值,否则会报错
  • const 简单类型一旦声明就不能再更改,�复杂类型(数组、对象等)指针指向的地址不能更改,内部数据可以更改。
  • const 一旦声明变量,就必须立即初始化,不能留到以后赋值。
  • const 命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。

from step-by-step.

zhitaocai avatar zhitaocai commented on May 31, 2024

image

在这个函数中,const 的「真正」作用是什么呢?用 let 可以吗?最后为什么用 const 呢?

from step-by-step.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.