块级作用域:
特点: 不存在变量声明提升;作用域仅在所在的{}之内(称为暂时性死区);不允许重复声明;
- let
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
const定义的变量是一个常量,不能改变;
如果const定义的是一个对象,可以改变该对象的值,但不能改变地址;
即const实质是定义的是一个变量占用的地址不能改变,但地址内的数据可以改变;
如:
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();

本文探讨了JavaScript中的块级作用域,重点讲解了let和const关键字,强调const定义的变量不可重新赋值但可改变对象内部属性。此外,还详细阐述了解构赋值的概念,包括数组和对象的解构,以及解构的惰性赋值特性,并通过实例展示了解构赋值在实际应用中的场景,如交换变量值和函数返回值的解构等。
865

被折叠的 条评论
为什么被折叠?



