特点: 不存在变量声明提升;作用域仅在所在的{}
之内(称为暂时性死区);不允许重复声明;
let i= 10;
for(let i = 0;i<10;i++){
let i= 20;
}
// 本段代码并不会报错(不允许重复声明错误),因为是三个层级的i,注意for循环的()与{}属于两个层级
// 即:
let i = 10
{
let i =0;
{
let i = 20;
}
}
const A= 0;
A = 1;//会报错
const obj = {};
obj.a = 10;
obj = {b:10}; //此时会报错,因为地址被改变;
let [a,b,c] = [1,2,3]; //基本形式写法
// 以上相当于:
let a =1;
let b =2;
let c = 3;
// 并且可以进行复杂的嵌套,甚至支持默认值的写法:let [a= 10] = [20];
解构失败:let [a,b] = [1]; // 此时b为undefined
不完全解构:let [a] = [1,2];
实质上,当右边的值绝对(===
)等于undefined
的时,才会用左边的默认值;并且是一种惰性赋值(不用不加载);
例:
let [x = 1,y = x] = []; // x=1 y=1
let [x = 1,y = x] = [2]; // x=2 y=2
let [x = 1,y = x] = [2,4]; // x=2 y=4
let [x = y,y = 1] = []; // 报错,使用了let,先使用后声明
let [x = y,y = 1] = [2]; // x=2 y=1
let {bar,foo} = { b:123, f:456}; // 简写形式
注意:以下两种写法输出
let {bar,foo} = { bar:123, foo:456}; console.log(bar,foo); // 123 456
let {bar,foo} = { foo:456, bar:123}; console.log(bar,foo); // 123 456
//说明此时匹配到的值是无序的 (对象存储的值是键值对的形式,本身就是无序的)
let {bar,foo} = { b:123, f:456}; console.log(bar,foo); // undefined undefined
let {foo:bar} = {foo:123};console.log(bar);console.log(foo); //123 报错
看到这里,是不是突然发现刚刚得到的规律好像并不适用于此行???
实质上: 上面的基本形式只是一种简写,完整形式写法为:let {bar:bar,foo:foo} = {bar:123,foo:456};
;:
前面的bar/foo代表的是一种模式(不具有意义),是根据模式进行匹配,把值给:
后面的即:
let {bar:ba,foo:fo} = {ba:123,fo:456}; console.log(bar,foo,ba,fo); //报错(not def)、报错(not def)、undef、undef
let {bar:ba,foo:fo} = {bar:123,foo:456}; console.log(bar,foo,ba,fo); //报错(not def)、报错(not def)、123、456
当bar与ba都写为bar时,可以是最上面的简写形式;
在举一个嵌套例子:
let obj = {
p : [
"hello",
{y : 123}
]
}
let {p:[x,{y:aa}]} = obj;
console.log(x,aa); //hello 123
console.log(p,y); //报错(not def)、报错(not def)
那么,怎么把obj里的p拿出来呢?我们在愿来obj的基础上执行:let {p,p:[x,{y:aa}]} = obj;console(p,x); //["hello",{y:123}] , hello
,这说明被可以解构多次!!
并且同样支持默认赋值;
3. 解构赋值扩展
let [a,b] = 12; //报错(12不是迭代器)
let [a,b] = "12"; console.log(a,b); // "1" "2" 字符串的包装类可以隐式将其转为类数组,比如可以以数字形式操作字符串:str[0] = 1;
let {length} = 123; console.log(length); //undef
let {length} = "123"; console.log(length); // 3(数字3,非字符串)
//甚至变态到用在一些方法中:
let {pow,ceil,floor} = Math; consle.log(floor(2.3)); // 2
let {toString:n} = 123;
let {toString:b} = false;
console.log(n == Number.prototype.toString); //true
console.log(b == Boolean.prototype.toString); //true
function add([x,y]){return x+y;}
console.log( add([1,2]) ); // 3
4.应用:
交换两个数:let x = 1,y = 2; [x,y] = [y,x];
函数返回值的解构:function methods(){return {add:function(){},sum:function(){}}} let {add,sum} = methons();