ES6新增语法

201 阅读5分钟

接下来我们来聊一聊一些ES6新增的语法

1、默认参数

以前,我们设置默认参数是这样的

function foo(x, y) {
    x = x || 10
    y = y || 11
    console.log(x + y);
}

foo(1, 2);  // 3
// 输出什么?
foo(1, null);
foo(1);

相信这个很快你就知道答案:12,是的,y没传参就取默认值 11

那这个呢?

foo(1, 0);

输出什么?

输出 1 ? NoNoNo.... 还是输出12

因为你传入的0被认为是false,所以 y || 11 会取11,而不是不传入的值0,使用这个有点危险

所以,ES6就新增了一种语法来改进这个缺点

function foo(x = 10, y = 11) {
    console.log(x + y);
}

我们调用时:

foo(1, 2); // 3

// x=1, y=11
foo(1); // 12

// x=1, y=0
foo(1, 0); // 1

// undefined 默认y没有传参
foo(1, undefined); // 12

// null会被强制转换为 0
foo(1, null);  // 1

2、剩余参数

剩余参数语法允许我们 将一个不定量的参数表示为一个数组

let sum = function(...args) {
    let total = 0;
    args.forEach(function(item) {
        total += item
    });
    return total;
}

console.log(sum(10, 20)); // 60
console.log(sum(10, 20, 30, 40)); // 100

剩余参数跟结构匹配

let arr = [10, 20, 30]
let [value, ...args] = arr

console.log(value);  // 10
console.log(args);  // [20, 30]

剩余参数还可以用于数组

let arr = [10, 20, 30]
let [...args] = arr
console.log(args); // [10, 20, 30]

arr[0] = 40
console.log(arr);  // [ 40, 20, 30 ]
console.log(args);  // [10, 20, 30]

args 的值没有跟着arr的改变而改变,所以这种复制方式一种浅复制

3、解构

解构赋值就是按照对应位置,对变量进行赋值

ES6中新增了一种语法,分别用于数组解构对象结构

2.1 数组解构

以前我们想要把数组中每个元素分别赋值给变量,是这么做的:

let arr = [1, 2, 3]
let a = arr[0],
    b = arr[1],
    c = arr[2]

console.log(a, b, c);  // 1 2 3

利用数组结构相当方便

let arr = [1, 2, 3]
let [a, b, c] = arr
console.log(a, b, c); // 1 2 3
  • 按照一一对应的关系匹配数组中的元素

2.2 对象解构

使用变量的名称匹配对象的属性,匹配成功将对象属性的值赋值给变量

let person = {
    namer: '张三',
    age: 2,
    sex: '其它'
}
let { namer, age, sex } = person
console.log(namer, age, sex);  // 张三 2 其它

注意:变量和属性名要匹配,换成别的变量会报错

还可以利用对象结构将属性值赋值给其它变量

let { namer: newName, age: newAge, sex: newSex } = person
console.log(newName, newAge, newSex); // 张三 2 其它

重复赋值

let { a: x, a: y } = { a: 100 }
console.log(x, y);  // 100 100

4、对象字面量扩展

4.1 简洁属性

下面这种利用对象字面量创建对象,添加键值对是比较常见的

let namer = '张三', age = 2
let obj = {
    namer: namer,
    age: age
}
console.log(obj);  // { namer: '张三', age: 2 }

ES6为我们提供了一种简洁属性的写法

let let obj = {
    namer,
    age
}
console.log(obj); // { namer: '张三', age: 2 }

4.2 简洁方法

为对象添加函数,我们平时是这样做的

let obj = {
    a: function() {
        console.log(123);
    }
}
obj.a()  // 123

ES6简化了方法的写法

let obj = {
    a() {
        console.log(123);
    }
}
obj.a() // 123
  • 推荐这种写法

4.3 计算属性名

以前我们计算对象属性名只能在“外面”

let namer = 'user'
let obj = {}
obj[namer + 'Foo'] = function() {}
obj[namer + 'Bar'] = function() {}
console.log(obj);  // { userFoo: [Function (anonymous)], userBar: [Function (anonymous)] }

ES6之后,我们可以这么做

let namer = 'user'
let obj = {
    [namer + 'Foo']: function() {},
    [namer + 'Bar']: function() {}
}

console.log(obj); // { userFoo: [Function (anonymous)], userBar: [Function (anonymous)] }

5、箭头函数

当我们的函数比较简短的时候,可以使用ES6新增的箭头函数

语法:

() => {}
  1. 函数体中只有一句代码,且代码的执行结果就是返回值可以省略大括号
// 普通函数
function foo(x, y) {
    console.log(x, y);
}

// 箭头函数
let foo = (x, y) => {x + y};
console.log(foo(1, 2));
  1. 如果形参只有一个,形参的小括号也可以省略
// 普通函数
function fn(n1) {
    return n1 ** 2;
};
console.log(fn(2)); // 4

// 箭头函数
const fn1 = n1 => n1 ** 2;
console.log(fn1(2)); // 4
  1. 箭头函数不绑定this关键字,箭头函数中没有this关键字,指向的是函数定义位置的上下文this
let obj = {
    namer: '张三'
}

function foo() {
    return () => {
        console.log(this.namer);
    }
}
// call 修改this的指向,并执行函数
let f = foo.call(obj);
f();  // 张三

箭头函数不能使用 argumentsupernew.target,也不能用作构造函数,除此之外,箭头函数还没有 prototype属性 —— 《JavaScript高级程序设计》


试一试

var age = 100;
var obj = {
    name: 'zxc',
    age: 18,
    say: () => {
        console.log(this.age);
    }
};
obj.say();

结果输出什么?

100,我们说过,this指向的是其上一级函数,否则它就是指向全局作用域window;跟obj对象没有半毛钱关系


6、for...of 循环

ES6在forfor...in 的基础上新增了 for...in循环,在迭代器产生的一系列值上循环

for...of 必须的值必须是一个 iterable

先来看一下 for...in 循环

let arr = ['a', 'b', 'c', 'd']
// 遍历数组
for (index in arr) {
    console.log(index);  // 0 1 2 3 
}


let obj = {
    namer: '张三',
    age: 2,
    sex: '其它'
}
// 遍历对象
for (key in obj) {
    console.log(key);  // namer age sex
}

再来看看 for...of

let arr = ['a', 'b', 'c', 'd']
for (value of arr) {
    console.log(value); // a b c d  
}

所以:

  1. for...in:遍历遍历的索引、对象的属性名
  2. for...of:遍历数组的值

for...of 一样可以用来遍历字符串

let str = 'hello'
for (value of str) {
    console.log(value); // h e l l o  
}

for...of循环也可以通过 breakcontinuereturn