ES6 新增声明方式与各种扩展
为了提高开发效率,语言设计者从原生上支持了许多快捷高效的新操作。故推出称为新一代标准 ES6
let 和 const
let
块级作用域
let 声明的变量只在当前块有效,适用于 for 循环、if 条件句等等
另外,es6 规定块级作用域必须要有大括号,否则就认为没有块级作用域
在 for 循环中,定义循环变量的地方可以为父作用域,而循环体又可以为子作用域
1 |
|
没有变量提升
用 var 来定义变量时,有时存在提升,即可以在声明之前调用不报错但会返回 undefined ;但是 let 不行,必须在声明之后使用,否则就会报错
ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错
另一方面,若是由 var 声明的变量又被 let 重新声明,那么在这次重新声明之前调用也会报错,这被称为暂时性死区,typeof 使用在声明之前也会报错
1 | console.log(a);//undefined |
不允许重复声明
在同一作用域里,不允许重复声明一个变量
1 | var a = 1; |
建议多使用 let 命令,因为它与 var 的作用几乎相同,但是 let 的规定更严格,也更符合先声明后使用的规则
const
一经定义就要赋值,赋值后不能再次改变其值
与 let 一样,存在块级作用域,并且也要在声明之后使用,没有变量提升,存在死区现象
但是如果定义的是对象常量,则可以改变对象的属性,因为 const 此时存的是对象的指针,并不是其中所以属性的值
globalThis
用来获取当前宿主环境的全局作用域对象
解构赋值
数组-变量-的解构赋值
传统的赋值很繁琐,利用解构赋值可以像 python 那样快速赋值;同时还允许使用默认值类似函数的参数默认值
1 | //原始 |
对象的解构赋值
与数组解构类似,甚至可以嵌套赋值非常方便
1 | let {name, age, getName, obj, obj: {number}} = { |
字符串解构赋值
1 | let \[a,b,c,d,e\] = "Great"; |
字符串扩展
模板字符串
使用反撇号 ` ,可当做普通字符串,也可以在其中嵌套任何 JS 表达式包括调用函数
1
2
3
4
5
6
7
1 | var a = 1; |
函数扩展
参数默认值
允许在参数传递时设置参数默认值,当调用函数没用提供参数时就用默认参数,否则还是用提供的参数
- 设置参数默认值后,默认值会形成一个自己的作用域直到参数初始化完毕
- 比如 (x = 1) 实际上执行的是 (let x = 1)
1 | function Person(name = 'Great', age = 21) { |
rest 参数
其实就是对象展开符,形式 …变量,rest 参数后不能再有其他参数
1 | const k = (...arg) => arg.sort(); |
箭头函数
简化了函数原来的写法
- 如果箭头函数不需要参数或者多个参数,可以使用圆括号包裹
- 如果函数体多于一条语句,那么可以用大括号包裹起来,但是需要用 return 语句返回
1 | console.log(\[1,2,3\].map(item => item \* 10));// \[10, 20, 30\] |
- 箭头函数的 this 指向初始化它的时候的执行对象,并非是调用它的时候的执行对象;这一点与普通函数不同
- 不能当成构造函数,使用 new 会报错
- 不能使用 arguments 对象,可以使用 rest 参数代替
1 | let x = 21; |
数组和对象的扩展
数组扩展
数组扩展运算符
这个对于对象同样适用。同时只有函数调用时才能适用圆括号包裹,否则会报错
1 | let x = [1, 2, 3, 4, 5]; |
新增对原型对象的操作
主要用来替代 __proto__
- Object.setPrototypeOf(obj, prototype) 设置某一个对象的原型对象
- Object.getPrototypeOf(obj) 获取某一个对象的原型对象