ES6函数的扩展

Date:2017/07/5       Cat:开发者手册       Word:共2337字       Tags:      

文章目录 「隐藏」
  1. 一、函数的默认值设置
  2. 二、解构默认值
  3. 函数的length属性
  4. 函数的作用域

参考:《ES6标准入门教程》 作者:阮一峰

一、函数的默认值设置

在ES5的时候如果一个函数的参数必须为有效值,那么我们通常会这样做一个判断:

function conlog(a) {
    if (!a) {
        a = 1;
    }
    console.log(a); //1
}

或者

function conlog(a) {
    a = a || '1';
    console.log(a); //1
}

在ES6中允许为函数的参数设置默认值,这个默认值只有在没有传入的时候有效,在传入参数后这个默认值失效,通过默认值设置可以很大的提高代码的容错能力,写法如下:

function conlog(a = 1) {
    console.log(a);
}

conlog(); //1

conlog(2); //2

如果你只指定了第一个参数的默认值,那么当这个参数是无法省掉的,你必须通过显示的传入undefined才能使默认值生效,所以在使用过程中建议把必需传入的参数放在前面,带有默认值的参数放在尾部,比如下面:

function conlog(a = 1, b) {
    console.log(a, b);
}

conlog(); // 1 undefined
conlog(2); // 2 undefined
conlog(, 1); //报错
conlog(undefined, 2); // 1 2

二、解构默认值

ES6允许函数的参数为解构模式来设置默认值,但按照我们通常的理解方式数组解构应该是下面的写法。

function conlog([a = 1, b = 2]) {
    console.log(a, b);
}

conlog(); //报错
conlog([]); // 1 2

上面的写法不能达到我们解构模式来设置默认值的要求,因为在解构模式下,需要有对等的结构来进行解构,在这里需要注意的一点是数组解构是需要分传参的位置,如果我们需要通过解构来设置默认值需要如下面这样来写:

function conlog([a = 1, b = 2] = []) {
    console.log(a, b);
}

conlog(); // 1 2
conlog([3, 4]); // 3 4

或者通过下面的写法都可以实现设置默认值:

function conlog([a, b] = [1 ,2]) {
    console.log(a, b);
}

conlog(); // 1 2
conlog([3, 4]); // 3 4

ES6对象解构同样允许使用,如果需要设置对象默认值解构,同理需要像数组解构设置一个空的对象值,比如下面这样来写:

function conlog({a = 1, b = 2} = {}) {
    console.log(a, b);
}

conlog(); // 1 2
conlog({a: 3, b: 4}); // 3 4

或者:

function conlog({a, b} = {a: 1, b: 2}) {
    console.log(a, b);
}

conlog(); // 1 2
conlog({a: 3, b: 4}); // 3 4

在对象解构中,不要求顺序,只需要你在传入的对象中含有这两个属性名即可,如果没有找到对应的属性名那么将会使用默认值,如果没有默认值将会是undefined。

function conlog({a = 1, b = 2} = {}) {
    console.log(a, b);
}

conlog({b: 4, a: 3}); // 3 4

但是这里注意,上面的数组解构以及对象解构传入后都成为了函数内部的变量,不是一个有效的数组以及对象,如果你需要得到传入的参数是数组或者对象,那么可以通过扩展运算符'...'来实现:

function conlog([...ary] = [1, 2]) {
    console.log(ary.toString());
}

conlog(); // 1,2
conlog([3, 4]); // 3,4

对象的写法如下:

function conlog({obj} = {obj: {a: 5}}) {
    console.log(obj.a);
}

conlog(); // 5
conlog({obj: {a: 1}}); // 1

当然ES7已有提案将rest运用在对象中,目前大多数不支持,但是babel已经支持了。

function conlog({...obj} = {a: 5}) {
    console.log(obj.a);
}

conlog(); // 5
conlog({a: 8}); // 8

函数的length属性

函数的length属性返回的数值是指函数预期需要传入的参数数量。但是一旦我们给某个参数指定了默认值后,此参数就不在计此参数,所以函数的lenght等于函数需要预期传入的参数数量减去设置了默认值的参数数量

function conlog(x = 1, b = 2) {
    console.log(x, b);
}

conlog.length // 0

function conlog(x, b) {
    console.log(x, b);
}

conlog.length // 2

函数的作用域

由于es6定于了块作用域以及let 和 const两个变量声明方法,所以es6函数作用域也会有一些变动。比如下面的例子,作为参数x在函数内部重复声明了一次,ES6声明在块作用域中参数和let及const声明的变量都会提升到块作用域顶部,并且此变量在没有声明之前不能使用以及调用,这个被称为"暂时性死区"。

function conlog(x = 5) {
    let x = 3;
    console.log(x);
}

conlog(); //报错

暂时性死区不影响var声明的变量,但var会覆盖局部变量,所以慎用var,尽量用let、const来代替var。

function conlog(x = 5) {
    console.log(x); // 5
    var x = 3;
    console.log(x); // 3
}

conlog();

除此之外es6增加的块作用域可以替代让新人纠结已久的匿名函数了

(function(){
    var a = 3;
})

可以用块作用域代替

{
    let a = 3;
}

文完

《ES6函数的扩展》留言数:0

发表留言