`Это` во вложенной функции является глобальным объектом

Может ли кто-нибудь объяснить концепцию, стоящую за этим?

предположим, что у нас есть функция как метод объекта:

var myobj = {
    myfunc : function () {      
        console.log(this); // Logs reference to myobj.                            
    }
};
myobj.myfunc();

в то время как вложенная функция внутри той же функции myfunc будет возвращать ссылку на головной объект (окно):

var myobj = {
    myfunc : function () {      
       ( function (){
           console.log(this); // Logs reference to head window object.   
       })();                     
    } 
 };
myobj.myfunc();

Меня действительно смущает, как это работает, так как я думал, что функция всегда будет возвращать ссылку на родительский объект.

Вопрос в том, является ли это фиксированным правилом, то есть любая вложенная функция всегда будет возвращать ссылку на window?


person ProllyGeek    schedule 27.08.2014    source источник
comment
связанные: stackoverflow.com/questions/8670877/   -  person alexp    schedule 27.08.2014
comment
ваша внутренняя функция - это закрытие, поэтому это всегда будет указывать на объект окна. Вы должны сохранить это во временной переменной, прежде чем обращаться к ней внутри анонимной функции.   -  person Prabhu Murthy    schedule 27.08.2014
comment
это может быть полезным постом для тех, кто ищет более глубокое объяснение: benalman .com/news/2010/11/ , спасибо adeneo за поисковый ключ IIFE.   -  person ProllyGeek    schedule 27.08.2014
comment
Не могли бы вы опубликовать свой код с удобным отступом?   -  person Bergi    schedule 27.08.2014
comment
@Bergi Берги, думаю, у вас есть право редактировать мой код, идите вперед и исправьте его, если хотите, добро пожаловать.   -  person ProllyGeek    schedule 27.08.2014
comment
@ProllyGeek: Да, у меня есть привилегия редактировать его, но у вас, как автора, есть обязанность помещать читаемый код в ваши вопросы - это помогает получить хорошие ответы и плюсы.   -  person Bergi    schedule 27.08.2014
comment
@Bergi хорошо сделано, дайте мне знать, если потребуются дальнейшие модификации.   -  person ProllyGeek    schedule 27.08.2014


Ответы (2)


Значение this внутри функции зависит от того, как она вызывается, а не от того, как она определена.

Когда вы вызываете функцию в области myobj, myobj будет значением this

myobj.myfunc();

Когда вы вызываете функцию без контекста выполнения, значением this будет глобальный объект, в данном случае window.

function test() {

    console.log(this); // window

}

test(); // global context

когда вы создаете IIFE, контекстом выполнения является окно, поскольку никакой другой контекст не установлен

( function (){
    console.log(this); // window
})();

Затем есть apply, call и bind, которые позволяют вам установить другое значение this для вызываемой функции.

person adeneo    schedule 27.08.2014
comment
На самом деле я это уже знаю, но мой вопрос ясен, все дело в вложенных функциях, будет ли какая-либо вложенная функция возвращать ссылку на головной объект? - person ProllyGeek; 27.08.2014
comment
Дело не во вложенных функциях, важно не то, как функция определена, а то, как она вызывается. IIFE вызывается сразу без специального контекста, поэтому он использует глобальный контекст, поэтому this внутри функции — это окно. - person adeneo; 27.08.2014
comment
IIFE ммм, после поиска я понял, спасибо за выражение. - person ProllyGeek; 27.08.2014
comment
Нет проблем, просто постарайтесь помнить, что важно не то, как вы определяете функцию, а то, как вы ее называете, и если она вызывается без контекста, она всегда будет использовать глобальный контекст (окно). Как только вы это поймете, грокать будет намного легче. - person adeneo; 27.08.2014
comment
пожалуйста, проверьте мой собственный ответ. - person ProllyGeek; 27.08.2014
comment
Независимо от того, что плавает ваша коза! - person adeneo; 27.08.2014

Боюсь, что правильный ответ выглядит следующим образом (после 2 часов поиска) эта книга " JavaScript Succinctly" утверждает, что:

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

в нем также говорится, что:

Хорошая новость заключается в том, что это будет исправлено в ECMAScript 5. На данный момент вы должны знать об этом затруднительном положении, особенно когда вы начинаете передавать функции в качестве значений другим функциям.

поэтому просто ответ ДА, любая вложенная функция всегда будет возвращать головной объект в качестве ссылки.

Также вы можете использовать обходной путь для решения этой проблемы, сохраняя значение this, как только оно становится доступным, например:

var myObject = {  
    myProperty: 'I can see the light', 
    myMethod : function() {
        var that = this; // Store a reference to this (i.e. myObject) in myMethod scope.
        var helperFunction = function() { // Child function.    // Logs 'I can see the light' via scope chain because that = this.
            console.log(that.myProperty); // Logs 'I can see the light'.
            console.log(this); // Logs window object, if we don't use "that".
        }(); 
    }
};  
myObject.myMethod(); // Invoke myMethod. 
person ProllyGeek    schedule 27.08.2014