javascript - with - Por que `obj.foo=function(){};` não atribui o nome `foo` à função?




lista de funções javascript (2)

Allen Wirfs-Brock respondeu na lista es-discuss com as objeções que impediram o consenso do obj.foo = function() { } no obj.foo = function() { } :

...para

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

vazaria as informações secretas do usuário como o valor do nome

e para

obj[someSymbol] = function() {}

vazaria o valor do símbolo como o valor do nome

e para

 table[n]=function() {}

nome provavelmente seria uma sequência numérica

Existem contadores para essas objeções (particularmente a última, que é extremamente fraca; existem muitas outras maneiras pelas quais uma função recebe automaticamente um nome de string numérico), mas esse não é o ponto; o ponto é que essas foram as objeções levantadas.

Ele também acrescentou que a operação IsPropertyReference seria necessária (onde atualmente há apenas um IsIdentifierRef) ...

... é uma operação de tempo de execução e a nova semântica requer determinação em tempo de execução do valor do nome. Isso é todo o trabalho de tempo de execução extra que pode retardar a criação de fechamentos de funções que aparecem nos loops.

Portanto, aparentemente, no momento em que a decisão foi tomada, essas objeções continuaram o dia (e possivelmente também agora), e é por isso que esse formulário não nomeia automaticamente funções, enquanto tantas outras o fazem.

No ES2015 (ES6), as funções têm nomes próprios (incluindo uma propriedade de name oficial) e os nomes são atribuídos quando a função é criada de várias maneiras, além da declaração óbvia da função e da expressão da função nomeada, como a atribuição a variáveis (o nome da função é definido como o nome da variável), atribuindo às propriedades do objeto (o nome da função é definido como o nome da propriedade), até os valores padrão dos parâmetros da função (o nome da função é definido como o nome do parâmetro). Mas atribuir a uma propriedade em um objeto existente (por exemplo, não em um inicializador de objetos) não atribui o nome dessa propriedade à função. Por que não? Certamente deve haver uma razão específica para não ser desejável / possível. O que foi isso?

Para ser claro: não estou perguntando como contornar isso. Estou perguntando o que impede que esse caso aparentemente óbvio seja tratado quando tantos outros (incluindo valores de parâmetro padrão!). Deve haver uma boa razão.

Por favor, não especule ou teorize. O TC39 tinha um motivo para não incluí-lo. Estou interessado em saber o motivo. Passei as notas da reunião do TC39, mas ainda não as encontrei. O mais próximo que eu encontrei até agora é Allen Wirfs-Brock respondendo a Bergi para dizer que não havia consenso em fazê-lo para essa forma por causa de "várias objeções", mas, infelizmente, ele não disse quais eram essas objeções.

Detalhes:

Todos os itens a seguir atribuem o nome foo à função em um navegador compatível :

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

Mas atribuir a uma propriedade em um objeto existente, fora de um inicializador de objeto, não:

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

Tanto quanto eu posso dizer, isso é coberto por esta seção da especificação, que define explicitamente apenas o nome da função se IsIdentifierRef do LeftHandSideExpression for verdadeiro (o que aparentemente não é para referências de propriedades).

Então, reiterando de cima: Por que não? Certamente deve haver uma razão específica para não ser desejável / possível. O que foi isso?


Não tenho certeza se existe um motivo específico.

obj.foo = function (){};

primeiro cria uma referência para a expressão da função em obj e, em seguida, liga foo a essa referência que já possui um nome (somente leitura).

Assim:

obj.fooC = (new Function ());
console.log(obj.fooC.name);//'anonymous'

obj.fooFE = function (){};
console.log(obj.fooFE.name);//''

obj.fooNFE = function a_name (){};
console.log(obj.fooNFE.name);//'a_name'

é um comportamento normal.

Existe alguma restrição para escrever:

obj.foo = (function foo(){});




ecmascript-6