2010-11-23 4 views
2

Почему функция самозапуска внутри функции не получает объем внешней функции в JavaScript?Область функции самозапуска в Javascript

var prop = "global"; 

var hash = { 
    prop: "hash prop", 
    foo: function(){ 
     console.log(this.prop); 
     (function bar(){ 
      console.log(this.prop); 
     })(); 
    } 
}; 

var literal = { 
    prop: "object" 
}; 

hash.foo(); 
// hash prop 
// global 

hash.foo.call(literal); 
// object 
// global 

Похоже, что изменение сферы внешней функции не влияет на объем внутренней функции самозапуска.

PS: Вопрос не в том, как изменить объем внутренней функции. Но каково правильное объяснение в перспективе «Javascript language»? По умолчанию все ли самозагружаемые функции имеют глобальную область? Если да, то почему?

ответ

1

Вы не применяете никаких объектов в качестве контекста this, когда вы вызываете внутреннюю функцию, поэтому по умолчанию значение this установлено равным window. Если вы хотите, чтобы вызвать закрытие с тем же this как внешней функции, вы должны сделать:

(function bar(){ 
    console.log(this.prop); 
}).call(this); 

Или:

var that = this; 
(function bar(){ 
    console.log(that.prop); 
})(); 
+0

+1 для первого решения! – 2010-11-23 22:17:49

7

Ваша проблема заключается в this и что она ссылается:

foo: function(){ 
    console.log(this.prop); 
    (function bar(){ 
     console.log(this.prop); <--- this does not reference to foo here, but instead it refers to the window object 
    })(); 
} 

Вы должны держать ссылку на внешний this:

foo: function(){ 
    console.log(this.prop); 

    var that = this; 
    (function bar(){ 
     console.log(that.prop); <--- tada! 
    })(); 
} 

Update
Некоторые пояснения. Это все о том, как JavaScript определяет контекст при вызове функции.

function Test() { 
    this.name = "Test"; 
    this.bar = function() { console.log("My name is: "+ this.name);} 
} 

function Blub() { 
    this.name = "Blub"; 
    this.foo = function() { console.log("My name is: " + this.name);} 
} 

var a = new Test(); 
var b = new Blub(); 

// this works as expected 
a.bar(); // My name is: Test 
b.foo(); // My name is: Blub 

// let's do something fun 
a.foo = b.foo; // make an educated guess what that does... 

a.foo() // My name is: Test 

Да? Разве мы не ссылаемся на method Blub? Нет, мы не. Мы ссылаемся на несвязанный function Blub.

JavaScript привязывается к . (точкам) и основывается на том, что он решает, что значение this должно быть.

Поскольку вы не вызываете свою анонимную функцию на объект (поэтому нет .), она будет ссылаться на глобальный объект, который - в случае браузера - объект окна.

Другой пример (можно подумать, что это будет работать):

var str = "Hello World"; 
var ord = str.charCodeAt; // let's make a little shortcut here.... bad idea 

ord(0) // no dot... 

Вместо полукокса кодов, которые в str мы получаем те, которые находятся в глобальном объекте, конечно, это не строка так charCodeAt звонки toString, по которым результаты "[object DOMWindow]"

+1

`this` будет ссылаться на глобальный объект, а не на` bar`. [Подробнее] (http://stackoverflow.com/questions/4223001/what-does-this-refer-to/4223037#4223037). – CMS 2010-11-23 22:15:50

Смежные вопросы