1. a. var创建的变量是词法作用域
(函数内部可访问外部变量,函数外部不可访问函数内部变量;作用域链,从内部开始往外层找,一 层一层访问,找到为止)
b. var在预编译阶段会变量提升
c. var定义的变量可以修改,如果不初始化会输出undefined,不会报错
d. 在同一作用域内,如果使用var 声明同一个变量,则后面的会覆盖前面的
2. a. let创建的变量是块级作用域,let声明的变量只在所声明的代码块内有效(通常是{ }内)
b. let声明的变量在预编译阶段不会变量提升(必须先声明,才能使用,否则报错)
c. let不允许在同一作用域内重复声明同一个变量(报错:语法错误)
3. a. const创建的变量也是块级作用域
b. 且必须初始化(即创建时便要赋值),否则会报错
c. 但其值是常量,之后试图修改会报错
d. const声明的变量在预编译阶段不会变量提升(必须先声明,才能使用,否则报错)
e. const不允许在同一作用域内重复声明同一个常量(报错:语法错误)
如果const声明的是对象(引用类型,数组同理),对象的属性是可以修改的(因为const声明常量保存的是对象的地址,地 址不可变,属性可变)
备注:
ES6规定,let和const声明的变量,在这个区块形成一个封闭的作用域,不管外部有没有声明,此区块必须先声明后才能使用
(也叫‘暂时性死区’,不存在变量提升,这是为了避免ES5中的var先使用后声明导致的意外行为和减少程序运行错误;
其本质是,只要一进入当前作用域,变量就已经存在但不可获取,只有等到声明变量的那行代码执行完,才可以获取和使用该变量;)
此外,try{ }catch(error){ }中catch也会创建一个块级作用域,但这个块作用域只对形参(此处为error)有效,外部访问不到error