Funciona de esta manera porque cada función ha asociado su propio contexto de ejecución .
Sin embargo, hay otras maneras de hacerlo, por ejemplo:
Uso call
o apply
para invocar la función:
function Alpha() {
this.onion = 'onion';
function Beta() {
alert(this.onion);
}
Beta.call(this);
}
var alpha1 = new Alpha();
// Alerts 'onion'
El nuevo ECMAScript quinta edición estándar, introduce una manera de mantener la función contexto, el método Function.prototype.bind
:
function Alpha() {
this.onion = 'onion';
var Beta = function() {
alert(this.onion);
}.bind(this);
Beta();
}
var alpha1 = new Alpha();
// Alerts 'onion'
Podemos decir que la función Beta
es enlazada, y no importa cómo la invoque, su valor this
estará intacto.
Este método no es ampliamente compatible todavía, actualmente solo IE9pre3 lo incluye, pero puede incluir an implementation para que funcione ahora.
Ahora voy a extenderme sobre cómo this
obras: existen
El valor this
en cada execution context, y por el código de función se establece implícitamente cuando se hace una llamada a la función, se determina el valor en función de cómo la referencia si formado.
En su ejemplo, cuando se invoca Beta();
, ya que no está vinculado a ningún objeto, podemos decir que la referencia no tiene un objeto de base , entonces, el valor this
se referirá al objeto global.
Otro caso ocurre cuando se invoca una función que está enlazado como una propiedad de un objeto, por ejemplo:
var obj = {
foo: function() { return this === obj;}
};
obj.foo(); // true
Como se puede ver, la referencia que se invoca obj.bar();
contiene un objeto de base, que es obj
y el valor this
dentro de la función invocada se referirá a él.
Nota: El reference type es un concepto abstracto, se define a efectos de ejecución lenguaje se pueden ver los detalles en la especificación.
Un tercer caso en el que el valor this
se establece implícitamente es cuando se utiliza el operador new
, se refiere a un objeto de nueva creación que hereda de prototipo de su constructor:
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
+1. Más completo que nunca. –
¡Gracias @Tim! – CMS