一. 默认参数值
举个栗子:
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时候就会抛错,