Misunderstanding Scope in JavaScript?

5

Eu vi alguns poucos outro falam sobre o escopo de vinculação em JavaScript, mas sempre me pareceu que essa é uma frase imprecisa. Os Function.prototype.call e Function.prototype.apply não passam o escopo entre dois métodos; eles mudam o chamador da função - duas coisas muito diferentes. Por exemplo:

function outer()
{
    var item = { foo: 'foo' };
    var bar = 'bar';
    inner.apply(item, null);
}

function inner()
{
    console.log(this.foo); //foo
    console.log(bar);      //ReferenceError: bar is not defined
}

Se o escopo de outer fosse realmente passado para inner , eu esperaria que inner fosse capaz de acessar bar , mas não é possível. bar estava no escopo em outer e está fora do escopo em inner . Assim, o escopo não foi aprovado. Mesmo os documentos do Mozilla não mencionam nada sobre a passagem do escopo:

Calls a function with a given this value and arguments provided as an array.

Estou entendendo errado o escopo ou especificamente o escopo aplicado ao JavaScript? Ou são esses outros desenvolvedores que estão entendendo mal?

    
por Jeff 18.09.2012 / 19:07
fonte

3 respostas

3

Você está correto. É melhor pensar em termos de contexto de objeto do que escopo com chamada e aplicação. No entanto, este exemplo a seguir pode ser visto como tornar um escopo acessível para outro contexto de objeto:

function objFactory(){
    var someProperty = 'a property of some sort';
    this.getSomeProperty = function(){ return someProperty; };
}

var someObj = new objFactory(),
somePlainObj = {};

'a property of some sort' === someObj.getSomeProperty.apply(somePlainObj);//true

Eu posso não ter os detalhes exatos, mas acho que objetos JS construídos a partir de construtores de função são basicamente apenas funções que são copiadas (juntamente com seus escopos - escopos js são apenas funções), executadas e simplesmente nunca coletar lixo (então todos os valores são persistentes) e atribuídos a um namespace, você pode acessar suas propriedades definidas internamente através de regras 'this' alteradas quando você invocar com a palavra-chave 'new'. Mas as vars internas não são exatamente propriedades privadas (embora tendamos a pensar nelas dessa maneira). Eles são propriedades do construtor da função acessadas pelos métodos por meio do encerramento.

Mas a primeira parte do processo ainda é como uma função de disparo. Isso faz com que o var interno seja acessado via fechamento, que é como uma cópia do escopo no momento em que o construtor foi finalizado com a etapa de execução da função.

    
por 18.09.2012 / 19:36
fonte
3

Quando você chama inner.apply (item, null) você está chamando inner () como se fosse um método do item objeto que tem foo definido nele. Isso define o objeto this em inner () como item . Você não está realmente expondo o escopo da função outer () para a função inner () . Você está passando o objeto (e pode, portanto, acessar seus atributos). Você não está passando o escopo léxico da função que definiu esse objeto.

    
por 18.09.2012 / 19:32
fonte
2

Veja o link , a série de artigos "Aprendendo JavaScript com gráficos de objetos". apply e call são a coisa mais mágica em JS (provavelmente junto com o escopo de fechamento), você não pode entender completamente a menos que você entenda o básico.

    
por 18.09.2012 / 19:39
fonte