Функция объект, контекст и это

Возможный дубликат:
этот оператор в JavaScript

Термин контекст немного сбивает меня с толку. Если я объявляю функцию внутри функции, то есть вложенную функцию, и выполняю ее сам, как показано ниже...

function  foo(){
    function fo(){
    alert(this);
       }
    fo();
   }

Ключевое слово this должно указывать на объект функции, а не на окно, так как функция fo() находится внутри своей родительской функции. Так как функция также является объектом javascript, то почему ключевое слово this просматривает объект функции и указывает на окно? Также это ключевое слово указывает на текущий объект, с которым работает функция, поэтому объект функции - это объект, с которым работает вложенная функция.

4 ответа

Если вы просто позвоните foo() на верхнем уровне, он идентичен window.foo(),
А также window является фактическим context ну, так что, this указывает на window объект.

Добавление к тому, что сказал dlutxx. Если у вас есть функция (в глобальном пространстве), и вы просто называете ее как foo() контекст - это само окно (так как функция является членом объекта окна). Однако, если вы используете new ключевое слово для получения нового экземпляра функции, this будет ссылаться на объект функции.

function foo() {
    alert(this);
}

foo(); // "this" inside the function will be window

new foo(); // "this" inside the function will be the function object.

Если вы хотите иметь пользовательское значение для this внутри функции вы можете вызвать ее, используя .call() лайк:

foo.call(x); // "this" inside the function will be x

Пример кода для вашего случая:

function  foo(){
    function fo(){
        alert(this);
    }
    fo(); // "this" is window
    new fo(); // "this" is the function object
    fo.call('x'); // "this" is 'x'
}

Если вы случайно используете this внутри функции, которая НЕ является конструктором, вы получите один из нескольких разных результатов:

function callThis () { return this; }


callThis(); // returns window object

var Bob = { func : callThis };

Bob.func(); // returns Bob

callThis.call(Bob);  // returns Bob

Вызов - это метод, который используется для определения контекста вызова.
Если контекст вызова не может быть определен с помощью:

а. Что перед "." (Bob.func();)
б. Что явно передается в .call(), .apply() или же .bind()

Тогда это установлено window,

Так решается контекст.

Так что если у вас есть конкретный объект для thisтогда ваши решения следующие:

function objMethod () {
    var self = this;
    function doStuff () {
        self.otherFunc();
        self.otherProperty = "bob";
    }

    doStuff();
}


var myObj = { myMethod : objMethod };
myObj.myMethod();

myObj звонки objMethod с установленным контекстом myObj,
objMethod сохраняет ссылку на текущий контекст (myObj) как self, doStuff использует ссылку для изменения свойств ссылочного объекта.

function outer () {
    function inner () { this.property = "Bob"; }
    inner.call(this);
}


var obj = {};
outer.call(obj);

Вот, outer передается контекст, используя .call(),
затем inner передан this из outerопять же используя .call()

var bob = { name : "Bob" };

function sayName () { console.log(this.name); }

var bobFunc = sayName.bind(bob);
bobFunc();

Здесь мы используем .bind() создать версию sayName где this всегда установлен на bob,
Вы можете свободно смешивать и сочетать эти системы, сколько захотите (и при работе с асинхронным программированием вы, скорее всего, это сделаете).

Я понимаю, что хотя function fo() определяется в объеме function foo()Это означает, что он не доступен извне foo если вы не вернете его, правила, которые применяются к значению this когда вы вызываете эту внутреннюю функцию, все равно, как если бы вы вызывали любую другую функцию.

function f() {
    function g() {
        console.log(this)
    }
    console.log(this);
    g();
    g.apply(this);
    }

f()           // => Window, Window, Window
f.apply(this) // => Window, Window, Window
f.apply({})   // => Object, Window, Object
Другие вопросы по тегам