深入理解ES6
三、函数
1.默认参数值对arguments的影响
在ES5非严格模式下参数的改变会同步到arguments对象中
function test(name,age) {
console.log(name===arguments[0]); //true
console.log(age===arguments[1]); //true
name='张三';
age=12;
console.log(name===arguments[0]); //true
console.log(age===arguments[1]); //true
}
test('李四',10);
在ES5严格模式下则会输出
true
true
false
false
在ES6中无论是否指定严格模式,都与ES5严格模式相同。
function test(name,age=18) {
console.log(arguments.length);
console.log(name===arguments[0]);
console.log(age===arguments[1]);
name='张三';
age=12;
console.log(name===arguments[0]);
console.log(age===arguments[1]);
}
test('李四');
输出
1
true
false
false
false
这样总是可以通过arguments对象将参数恢复为默认值。
2.不定参数
function test(name,...args) {
console.log(name); // 李四
console.log(args); // [18, "man"]
}
test('李四',18,'man');
- 不可以在setter中使用。
- 无论是否使用不定参数,arguments对象总是包含所有传入对象的参数。
3.展开运算符
var value=[2,3,6,32,-1,-200];
console.log( Math.max.apply(Math,value) ); //32
因为Math.max(1,2,.......)可以传递不限定参数并返回最大的一个,但是不支持传递数组,所以借助Array原型链上的apply方法的第二个参数来实现传递数组的目的。
ES6的展开运算符可以简化上述事例
var value=[2,3,6,32,-1,-200];
console.log(Math.max.apply(Math,value)); //32
console.log(Math.max(...value)); //32
value=[-12,-294,-29,-49]
console.log(Math.max(...value,0)); //0 限定最小值
3.明确函数的多种用途
1.关于函数的new操作
function Test(name) {
this.name=name;
}
console.log(new Test('张三')); // [Object Object]
console.log(Test('张三')); // undefined
console.log(name); //张三
不同过new调用Test,会返回undefined,在非严格模式下还会创建一个全局变量
JS函数有两个内部方法[call]和[constructor]
- 通过new关键字调用函数时执行[constructor]函数时
- 创建一个实例对象
- 绑定this到此对象上
- 执行函数体
- 返回此对象
- 不同过new调用函数时执行[call]函数,直接执行函数体 箭头函数没有[constructor]方法
2.在es5中判断函数被调用的方式
function Person(name) {
if(this instanceof Person) {
this.name=name;
}else {
throw new Error('请用new调用函数')
}
}
const person=new Person('jack');
const person=Person('jack'); // error
此方式有缺陷,如
const person=Person.call(person,'jack'); // 有效
这种情况函数调时无法分辨是否使用new关键字
3.元属性 new.target
es6引入new.target元属性(☞非对象的属性),当调用函数的[construtor]方法时被赋值为构造函数,若调用[call]则被赋值为undefined
function Person(name) {
console.log(new.target); // 1.使用new关键字 new.target=Person 2.直接调用 new.target=undefined
if(new.target===Person) {
this.name=name;
}else {
throw new Error('请用new调用函数')
}
}
const person=new Person('jack');
const person2=Person('jack'); // error
Person.call(person,'jack');// error
不能在函数外使用new.target