1.构造函数
通常用来动态创建新的函数,接收字符串形式的参数,分别为函数参数及函数体;增强功能,支持定义默认参数和不定参数。
var add = new Function("first", "second = first", "return first + second");
console.log(add(1)); // 2
var pickFirst = new Function("...args", "return args[0]");
console.log(pickFirst(1, 2)); // 1
2.展开运算符
Math.max()方法可以接受任意数量参数并返回最大值。
let value1 = 25,
value2 = 50;
console.log(Math.max(value1, value2)); // 50
但max方法不允许传入数组,可能需要手动遍历从数组中取值,或者使用apply。
let values = [25, 50, 75, 100];
console.log(Math.max.apply(Math, values)); // 100
这样很难让人看懂代码的意图,可以使用展开运算符,将参数数组分割为各自独立的参数传入。
let values = [25, 50, 75, 100];
console.log(Math.max(...values)); // 100
// 等价于 console.log(Math.max(25, 50, 75, 100));
看起来更加简洁易懂,还可以传入其他参数使用,如:(…values, 0)。
3.name属性
函数新增了name属性用于区分辨别函数。
函数name为声明名称,表达式name为赋值时变量的名称,如:
function doSomething() {}
var doAnotherThing = function() {}
console.log(doSomething.name); // "doSomething"
console.log(doAnotherThing.name); // "doAnotherThing"
name属性的特殊情况,如:
var doSomething = function doSomethingElse() {};
var person = {
get firstName() {
return 'Nicholas'
},
sayName: function() {
console.log(this.name);
}
}
console.log(doSomething.name); // "doSomethingElse"
console.log(person.sayName.name); // "sayName"
console.log(person.firstName.name); // "get firstName"
函数表达式的名称权重比被赋值变量高;person.firstName实际上是一个getter函数,所以它的名称为get firstName。
还有两个名称的特例:通过bind函数创建的名称带有bound前缀;通过Function构造函数创建的名称是anonymous。
var doSomething = function() {};
console.log(doSomething.bind().name); // "bound doSomething"
console.log((new Function()).name); // "anonymous"
切记,函数的name属性不一定引用同名变量,所以不能使用name属性值来获取对于函数的引用。
4.函数调用
函数有两个内部方法:call和construct。call直接执行代码中的函数体;construct通过new关键字调用,创建一个实例新对象,然后执行函数体,将this绑定到实例上。
可以用instanceof判断是否通过new调用,如:
function Person(name) {
if (this instanceof Person) {
this.name = name;
} else {
throw new Error("通过关键字调用");
}
}
var person = new Person("Nicholas");
var notAPerson = Person("Nicholas"); // 抛出错误
此方法并不完全可靠,我们可以使用call和apply将this绑定到person上,这两种情况是无法区分的。
var notAPerson = Person.call(person, "Nicholas");
元属性new.target可以用来区分,它可以提供非对象目标的补充信息。当调用construct方法时,new.target被赋值为new操作符的目标,通常是新创建的实例,也就是函数体内的构造函数;如果调用call方法,则为undefined。因此判断条件可以修改为:
new.target === Person
注意:不能在函数外使用new.target。
5.箭头函数
- 没有this、super、arguments和new.target绑定:这些值由外层最近一层非箭头函数决定。
- 不能通过new调用:没有construct方法,不能被用作构造函数,new会抛出错误。
- 没有原型:不存在prototype。
- 不可以改变this绑定:函数内部的this值不可被改变。
- 不支持arguments对象:必须通过命名参数和不定参数访问函数参数。
- 不支持重复命名参数。