背景
在工作中,常常会用到ES6的一些特性,但是对ES6特性及方法到底了解多少呢?大概也就是一些大众方法罢了,整理了ES6的常见的特性及用法,如果对你有帮助,不要忘了来个点赞哦 👍 ~~。有任何问题还望各位大佬批评指正,谢谢!
ES6是ECMA为JavaScript制定的第6个标准版本,本文知识点参考和摘录《ES6》里的语句。相关详细内容可查看《ES6-ECMAScript6简介》。
块级作用域 {}
在ES6之前,声明变量只能用var,在ES5里面只有全局作用域和函数作用域,没有块级作用域,let 声明的变量拥有自己的块级作用域,修复了var声明变量带来的变量提升问题,因为let声明的变量不存在变量提升。
var
- var定义的变量
可以跨块作用域访问
{
var a = 1;
console.log(a); // 1
}
console.log(a); // 1`
- var定义的变量
不可以跨函数作用域访问
{
(function varTest(){
var b = 2;
console.log(b); // 2
})();
}
console.log(b); // b is not defined
let
- let定义的变量
不能跨块作用域访问
{
let c = 1;
console.log(c); // 1
}
console.log(c); // c is not defined
- let定义的变量
不能跨函数作用域访问
{
(function varTest(){
let d = 2;
console.log(d); // 2
})();
}
console.log(d); // d is not defined
- let定义的变量,
只能在块级作用域访问
{
let e = 1;
{
console.log(e); // 1 子作用域可以访问到父作用域的变量
}
console.log(e); // 1
}
const
- const 用来定义常量,使用时
必须初始化,且初始化后的值不可修改。
// 错误写法
const f;
console.log(f); // Missing initializer in const declaration
// 正确写法
const f = 1;
console.log(f); // 1
f = 2;
console.log(f); // 报错
- const
只能在块级作用域访问,不能修改不能跨块
{
const g = 1;
console.log(g); // 1
g = 2;
console.log(g); // 报错
}
console.log(g); // 报错 不能跨块
变量提升
// 注意:变量提升只提升声明,不赋值。 let和const变量声明不存在提升。
function fn(){
console.log(a); // undefined
var a = 1;
}
fn();
function fn1(){
console.log(b); // Cannot access 'b' before initialization
let b = 1;
}
fn1();
var 关键字
- 有变量提升
- 有全局作用域,函数作用域的概念,没有块级作用域。
- 同一作用域可以重复声明。
- 全局作用域下 var 声明的变量会挂载到window对象上。
let 关键字
- 不存在变量提升
- 有块级作用域的概念
- 同一作用域中不能重复声明
- 存在暂时性死区
const 关键字
- 与 let 特性一致,有两点不同
- 声明时必须初始化
- 常量的值不能改变。
解构赋值
以前,为变量赋值,只能直接指定值。(变量赋值:是对已经声明过的变量进行重新赋值)
let a = 1;
let b = 'abcd';
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
let [a,b,c] = [1,2,3]; // a=1, b=2, c=3
这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
let [aa, [[bb], cc] = [1, [[2], 3]]; // aa = 1, bb = 2, cc = 3
let [x, …y] = [1,2,3,4]; // x = 1,y = [2,3,4]
let [aaa,bbb] = [11]; // aaa = 11, bbb = undefined
// 如果解构不成功,变量的值就等于`undefined`
解构分为两类:完全解构、不完全解构
- 完全解构:等号左边的变量与右边的值一一对应。
- 不完全解构:等号左边的变量,只匹配一部分的等号右边的数组。
let [x, y] = [1, 2, 3];
console.log(x); // 1
console.log(y); // 2
let [x,[a],y] = [1,[2,3],4];
console.log(a) // 2
解构值允许指定默认值
let [aaa = true] = []; // aaa = true
let [aa, bb = 1] = [11]; // aa = 11, bb = 1
let [xa, xb = 22] = [11, undefined]; // xa = 11, xb = 22
// es6内部使用严格的相等运算符判断一个位置是否有值,只有当一个成员严格等于undefined时才能使用默认值.
let [a, b = 2] = [1,null];
console.log(a) // 1
console.log(null === undefined) // false 严格模式下,null和undefined不等
console.log(b) // null
默认值可以引用解构赋值的其他变量,但该变量必须已经声明
let [d = 1, e = d] = []; //d = 1, e = 1
let [g = 2, h = g] = [2]; //g = 2, h = 2
let [i = 3, j = i] = [11,22]; //i =11, j = 22
let [k = m, m = 1] = []; // 报错 m is not defined
最常见的例子还有如何将两个数值互换?,一般我们常用借用第三个变量或者用加减法来进行互换,因此数组的解构赋值也可以将两个数值互换。
let x = 1;
let y = 2;
[x, y] = [y, x]; // x = 2, y = 1
对象解构赋值
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。如果对象解构赋值中没有找到对应的属性名,则返回undefined.
let { a, b } = { a:1, b:2 }; // a = 1, b = 2
let { c, d } = { d:3, c:4 }; // c = 4, d = 3
let { ab } = { aa:1, bb:2 };
// ab = undefined 对象解构没有找到对应的属性名,解构失败,则返回undefined
对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者.
const obj = {
foo: 'peter',
bar: 25
};
let {foo: name, bar: age} = obj; // name = peter age = 25
let obj = {
p: [
'Hello',
{ y: 'World' }
]
};
let { p: [x, { y }] } = obj;
x // "Hello"
y // "World"
// 无法输出 p,p只是个模板,未定义
let { p, p: [x, { y }] } = obj; // p ["Hello", {y: "World"}]
字符串解构 是字符串被转化成一个类似数组的对象
let [a,b,c,d,e,f] = 'hello'; // a:h b:e c:l d:l e:o f:undefined
let [m,n,q,p] = 'w ord';// m:w n: q:o p:r
let {length:len} = 'hello world'; // 12
let [a='H',b,c,d,e,f='W'] = 'hello'; // a:h b:e c:l d:l e:o f:W
// 1. 字符串是按着顺序依次赋值的,有空格也要赋值为空格
// 2. 左边的变量声明的个数>右边赋值的个数,那么从左往右的后面的元素赋值为undefined。
// 3. 左边的变量声明的个数<右边赋值的个数,那么右边多余的则不展示。
// 4. 如果有类似数组的对象有length,可以对这个进行赋值.
// 5. 有默认值的情况下,则会覆盖默认值,如果最后一个元素在赋值中为undefined则会使用默认
函数参数的解构赋值
function test({x,y},{a,b}){
}
test({x:1,y:2},{a:3,b:4}); // {x,y}={x:1,y:2}; {a,b}={a:3,b:4}
// 因为什么参数都不传,那函数内部的解构赋值语法的 被取值对象 就都是 undefined
// {x,y}=undefined; {a,b}=undefined; 将 undefined 转换为对象时报错
test();// 什么参数都不传会报错的
// 所以为了避免上面函数调用时不传参数的情况,
// 要对函数定义中的 模拟伪对象 参数设置一个 {} 空对象作为 被取值对象
function test({x,y}={},{a,b}={}){
}
// 函数内部 {x:1,y:2} 取代了 {x,y}={} 的默认 被取值对象 {}
test({x:1,y:2});//{x,y}={x:1,y:2};
参考文献
后记
以上就是本期 ES6 相关的内容,希望对小伙伴们更好的掌握这方面的知识点有些许帮助,后续持续更新。。。