蓝狮注册登陆你需要知道的ES6—ES13开发技巧!

大家好,我是 CUGGZ。

ECMAScript 是 JavaScript 的标准与规范,JavaScript 是 ECMAScript 标准的实现和扩展。今天就来看看 ECMAScript 各版本有哪些实用开发技巧吧!

一、ES6 新特性(2015)
1、let和const
在ES6中,新增了let和const关键字,其中 let 主要用来声明变量,蓝狮注册开户而 const 通常用来声明常量。let、const相对于var关键字有以下特点:

特性
var
let
const
变量提升

:heavy_check_mark:

×

×

全局变量

:heavy_check_mark:

×

×

重复声明

:heavy_check_mark:

×

×

重新赋值

:heavy_check_mark:

:heavy_check_mark:

×

暂时性死区

×

:heavy_check_mark:

:heavy_check_mark:

块作用域

×

:heavy_check_mark:

:heavy_check_mark:

只声明不初始化

:heavy_check_mark:

:heavy_check_mark:

×

这里主要介绍其中的四点:

(1)重新赋值
const 关键字声明的变量是“不可修改”的。其实,const 保证的并不是变量的值不能改动,而是变量指向的那个内存地址不能改动。对于基本类型的数据(数值、字符串、布尔值),其值就保存在变量指向的那个内存地址,因此等同于常量。但对于引用类型的数据(主要是对象和数组),变量指向数据的内存地址,保存的只是一个指针,const只能保证这个指针是不变的,至于它指向的数据结构就不可控制了。

(2)块级作用域
在引入let和const之前是不存在块级作用域的说法的,这也就导致了很多问题,比如内层变量会覆盖外层的同名变量:

var a = 1;
if (true) {
var a = 2;
}
console.log(a); // 输出结果:2
循环变量会泄漏为全局变量:

var arr = [1, 2, 3];
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]); // 输出结果:1 2 3
}
console.log(i); // 输出结果:3
而通过let和const定义的变量存在块级作用域,就不会产生上述问题:

let a = 1;
if (true) {
let a = 2;
}
console.log(a); // 输出结果:1
const arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]); // 输出结果:1 2 3
}
console.log(i); // Uncaught ReferenceError: i is not defined
(3)变量提升
我们知道,在ES6之前是存在变量提升的,所谓的变量提升就是变量可以在声明之前使用:

console.log(a); // 输出结果:undefined
var a = 1;
变量提升的本质是JavaScript引擎在执行代码之前会对代码进行编译分析,这个阶段会将检测到的变量和函数声明添加到 JavaScript 引擎中名为 Lexical Environment 的内存中,并赋予一个初始化值 undefined。然后再进入代码执行阶段。所以在代码执行之前,JS 引擎就已经知道声明的变量和函数。

这种现象就不太符合我们的直觉,所以在ES6中,let和const关键字限制了变量提升,let 定义的变量添加到 Lexical Environment 后不再进行初始化为 undefined 操作,JS 引擎只会在执行到词法声明和赋值时才进行初始化。而在变量创建到真正初始化之间的时间跨度内,它们无法访问或使用,ES6 将其称之为暂时性死区:

// 暂时性死区 开始
a = “hello”; // Uncaught ReferenceError: Cannot access ‘a’ before initialization
let a;
// 暂时性死区 结束
console.log(a); // undefined
(4)重复声明
在ES6之前,var关键字声明的变量对于一个作用域内变量的重复声明是没有限制的,甚至可以声明与参数同名变量,以下两个函数都不会报错:

function funcA() {
var a = 1;
var a = 2;
}
function funcB(args) {
var args = 1;
}
而let修复了这种不严谨的设计:

function funcA() {
let a = 1;
let a = 2; // Uncaught SyntaxError: Identifier ‘a’ has already been declared
}
function funcB(args) {
let args = 1; // Uncaught SyntaxError: Identifier ‘args’ has already been declared
}
现在我们项目中已经完全放弃了var,而使用let来定义变量,使用const来定义常量。在ESlint开启了如下规则:

“no-var”: 0;
2、解构赋值
ES6中还引入了解构赋值的概念,解构赋值遵循“模式匹配”,即只要等号两边的模式相等,左边的变量就会被赋予对应的值。不同类型数据的解构方式不同,下面就分别来看看不同类型数据的解构方式。

平时在开发中,我主要会用到对象的解构赋值,比如在react中解构porps值等,使用解构赋值来获取父组件传来的值;在React Hooks中的useState使用到了数组的解构赋值。

(1)数组解构
具有 Iterator 接口的数据结构,都可以采用数组形式的解构赋值。

const [foo, [[bar], baz]] = [1, [[2], 3]];
console.log(foo, bar, baz) // 输出结果:1 2 3
这里,ES6实现了对数组的结构,并依次赋值变量foo、bar、baz。蓝狮注册登陆数组的解构赋值按照位置将值与变量对应。

数组还可以实现不完全解构,只解构部分内容:

const [x, y] = [1, 2, 3]; // 提取前两个值
const [, y, z] = [1, 2, 3] // 提取后两个值
const [x, , z] = [1, 2, 3] // 提取第一三个值
如果解构时对应的位置没有值就会将变量赋值为undefined:

const [x, y, z] = [1, 2];
console.log(z) // 输出结果:undefined
数组解构赋值可以使用rest操作符来捕获剩余项:

const [x, …y] = [1, 2, 3];
console.log(x); // 输出结果:1
console.log(y); // 输出结果:[2, 3]
在解构时还支持使用默认值,当对应的值为undefined时才会使用默认值:

const [x, y, z = 3] = [1, 2];
console.log(z) // 输出结果:3
(2)对象解构
对象的解构赋值的本质其实是先找到同名的属性,在赋值给对应的变量:

let { foo, bar } = { foo: ‘aaa’, bar: ‘bbb’ };
console.log(foo, bar); // 输出结果:aaa bbb
需要注意的是,在JavaScript中,对象的属性是没有顺序的。所以,在解构赋值时,变量必须与属性同名才能去取到值。

对象的解构赋值也是支持默认值的,当定义的变量在对象中不存在时,其默认值才会生效:

0 Comments
Leave a Reply