Работает так, потому что каждая функция имеет свой собственный контекст выполнения .
Однако есть и другие способы сделать это, например:
Использование call
или apply
для вызова функции:
function Alpha() {
this.onion = 'onion';
function Beta() {
alert(this.onion);
}
Beta.call(this);
}
var alpha1 = new Alpha();
// Alerts 'onion'
В новом стандарте ECMAScript 5-го издания представлен способ сохранения функции context , метод Function.prototype.bind
:
function Alpha() {
this.onion = 'onion';
var Beta = function () {
alert(this.onion);
}.bind(this);
Beta();
}
var alpha1 = new Alpha();
// Alerts 'onion'
Можно сказать, что функция Beta
ограничена , и как бы вы ее ни вызывали, ееЗначение this
останется неизменным.
Этот метод пока широко не поддерживается, в настоящее время его включает только IE9pre3, но вы можете включить реализацию , чтобы заставить его работать сейчас.
Теперь позвольте мне подробнее рассказать о том, как работает this
:
Значение this
существует в каждом контексте выполнения , и для кода функции устанавливается неявно, когда выполняется вызов функциизначение определяется в зависимости от того, как ссылка , если сформирована.
В вашемНапример, когда вы вызываете Beta();
, поскольку он не привязан ни к какому объекту, мы можем сказать, что ссылка не имеет базового объекта , тогда значение this
будет ссылаться на глобальный объект.
Другой случай возникает, когда вы вызываете функцию, которая связана как свойство объекта, например:
var obj = {
foo: function () { return this === obj;}
};
obj.foo(); // true
Как видите, вызываемая ссылка obj.bar();
содержит базуобъект, который равен obj
, и значение this
внутри вызванной функции будет ссылаться на него.
Примечание : тип ссылки абстрактная концепция, определенная для целей реализации языка, вы можете увидеть подробности в спецификации.
Третий случай, когда значение this
устанавливается неявно, это когда вы используете оператор new
, онбудет ссылаться на вновь созданный объект, который наследуется от прототипа его конструктора:
function Foo () {
return this; // `this` is implicitly returned when a function is called
} // with `new`, this line is included only to make it obvious
var foo = new Foo();
foo instanceof Foo; // true
Foo.prototype.isPrototypeOf(foo); // true