Pergunta

Hoje eu tive uma discussão com um colega sobre funções aninhadas em Javascript:

function a() {
   function b() {
      alert('boo')
   }
   var c = 'Bound to local call object.'
   d = 'Bound to global object.'
}

Neste exemplo, ensaios apontam que b não é acessível do lado de fora do corpo de um, bem como c é. No entanto, é d - após a execução de uma (). Olhando para a definição exata desse comportamento no v ECMAScript. 3 padrão , eu não encontrar as palavras exatas que eu estava procurando; o que Sec.13 p.71 não diz, é que objeto o objeto função criada pela declaração declaração de função deve ser vinculado. Estou faltando alguma coisa?

Foi útil?

Solução

Esta é escopo estático. Instruções dentro de uma função são escopo dentro dessa função.

Javascript tem um comportamento peculiar, no entanto, o que é que sem o var palavra-chave, você já implicava um variável global . Isso é o que você está vendo em seu teste. Seu "d" variável está disponível porque é uma implícita global, apesar de ser escrito dentro do corpo de uma função.

Além disso, para responder à segunda parte da sua pergunta:. A função existe em qualquer âmbito é declarado, assim como uma variável

Sidenote: Você provavelmente não quer variáveis ??globais, especialmente os não implícitas. É recomendável que você sempre usa a palavra-chave var, para evitar confusão e para manter tudo limpo.

Sidenote: A ECMA padrão não é provavelmente o lugar mais útil para encontrar respostas sobre Javascript, embora certamente não é um recurso ruim. Lembre-se que o JavaScript no seu navegador é apenas uma implementação desse padrão, então o documento padrões serão dando-lhe as regras que foram (principalmente) seguidos pelos implementadores quando o motor javascript estava sendo construída. Ele não pode oferecer informações específicas sobre as implementações que se preocupam, ou seja, os principais navegadores. Há um par de livros, em particular, que lhe dará informação muito direta sobre como as implementações de JavaScript nos principais navegadores se comportam. Para ilustrar a diferença, eu vou incluir trechos abaixo, tanto a especificação ECMAScript, e um livro sobre Javascript. Eu acho que você vai concordar que o livro dá uma resposta mais direta.

Eis a partir do ECMAScript Language Specification :

10,2 Entrando um contexto de execução

função toda e chamada do construtor entra em um novo contexto de execução, mesmo se uma função é que se autodenomina de forma recursiva. Cada um saídas de retorno contexto de execução. A exceção lançada, se não for pego, pode também sair um ou mais contextos de execução.

Quando o controle entra um contexto de execução, o escopo cadeia é criado e inicializado, instanciação variável é realizada, e a este valor é determinado.

A Inicializao da cadeia do escopo, instanciação variável, eo determinação do valor este dependerá sobre o tipo de código que está sendo digitado.

Aqui está a partir de Javascript de O'Reilly: The Definitive Guia (5th Edition) :

8.8.1 Lexical Scoping

Funções em JavaScript são lexically ao invés de escopo dinamicamente. este significa que eles correm no âmbito de que eles são definidos, não o escopo a partir do qual eles são executados. Quando um função é definida, o alcance actual cadeia é guardado e torna-se parte de o estado interno da função. ...

Altamente recomendado para cobrir esses tipos de perguntas é o livro de Douglas Crockford:

JavaScript, The Good Parts http://oreilly.com/catalog/covers/9780596517748_cat.gif

Javascript, The Good Parts , também de O 'Reilly.

Outras dicas

Pelo que entendi, estes são equivalentes, na medida do escopo está em causa:

function a() { ... }

e

var a = function() { ... }

Parece importante notar que, enquanto d está sendo criado como um "global", que é na realidade que está sendo criado como uma propriedade do objeto janela. Isso significa que você pode inadvertidamente ser substituindo algo que já existe no objeto janela ou sua variável pode realmente deixar de ser criado em tudo. Assim:

function a() {
    d = 'Hello World';
}
alert(window.d); // shows 'Hello World'

Mas você não pode fazer:

function a() {
    document = 'something';
}

porque você não pode substituir o objeto window.document.

Para todos os efeitos práticos, você pode imagem que todo o código está sendo executado em um bloco with(window) gigante.

Javascript tem dois âmbitos. Global, e funcional. Se você declarar uma variável dentro de uma função usando a palavra-chave "var", será local para essa função, e todas as funções internas. Se você declarar um fora variável de uma função, tem escopo global.

Finalmente, se você omitir a palavra-chave var ao primeiro declarar uma variável, javascript assume que você queria uma variável global, não importa onde você declará-lo .

Então, você está chamando uma função, e funcionar um está declarando uma variável d global.

...

function a() {
   function b() {
      alert('boo')
   }
   var c = 'Bound to local call object.'
   d = 'Bound to global object.'
}

sem ser precedido por var , d é global. Faça isso para feitos d privada:

function a() {
   function b() {
      alert('boo')
   }
   var c = 'Bound to local call object.'
   var d = 'Bound to local object.'
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top