ECMAScript(ES6)let 和 const 命令,变量的解构赋值
let 和 const 命令
- 用var定义全局变量,会自动成为window的属性
ES5有两种作用域:
全局作用域
局部作用用域 (函数内部)
变量允许在定义之前使用,值为undefined, 这种现象称之为变量提升现象 - 用let声明的变量,不允许在声明之前就使用(不存在变量提升现象)
用let声明的变量,不会成为window的属性
用let声明的变量,只在其声明的代码块内有效 ({ }) - 块级作用域
在相同作用域下,用let声明的变量不允许再重复声明 。
let命令
ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1 for循环的计数器,就很合适使用let命令。 for (let i = 0; i < 10; i++) { // ... } console.log(i); // ReferenceError: i is not defined 上面代码中,计数器i只在for循环体内有效,在循环体外引用就会报错。
上面代码在代码块之中,分别用let和var声明了两个变量。然后在代码块之外调用这两个变量,结果let声明的变量报错,var声明的变量返回了正确的值。这表明,let声明的变量只在它所在的代码块有效。
ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
if (true) { // TDZ开始 tmp = 'abc'; // ReferenceError console.log(tmp); // ReferenceError let tmp; // TDZ结束 console.log(tmp); // undefined tmp = 123; console.log(tmp); // 123 } 上面代码中,在let命令声明变量tmp之前,都属于变量tmp的“死区”。
let不允许在相同作用域内,重复声明同一个变量。 // 报错 function func() { let a = 10; var a = 1; } // 报错 function func() { let a = 10; let a = 1; }
const 命令
const声明一个只读的常量。一旦声明,常量的值就不能改变。 const PI = 3.1415; PI // 3.1415 PI = 3; // TypeError: Assignment to constant variable. const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。 const foo; // SyntaxError: Missing initializer in const declaration 上面代码表示,对于const来说,只声明不赋值,就会报错。 const的作用域与let命令相同:只在声明所在的块级作用域内有效。
ES6 声明变量的六种方法
ES5 只有两种声明变量的方法:var命令和function命令。ES6 除了添加let和const命令,后面章节还会提到,另外两种声明变量的方法:import命令和class命令。所以,ES6 一共有 6 种声明变量的方法。
变量的解构赋值
数组的解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
let [a, b, c] = [1, 2, 3]; 上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值。
let [foo, [[bar], baz]] = [1, [[2], 3]]; foo // 1 bar // 2 baz // 3 let [ , , third] = ["foo", "bar", "baz"]; third // "baz" let [x, , y] = [1, 2, 3]; x // 1 y // 3 let [head, ...tail] = [1, 2, 3, 4]; head // 1 tail // [2, 3, 4] let [x, y, ...z] = ['a']; x // "a" y // undefined z // [] 如果解构不成功,变量的值就等于undefined。
默认值
解构赋值允许指定默认值。
let [foo = true] = []; foo // true let [x, y = 'b'] = ['a']; // x='a', y='b' let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
注意,ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。
let [x = 1] = [undefined]; x // 1 let [x = 1] = [null]; x // null 上面代码中,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。
对象的解构赋值
let { foo, bar } = { foo: "aaa", bar: "bbb" }; foo // "aaa" bar // "bbb"
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
如果变量名与属性名不一致,必须写成下面这样。 let { foo: baz } = { foo: 'aaa', bar: 'bbb' }; baz // "aaa" let obj = { first: 'hello', last: 'world' }; let { first: f, last: l } = obj; f // 'hello' l // 'world'
字符串的解构赋值
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象
const [a, b, c, d, e] = 'hello'; a // "h" b // "e" c // "l" d // "l" e // "o" 类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。 let {length : len} = 'hello'; len // 5
数值和布尔值的解构赋值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
let {toString: s} = 123; s === Number.prototype.toString // true let {toString: s} = true; s === Boolean.prototype.toString // true 上面代码中,数值和布尔值的包装对象都有toString属性,因此变量s都能取到值。
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。
let { prop: x } = undefined; // TypeError let { prop: y } = null; // TypeError
函数参数的解构赋值
function add([x, y]){ return x + y; } add([1, 2]); // 3 上面代码中,函数add的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量x和y。对于函数内部的代码来说,它们能感受到的参数就是x和y。
[[1, 2], [3, 4]].map(([a, b]) => a + b); // [ 3, 7 ]
函数参数的解构也可以使用默认值。 function move({x = 0, y = 0} = {}) { return [x, y]; } move({x: 3, y: 8}); // [3, 8] move({x: 3}); // [3, 0] move({}); // [0, 0] move(); // [0, 0]
//一个参数可省略() let f1 = a=> a; //多个参数 let f2 = (x,y)=>x+y; //没参数必须写() let f3 = ()=>'hellow'; f3() //函数体不止一条语句必须用{} let f4 =(x=5,y=6)=>{ console.log(x,y) } f4() //函数体不止一条语句 有返回值 必须用{} 必须写return let f5=(a=5,b=9)=>{ console.log(a,b) return a+b; }; console.log(f5()) //函数体只一条返回语句 且返回的是一个对象 要用()包含 let f6=()=>({ name:'aaa' }) console.log(f6()) let f7=({sp=300,dot=false,s1=false}={})=>{ return { code:200, msg:'ok' } }; let {code:c,msg:m}=f7() console.log(c,m)
- 【ES6学习】— (1)ES6简介、let与const命令以及变量的解构赋值
- es6学习篇之 let和const命令 、变量的解构赋值
- ECMAScript 6笔记(let,const 和 变量的解构赋值)
- ES6新特性 let、const、变量对象的解构赋值
- const命令,全局变量的属性,变量的解构赋值
- ES6学习笔记(let、const、变量的解构赋值、字符串扩展)
- JS变量中有var定义和无var定义的区别以及es6中let命令和const命令
- ES6语法之let、const和解构赋值
- ECMAScript 6学习笔记(一)let、const、变量的结构赋值
- ECMAScript 2015(ES6):let和const命令
- ECMAScript6学习笔记 ——let、const、变量解构赋值
- 【Javascript学习笔记】【ES6:let/var声明变量与作用域+const声明常量+变量的解构赋值】
- ES6------第三天(const命令、变量解构)
- ECMAScript 6(4)变量的解构赋值
- ES6学习--let和const命令
- ES6 let和const命令
- es6——let和const命令
- ECMAScript 6 入门学习(2.变量的解构赋值)
- ES6的let和const命令(一)
- ECMAScript 6 入门(let 和 const 命令)