Функция объект, контекст и это
Возможный дубликат:
этот оператор в 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