ES6 特性总结(一)

一、变量

1. let/const 关键字

在 ES6 之前,我们声明变量都用的关键字 var ,甚至可以直接通过为变量赋值来声明全局变量 a = 1(等价于window.a = 1) 。在 ES6 中新增了 let const 关键字用于变量声明,相比较 var 关键字,他们有如下特点:

  • let 关键字不存在变量提升的特性;不允许重复声明;仅在代码块中有效。
  • const 关键字用于常量声明,不允许修改,因此在声明时就必须赋值。
  • 注意const 声明的对象其属性可以修改的,声明的数组其数组元素也可以修改
// let
console.log(a);             // undefined
let a = 10;
let a = 20;                 // 报错:Uncaught SyntaxError: Identifier 'a' has already been declared

// const
const num = 1;
num = 2;                    // 报错:Uncaught TypeError: Assignment to constant variable.
const obj = {name: 'mu', age: 18};
obj.age = 19;               // {name: 'mu', age: 19}
const arr = [1, 2, 3, 4];
arr[0] = 5;                 // [5, 2, 3, 4]

面试常见题

for(var i = 0; i < 3; i++) {
    setTimeout(function () {
        console.log(i);             // 输出 3 3 3
    }, 10)
}

for(let i = 0; i < 3; i++) {
    setTimeout(function () {
        console.log(i);             // 输出 0 1 2 
    }, 10)
}

原因: let 仅在代码块有效,因此在获取动态更替的值时可以解决作用域问题。

2. 解构赋值

ES6 允许按照一定的格式从数组和对象(字符串将切割为数组)中获取特定的值。原理上基于模式匹配,即等号左右两边的格式保持一致时,将进行一一对应赋值。有以下几种解构赋值:

  • 数组的解构赋值
let [a, b, c] = [1, 2, 3];
let [a, [b, c], d] = [1, [2, 3], 4];
  • 对象的解构赋值
let {name, age} = {name: 'mu', age: 18};
let {name: n1, age: a1} = {name: 'mu', age: 18};    // n1 = 'mu', a1 = 18
  • 字符串的解构赋值
let {length} = 'abcd';              // length = 4;
let [s1, s2, s3, s4] = 'abcd';      // s1 = 'a', s2 = 'b', s3 = 'c', s4 = 'd'

此外,解构赋值允许设置默认值,此时等号左右格式可以不一致。

let [x, y = 2] = [1];               // x = 1, y = 2

二、函数

ES6 在函数声明和函数传参上都做了更新,使得函数更加简洁,使用更加方便。

1. 箭头函数

ES5 中函数声明需要采用 function () {} 的形式,在 ES6 中函数声明可以省去 function 关键字,引入 “=>” 符号,常应用于回调函数的声明中。例如:可以用如下方式声明一个简单的 add 函数,传入数组的 map 方法中。

let arr = [0, 1, 2, 3];
let newArr = arr.map( (el) => {return el + 1} );        // [1, 2, 3, 4]
  • 当传入参数仅有一个是,“=>” 左侧的括号可以省略

  • 当函数主体只有一个返回语句,“=>” 右侧的花括号可以省略。(注意:当返回的值是对象时,需要在对象外添加括号 () => ({age: 18})

箭头函数相比较普通函数有如下两点不同:

  • 内部的 this 继承上一个作用域内的 this ,因此箭头函数不能作为构造函数;

  • 函数内部没有 arguments 这个默认参数

var name = 'window';
var obj = {
    name: 'obj',
    print: () => {
        console.log(this.name)              
    }
}
obj.print();            // 'window'
2. 参数

ES6 支持默认参数,rest 参数(...变量名),在函数在参数传递上更加方便,使得函数的功能更加灵活。

  • 默认参数。当设置了参数默认值,那么在函数初始化到初始化结束期间,参数会有一个单独的作用域
function add(x, y = 0) {
    return x + y;
}
add(2, 3)           // 5
add(2)              // 2
  • rest 参数
function add(...args) {
    return args.reduce((a, b) => a+b);
}
add(1, 2, 3, 4)         // 10

作用域问题:

var n = 'window';
function fn(n, m = n) {
    console.log(m)
}
fn('function')          // 'function' 
/*
分析:调用fn时,生成一个参数作用域
{
    n = 'function';
    m = n;
}
因此输出m = 'funciton'
*/

var n = 'window';
function fn(m = n) {
    var n = 'function';
    console.log(m);
}
fn()                    // 'window'

三、数据结构

1. Set 和 Map

ES6 中新增了两种数据结构 SetMap ,两者的实例都通过 new 关键字声明。这里简单介绍他们的功能和常用的属性和函数:

  • Set :集合,与数组的功能类似,不同的是内部不存在重复的元素,因此常用于数组去重。
    • size 属性:等同于数组的 length 属性,获取数据集合的长度。
    • add(val) 方法:向集合中添加元素
    • delete(val) 方法: 删除集合中某一个值
    • has(val) 方法:等同于数组的 includes() 方法,判断集合中是否包含某个值
    • clear() 方法:清空集合。
  • Map :哈希表,映射关系键值对,“键”可为任意类型(包括函数、对象和基本类型)。相比普通的 Object 在涉及频繁增删键值对的场景下会有些性能优势。
    • size 属性: 同上。
    • get(key) 方法:获取哈希表中该键所对应的值。
    • set(key, val) 方法:用于存储新的键值对到哈希表中。
    • keys()values() 方法:分别用于获取该哈希表中所有的键、所有的值。

如何判断某一实例是否为 MapSet

使用 typeof 对实例进行判断得到的是 object ,同 Array 一样,如果要判断该实例是否为 SetMap ,可以使用以下两种方法:

  • 调用原型上的 toString 方法

  • 使用原型链判断实例的 constructor 属性

let m = new Map();
let s = new Set();

console.log(Object.prototype.toString.call(m))      // '[object Map]'
console.log(Object.prototype.toString.call(s))      // '[object Set]'

console.log(m.constructor === Map)                          // true
console.log(s.constructor === Set)                          // true

如何遍历拿到 MapSet 中的所有元素:

这两种数据类型都是有序的,可以通过 for...of 来进行迭代,其原理在于生成一个遍历器(指针对象),指针默认指向当前对象的内存地址。每次迭代,指针后移(当前元素的字节长度),返回数据并判断是否结束(判断指针是否等于对象结束的位置,起始位置+单元字节*元素长度)

for (let val of set) {}
for (let item of map) {}                // 每次返回形式为 [key, value]的数组
for (let key of map.keys()) {}
for (let key of map.values()) {}

面试常见题

// 实现数组的去重
let arr = [1, 2, 3, 3, 9, 8, 9, 2];
arr = Array.from(new Set(...[arr]))         //  [1, 2, 3, 9, 8]
2. Symbol

在 ES5 中数据类型包括:StringNumberBooleanArrayUndefinedNullObject,而在 ES6 中新增了 Symbol 数据类型(使用 typeof 输出为 “symbol” )。Symbol 的最大特点是独一无二,任意两个 Symbol 都是不相等的。需要注意的事它并不需要 new 关键字进行声明,直接使用 Symbol() 进行创建即可,可以传入一个字符串作为其描述。

let sym1 = Symbol();
let sym2 = Symbol('mu');

Symbol('foo') === Symbol('foo');        // false

你可能感兴趣的:(ES6 特性总结(一))