es6函数功能整理

147 阅读4分钟

一. 默认参数值

举个栗子:

function markRequest(url, timeout = 2000, callback = function(){}){
    // todo
}

调用:
// 使用 timeout 和 callback的默认值
markRequest('/foo')

// 使用callback的默认值
markRequest('/foo', 500)

// 不使用默认值
markRequest('/foo', 500,function(bosy){dosomething(body)})

// 如果参数传null,则不会使用默认值,null是一个和法值。只有当传入undefined或者不传参数时,才会使用默认值

二. 不定参数对arguments的影响

在ECMAScript5 非严格模式下,命名参数的变化会同步更新到arguments对象中,举个例子:

function add(first, seconds){
    console.log(first === arguments[0]);
    console.log(seconds === arguments[1]);
    first = 'a'
    seconds = 'b'
    console.log(first === arguments[0]);
    console.log(seconds === arguments[1])
}
add('c','d')

运行结果如下:
true
true
true
true

当参数进行改变时,arguments同时也会被更新。所以最终 === 的比较都为true

在ECMAScript5 严格模式下,命名参数的变化就不会同步更新到arguments对象中,举个例子:

function add(first, seconds){
    "use strict";

    console.log(first === arguments[0]);
    console.log(seconds === arguments[1]);
    first = 'a'
    seconds = 'b'
    console.log(first === arguments[0]);
    console.log(seconds === arguments[1])
}
add('c','d')

运行结果如下:
true
true
false
false

这样正如你所期待的那样,argumens不会随着参数的而改变而被更新,但是一定是在严格模式下

在ECMAScript6中,无论是严格模式下还是非严格模式下,arguments都会是你所期待的那样。不会随着参数的改变而被更新,但是默认参数的存在使得arguments对象与命名参数分离,举个例子:

function minxArg(first, second = 'b'){
    console.log(arguments.length)
    console.log(first === arguments[0])
    console.log(second === argumrnts[1])
    first = 'b'
    second = 'e'
    console.log(first === argumets[0])
    console.log(second === arguments[1])
}

minArg('a')

// 执行结果如下
1
true
false
false
false

这个例子中,minArg只传入了一个参数,所以。正如期待的一样,arguments的长度为1,并且改变first,second,都不会影响arguments

三.  默认参数表达式

函数的传参可以通过非原始值传参,举个例子

function getValue (){
    return 5
}

function add (first, second = getValue()){
    return first + second
}

console.log(add(1,1)) // 2
console.log(1); // 6

以上代码,如果只传入一个参数,那么第二个参数就会默认调用getValue方法,返回的是5

正因为默认参数是函数调用时求值,所以可以将先定义法人参数给后定义的参数赋值,举个例子:

funtion add(first, second = fist){
    return first + second
}
console.log(add(1,1)) // 2
console.log(1) // 2

注意:引用参数默认值的时候,只允许引用前面参数的值,如果引用了后面参数的值就会抛错。也就是所谓的参数临时死区

四. 不定参数

在命名参数前面加三个点(...)就表示一个不定参数,举个例子:

funtion dosome(object,...keys){
    let result = Object.create(null)
    for(let i = 0;i<keys.length;i++){
        result[keys[i]] = object[keys[i]]
    }
    return result
}

不定参数具有一定的限制

1. 每一个函数只能声明一个不定参数

2.  不定参数一定是写在所以参数的最后面

五. 展开运算符

与不定参数相似,都是有三个点(...)

不定参数是将指定的各自独立的参数通过整合后的数组来访问,而展开运算是将数组进行打散后作为独自的参数传入函数,举个例子:

计算最大最小值
let value = [10,20,30,40]

console.log(Math.max(...value)); // 40

也可以将正常值混入计算

console.log(Math.max(...value,50)); // 50

六.明确函数的多重用途

在ECMAScript6中函数有两个不同的内部方法:[[call]]和[[construct]]

通过new关键字调用,执行的是[[construct]],否则执行[[call]],不是所有的函数都有[[construct]],箭头函数就没有。

如何判断是否需要new关键字来调用,可以使用instanceof,例如:

function Person(name){
    if(this instanceof Person){
        this.name = name
    }else{
        throw new Error('必须使用new关键字')
    }
}

但是instanceof也不是全能的,例如:

function Person(name){
    if(this instanceof Person){
        this.name = name
    }else{
        throw new Error('必须使用new关键字')
    }
}
var person = new Person('hello')
var otherPerson = Person.call(person,'haha')

instanceof无法区分是使用call还是apply还是new调用到的Person,所以es6新出来了一个检验方法,那就是 new.target

function Person(name){
    if(new.target ===  Person){
        this.name = name
    }else{
        throw new Error('必须使用new关键字')
    }
}
var person = new Person('hello')
var otherPerson = Person.call(person,'haha') //抛错

因此,当new.target是undefined时候就会抛错,