ES6规范记录(一):块作用域,解构赋值

记录下ES6的一些容易忽略的规范:

  1. let和const
    1)只要块级作用域内存在let命令,它所声明的变量就‘绑定’这个区域,不再受外部的影响。
    ES6明确规定,如果区块中存在letconst命令,这个区域对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
    总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。在语法上称为“暂时性死区”(temporal dead zone, 简称TDZ)。

    //例1:
    for(let index = 0; index < 3; index ++) {
    	console.log(index); //ReferenceError
    	let index = 9527;
    	console.log(index);
    }
    
    //例2:
    let x = x;//ReferenceError
    
    //例3:
    var x = x;//undefined
    

    注意:ES6的块级作用域必须有大括号,如果没有大括号,js引擎就认为不存在块级作用域。

    // 第一种写法,报错
    if(true) let x = 1;
    
    // 第二种写法,不报错
    if(true) {
    	let x = 1;
    }
    

    2)const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据,值就保存在变量指向的内存地址,保存的知识一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

    const foo = {};
    foo.prop = 123;
    foo.prop // 123
    
    foo = {}; // TypeError: "foo" is read-only
    
  2. 数组的解构与赋值

    // ES5
    let a = 1;
    let b = 2;
    let c = 3;
    
    //ES6
    let [a, b, c] = [1, 2, 3];
    
    // 嵌套赋值
    let [a, [b, [c]]] = [1, [2, [3]]];
    //a == 1, b == 2, c == 3
    
    // 定义默认值
    let [x = 1, y] = []
    

    注意:ES6内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。
    如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。

    function f() {
    	console.log('aaa');
    }
    let [x = f()] = [1];
    

    上述代码中f函数不会执行。上面代码等价于下面的代码:

    let x;
    if([1][0] === undefined) {
    	x = f();
    } else {
    	x = [1][0];
    }
    

    如果变量名与属性名不一致必须写成下面这样:

    let { foo: baz } = { foo: 'aaa', bar: 'bbb'};
    // baz=='aaa'
    let obj = {first: 'hello', last: 'world'};
    let {first: f, last: 1} = obj;
    //f == 'hello', last = 'world'
    

    也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋值给对应的变量。真正被赋值的是厚泽,而不是前者。

    let {foo: baz} = {foo: 'aaa', bar: 'bbb'};
    //baz == 'aaa'
    foo // error: foo is not defined
    

    注意点:
    1)如果要将一个已声明的变量用于解构赋值,必须非常小心。

    let x;
    {x} = {x: 1};//SyntaxError: syntax error
    

    因为js引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在首行,避免js将其解释为代码块,才能解决这个问题。

    let x;
    ({x} = {x: 1});
    

    2)由于数组本质是非常特殊的对象,因此可以对数组进行对象属性的解构。

    let arr = [1, 2, 3];
    let {0: first, [arr.length - 1]: last} = arr;
    //first == 1, last == 3
    
  3. 字符串的解构赋值
    字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

    const [a, b, c, d, e] = 'hello';
    //a == 'h', b == 'e'....
    

    类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。

    let {length: len} = 'hello';
    //len == 5;
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值