天天看点

es6 变量作用域块

块级作用域

es6中let和const形成了一个块级作用域,他们声明的变量只存在块内。块级作用域外是不能访问内部声明的变量的。

{
	let a = 10 
}
a  //ReferenceError

{
	var a = 10
}
a //10
           

内层作用域可以定义外层作用域的同名变量,例如

function foo() {
    let n = 5;
    if (true) {
        let n = 10
    }
    console.log(n);  // 5
}
           

外层代码块不受内层代码块的影响

块级作用域是可以无限嵌套的

块级作用域的作用:

1.内层变量不会影响外层变量,因为es5中只有全局作用域和函数作用域,这样会导致内层变量修改外层变量的值。

2.循环中用来计数的局部变量不会泄露成全局变量。

let const var

let 和 const 只可以先定义后使用,不存在变量提升,代码块中只要有let 或 const, 它所声明的变量就“绑定”在这个区块内,不受外部影响。

for 循环 会形成两层的作用域区块,循环语句部分是一个父作用域,循环体内部是一个单独的子作用域。例如

for(let i = 0; i < 3; i++) {
    let i = 'abc';
    console.log(i); //输出3次abc
}

           

暂时性死区

for (let i = 0; i < 3; i++) { 
  console.log(i); //Uncaught ReferenceError: i is not defined  因为后面有使用let重新定义i, i在这里被绑定了一个死区
  let i = 'abc';
  console.log(i);
}


{
    typeof x;  //Uncaught ReferenceError: x is not defined  因为后面有使用let重新定义x, let x之前都是x的死区
    let x;  // 然而要是没有let x, typeof x 返回的则是undefined
}
           

暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,不可使用。只有等到声明变量的那一行代码出现,才可以获取或者使用。

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

var

var 定义的变量挂载在函数作用域或者全局作用域上。当var声明了一个变量,这个变量就有一个存储空间,初始化值为undefined,当执行的范围到达声明出,变量设置为指定的值,如果没有赋值,那么还是undefined.

let定义的变量,就有一个块作用域,也具有一个存储空间,只不过没有初始值,获取或者设置一个未初始化的变量,就得到一个ReferenceError, 当执行到声明的变量处,如果没有赋值的话,变量的值就被初始化为undefined

const

const用来声明一个常量

const声明的变量工作类似let, 但是const必须要有一个初始值。

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

const实际上保证的不是变量的值不可改变,而是变量指向的内存地址不得改变。所以如果是简单类型的数据(数值,布尔值,字符串)即值引用类型,是不能改变的。因为它的值就保存在变量指向的内存地址中。如果const声明的是复合类型数据(数组,对象)即地址引用类型,那么它只能保证这个指针是固定不变的,至于它指向的数据结构是不是可变的,就不能控制了。

const foo = {};

// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123

// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only

const a = [];
a.push('Hello'); // 可执行
a.length = 0;    // 可执行
a = ['Dave'];    // 报错
           

转载于:https://my.oschina.net/jjjing/blog/879818