从 ES2015 (ES6) 开始,函数有了专有名称(包括官方名称)name
属性),而函数创建时的赋值除了明显的函数声明和命名函数表达式之外还有多种方式,比如给变量赋值(函数的名字设置为变量的名字)、给对象属性赋值(函数的名称设置为属性的名称),甚至函数参数的默认值(函数的名称设置为参数的名称)。但是分配给现有对象上的属性(例如,不在对象初始值设定项中)不会将该属性的名称分配给函数。为什么不?肯定一定有一个specific原因是它不理想/不可能。它以前如何?
需要明确的是:我并不是在问如何解决这个问题。我问的是,当有这么多其他情况(包括默认参数值!)时,是什么阻止了这种看似明显的情况的处理。一定有一个很好的理由。
请不要猜测或推理。TC39 不包括它是有原因的。我很感兴趣那个原因是什么。我已经经历过TC39 会议记录 https://github.com/rwaldron/tc39-notes但还没找到。到目前为止我发现的最接近的是 Allen Wirfs-Brock回复 贝尔吉 https://esdiscuss.org/topic/name-anonymous-functions-on-property-assignments他说,由于“各种反对意见”,因此没有就该表格达成共识,但遗憾的是,他没有说明这些反对意见是什么。
Details:
以下所有分配名称foo
到 a 上的函数兼容浏览器 https://kangax.github.io/compat-table/es6/#test-function_name_property:
// Requires a compliant browser
// Assigning to a variable or constant...
// ...whether in the initializer...
{
let foo = function() { };
console.log("1:", foo.name); // "foo"
}
{
const foo = function() { };
console.log("2:", foo.name); // "foo"
}
// ...or later...
{
let foo;
foo = function() { };
console.log("3:", foo.name); // "foo"
}
// As an initializer for an object property
{
const obj = {
foo: function() { }
};
console.log("4:", obj.foo.name); // "foo"
}
// Or as a method
{
const obj = {
foo() { }
};
console.log("5:", obj.foo.name); // "foo"
}
// Even if it's a computed property name
{
let name = "f";
const obj = {
[name + "o" + "o"]() { }
};
console.log("6:", obj.foo.name); // "foo"
}
// As a default value for a parameter
(function(foo = function() { }) {
console.log("7:", foo.name); // "foo"
})();
// ...and a bunch of others
但是,在对象初始值设定项之外分配给现有对象的属性不会:
const obj = {};
obj.foo = function() { };
console.log("Nope:", obj.foo.name);
据我所知,这涵盖了本节 http://www.ecma-international.org/ecma-262/7.0/index.html#sec-assignment-operators-runtime-semantics-evaluation规范的,它明确地仅设置函数名称,如果是标识符引用 of the 左手边表达是真的(显然it isn't http://www.ecma-international.org/ecma-262/7.0/index.html#sec-static-semantics-static-semantics-isidentifierref供财产参考)。
所以重申上面的观点:为什么不呢?肯定一定有一个specific原因是它不理想/不可能。它以前如何?
艾伦·维尔夫斯-布洛克有在 es-讨论列表中回复 https://esdiscuss.org/topic/name-anonymous-functions-on-property-assignments#content-20反对意见阻碍了 TC39 达成共识obj.foo = function() { }
form:
...for
cache[getUserSecret(user)] = function() {};
它会泄露秘密用户信息作为名称的值
and for
obj[someSymbol] = function() {}
它将泄漏 Symbol 值作为 name 的值
and for
table[n]=function() {}
名称可能是一个数字字符串
对于这些反对意见,有一些反对意见(特别是最后一个,它非常弱;还有许多其他方法可以自动为函数分配数字字符串名称),但这不是重点;关键是这些就是提出的反对意见。
他还补充说,需要 IsPropertyReference 操作(目前只有 IsIdentifierRef)...
...是运行时操作,新语义需要运行时确定名称值。这些都是额外的运行时工作,可能会减慢循环中出现的函数闭包的创建速度。
总而言之,显然在做出决定时,这些反对意见占了上风(现在很可能也会如此),这就是为什么这种形式不会自动命名函数,而其他许多形式却这样做。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)