{ let a=10;//let声明的变量只在它所在的代码块有效 var b=1; } console.log(b); // console.log(a);//报错
let应用
1 2 3 4 5 6 7 8 9 10 11
for(let i=0;i<10;i++){} //console.log(i);//i不能在外面引用 var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); //如果是var声明,则会输出10;如果是let声明,则会输出6 //let声明中,每次循环的i其实都是一个新的变量
let不支持变量提升
只要块级作用域内存在let命令,它所声明的变量就“绑定”了这块区域,不再受外部的影响
1 2 3 4 5 6 7 8 9 10 11
var temp=123; if(true){ temp='abc';//会报错,因为下面的let声明了temp,所以这里的temp和外面的就没有关系了, //但是此处的赋值在声明之前,还没有声明就赋值会报错 let temp; /*ES6明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。*/ //称为暂时性死区 } typeof x; // 报错 let x; //let不予许重复声明
let [x = 1, y = x] = []; // x=1; y=1 let [x = 1, y = x] = [1, 2]; // x=1; y=2 let [x = y, y = 1] = []; // ReferenceError
对象的解构赋值
数组的解构赋值是有顺序的,但是对象的解构赋值是无需的,变量名和属性同名才能获取到正确的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
let { bar: bar, foo: foo } = { foo: "aaa", bar: "bbb"}; // 可以简写为 let { bar, foo } = { foo: "aaa", bar: "bbb"}; foo // "aaa" bar // "bbb" let {foo: xiao , baz } = { foo: "aaa", bar: "bbb"}; baz // undefined xiao // "aaa" //真正被赋值的是后者 foo // error : foo is not defined
let obj = { first: 'hello', last: 'world' }; let { first: f, last: 1 } = obj; f // 'hello' l // 'world'
与数组一样,结构也可以用于嵌套结构的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
let obj = { p: [ 'Hello', { y: 'World' } ] }; let { p: [x, { y }] } = obj; x // "Hello" y // "World" //如果写法如下:那么p既是模式又是变量 let { p, p: [x, { y }] } = obj; x // "Hello" y // "World" p // ["Hello", {y: "World"}]
一个嵌套的例子:
1 2 3 4 5
let obj = {}; let arr = []; ({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true});// 此处必须加小括号,否则会报错 obj // {prop:123} arr // [true]
对象的结构也可以设置默认值,默认值生效的条件是严格等于undefined
如果结构失败,变量的值等于undefined
1 2 3
var { x = 1, y = 2 } = { x: undefined, y: null }; x // 1 y // null
对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量
1 2 3
let {sin, cos, tan} = Math; Math.sin // 一个sin function sin // 一个sin function 直接将Math中的方法给了sin
字符串的解构赋值
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象
1 2 3 4 5 6 7
const [a, b, c, d, e] = 'hello'; a // "h" e // "o"
//类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值 let {length : len} = 'hello'; len // 5
数值和布尔值得解构赋值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象,无法转化成对象,将会报错
1 2 3 4 5 6 7 8
let {toString: s} = 123; s === Number.prototype.toString // true
let {toString: s} = true; s === Boolean.prototype.toString // true
let { prop: x } = undefined; // TypeError let { prop: y } = null; // TypeError
函数参数的解构赋值
1 2 3 4 5 6 7
function add([x, y]){ return x + y; } add([1, 2]); // 3
const map = new Map(); map.set('first', 'hello'); map.set('second', 'world'); for (let [key, value] of map) { console.log(key + " is " + value); } // first is hello // second is world
//如果只想获取键名,或者只想获取键值,可以写成下面这样。 // 获取键名 for (let [key] of map) { // ... } // 获取键值 for (let [,value] of map) { // ... }