ES6 的函数 name 属性
定义函数有各种各样的方式,在 JS
中识别函数就变得很有挑战性。此外,匿名函数表达式的流行使得调试有点困难,经常导致堆栈跟踪难以被阅读与解释。正因为此,ES6
给所有函数添加了 name
属性。
选择合适的名称
ES6
中所有函数都有适当的 name
属性值。为了理解其实际运作,请看下例——它展示了一个函数与一个函数表达式,并将二者的 name
属性都打印出来:
function doSomething() {
// ...
}
var doAnotherThing = function() {
// ...
};
console.log(doSomething.name); // "doSomething"
console.log(doAnotherThing.name); // "doAnotherThing"
在此代码中,由于是一个函数声明,doSomething()
就拥有一个值为 "doSomething"
的 name
属性。而匿名函数表达式 doAnotherThing()
的 name
属性值则是 "doAnotherThing"
,因为这是该函数所赋值的变量的名称。
匿名函数的名称属性在 |
名称属性的特殊情况
虽然函数声明与函数表达式的名称易于查找,但 ES6
更进一步确保了所有函数都拥有合适的名称。为了表明这点,请参考如下程序:
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"
var descriptor = Object.getOwnPropertyDescriptor(person, "firstName");
console.log(descriptor.get.name); // "get firstName"
本例中的 doSomething.name
的值是 "doSomethingElse"
,因为该函数表达式自己拥有一个名称,并且此名称的优先级要高于赋值目标的变量名。person.sayName()
的 name
属性值是 "sayName"
,正如对象字面量指定的那样。类似的,person.firstName
实际是个 getter
函数,因此它的名称是 "get firstName"
,以标明它的特征;同样,setter
函数也会带有 "set"
的前缀(getter
与 setter
函数都必须用 Object.getOwnPropertyDescriptor()
来检索)。
函数名称还有另外两个特殊情况。使用 bind()
创建的函数会在名称属性值之前带有 "bound"
前缀;而使用 Function
构造器创建的函数,其名称属性则会有 "anonymous"
前缀,正如此例:
var doSomething = function() {
// ...
};
console.log(doSomething.bind().name); // "bound doSomething"
console.log((new Function()).name); // "anonymous"
绑定产生的函数拥有原函数的名称,并总会附带 "bound"
前缀,因此 doSomething()
函数的绑定版本就具有 "bound doSomething"
名称。
需要注意的是,函数的 |