为什么`obj.foo = function(){};`没有将名称`foo`分配给函数? [英] Why does `obj.foo = function() { };` not assign the name `foo` to the function?

查看:137
本文介绍了为什么`obj.foo = function(){};`没有将名称`foo`分配给函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自ES2015(ES6)起,函数具有正确的名称(包括官方的名称属性),并且在以多种方式创建函数时分配名称除了明确的函数声明和命名函数表达式,如分配变量(函数的名称设置为变量的名称),分配给对象属性(函数的名称设置为属性的名称),甚至函数参数的默认值(函数的名称设置为参数的名称)。但是分配给现有对象(例如,不在对象初始化程序中)的属性不会将该属性的名称分配给该函数。为什么不?当然必须有一个具体的原因,这是不可取的/可能的。这是什么?

As of ES2015 (ES6), functions have proper names (including an official name property), and names are assigned when the function is created in a variety of ways in addition to the obvious function declaration and named function expression, such as assigning to variables (function's name is set to the variable's name), assigning to object properties (function's name is set to the property's name), even default values for function parameters (function's name is set to the parameter's name). But assigning to a property on an existing object (e.g., not in an object initializer) doesn't assign that property's name to the function. Why not? Surely there must be a specific reason it was not desirable/possible. What was it?

要清楚:我不是在问问如何解决这个问题。我在问什么,当这么多其他(包括默认参数值!)是什么阻止这个看似明显的情况被处理。必须有一个很好的理由。

To be clear: I'm not asking how to work around it. I'm asking what prevents this seemingly-obvious case from being handled when so many others (including default parameter values!) are. There must be a good reason.

请不要推测或理论化。 TC39有理由不包括它。我对这个原因感兴趣我已经通过 TC39会议笔记,但尚未找到。到目前为止我发现的最近的是Allen Wirfs-Brock 回复Bergi 说由于各种异议,因为这种形式的做法并没有达成共识,可惜他并没有说出这些反对意见。

Please don't speculate or theorize. TC39 had a reason for not including it. I'm interested in what that reason was. I've been through the TC39 meeting notes but haven't found it yet. The closest I've found so far is Allen Wirfs-Brock replying to Bergi to say there was no consensus for doing it for that form because of "various objections," but sadly he didn't say what those objections were.

详细说明:

以下所有以下内容将名称 foo 分配给兼容浏览器

All of the following assign the name foo to the function on a compliant browser:

// 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

但分配对于现有对象的属性,对象初始化程序外,不会:

But assigning to a property on an existing object, outside an object initializer, does not:

const obj = {};
obj.foo = function() { };
console.log("Nope:", obj.foo.name);

据我所知,这是由本节,如果 IsIdentifierRef LeftHandSideExpression 是真的(这显然是属性引用不是

As far as I can tell, this is covered by this section of the specification, which explicitly only sets the function name if the IsIdentifierRef of the LeftHandSideExpression is true (which apparently it isn't for property references).

所以从上面重申:为什么不呢?当然必须有一个具体的原因,这是不可取的/可能的。这是什么?

So reiterating from above: Why not? Surely there must be a specific reason it was not desirable/possible. What was it?

推荐答案

Allen Wirfs-Brock有在es讨论列表中回复以及阻止TC39在 obj上的共识的反对意见。 foo = function(){} form:

Allen Wirfs-Brock has replied on the es-discuss list with the objections that prevented the TC39 consensus on the obj.foo = function() { } form:


... for

...for

cache[getUserSecret(user)] = function() {};

它将泄露秘密用户信息作为名称的值

it would leak the secret user info as the value of name

obj[someSymbol] = function() {}

它会将Symbol值作为

it would leak the Symbol value as the value of name

 table[n]=function() {}

名称可能是一个数字字符串

name would likely be a numeric string

有反对意见的计数器(特别是最后一个,这是非常弱的;还有很多其他方式一个函数自动分配一个数字字符串名称),但这不是重点;关键是那些是提出的反对意见。

There are counters to those objections (particularly the last one, which is extremely weak; there are many other ways a function is automatically assigned a numeric string name), but that's not the point; the point is that those were the objections raised.

他还补充说,需要的IsPropertyReference操作(目前只有一个IsIdentifierRef)...

He also added that the IsPropertyReference operation that would be required (where currently there's just an IsIdentifierRef)...


...是一个运行时操作,新的语义需要运行时确定名称值。这是所有额外的运行时工作,可能会减慢循环中出现的函数闭包的创建。

...is a runtime operation and the new semantics require runtime determination of the name value. This is all extra runtime work that may slow down the creation of function closures that appear within loops.

所有这一切,显然在决定的时间,这些反对意见(甚至可能现在也是),这就是为什么这种形式不会自动命名功能,而许多其他人。

So all in all, apparently at the time the decision was taken, those objections carried the day (and quite possibly would now as well), which is why this form doesn't automatically name functions whereas so many others do.

这篇关于为什么`obj.foo = function(){};`没有将名称`foo`分配给函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆