javascript - para - estrategia de crowdfunding
Javascript: ¿por qué “esto” dentro de la función privada se refiere al ámbito global? (4)
Debido a que la función f() no se llama sin ninguna referencia de objeto. Tratar,
f.apply(this);
Considere el siguiente código:
function A() {}
A.prototype.go = function() {
console.log(this); //A { go=function()}
var f = function() {
console.log(this); //Window
};
f();
}
var a = new A();
a.go();
¿Por qué "esta" función interna "f" se refiere al ámbito global? ¿Por qué no es el alcance de la función ''A''?
El alcance de todas las funciones es window .
Para evitar eso, puedes hacer esto:
function A() {}
A.prototype.go = function() {
var self = this;
console.log(self); //A { go=function()}
var f = function() {
console.log(self); //A { go=function()}
};
f();
}
JavaScript tiene un concepto diferente de a qué se refiere el nombre especial al que hace la mayoría de los otros lenguajes de programación. Hay exactamente cinco formas diferentes en que el valor de this puede vincularse en el idioma.
El alcance global
this;
Cuando se usa this en el ámbito global, simplemente se referirá al objeto global .
Llamando a una función
foo();
Aquí, this volverá a referirse al objeto global .
ES5 Nota: En modo estricto, el caso global ya no existe.
thistendrá en su lugar el valor deundefineden ese caso.
Llamando a un método
test.foo();
En este ejemplo, this se referirá a la test .
Llamando a un constructor
new foo();
Una llamada de función que está precedida por la new palabra clave actúa como un constructor. Dentro de la función, this se referirá a un Object recién creado .
Configuración explícita de this
function foo(a, b, c) {}
var bar = {};
foo.apply(bar, [1, 2, 3]); // array will expand to the below
foo.call(bar, 1, 2, 3); // results in a = 1, b = 2, c = 3
Cuando se utiliza la call o se apply métodos de Function.prototype , el valor de this dentro de la función llamada se establece explícitamente en el primer argumento de la llamada de función correspondiente.
Como resultado, en el ejemplo anterior, el caso del método no se aplica, y this dentro de foo se establecerá en bar .
Nota:
thisno se puede usar para referirse al objeto dentro de un literal deObject. Así quevar obj = {me: this}no dará como resultado quemerefiera aobj, ya quethissolo queda vinculado por uno de los cinco casos enumerados.
Errores comunes
Si bien la mayoría de estos casos tienen sentido, el primero debe considerarse otro diseño erróneo del lenguaje porque nunca tiene ningún uso práctico.
Foo.method = function() {
function test() {
// this is set to the global object
}
test();
}
Un error común es que this test interna se refiere a Foo ; mientras que de hecho, no lo hace .
Para poder acceder a Foo desde dentro de la test , es necesario crear una variable local dentro del method que se refiera a Foo .
Foo.method = function() {
var that = this;
function test() {
// Use that instead of this here
}
test();
}
that es solo un nombre de variable normal, pero se usa comúnmente para la referencia a this externo. En combinación con los cierres, también se puede utilizar para pasar this valores.
Asignando Métodos
Otra cosa que no funciona en JavaScript es la función de alias, que es asignar un método a una variable.
var test = someObject.methodTest;
test();
Debido al primer caso, la test ahora actúa como una llamada de función simple; por lo tanto, this interior ya no se referirá a someObject .
Si bien la vinculación tardía de this puede parecer una mala idea al principio, de hecho, es lo que hace que la herencia prototípica funcione.
function Foo() {}
Foo.prototype.method = function() {};
function Bar() {}
Bar.prototype = Foo.prototype;
new Bar().method();
Cuando se llama al method en una instancia de Bar , ahora se referirá a esa instancia.
Descargo de responsabilidad: descarado robado de mis propios recursos en http://bonsaiden.github.com/JavaScript-Garden/#function.this
La razón por la cual está invocando f como una function y no como un method . Cuando se invoca como una función, se configura como window durante la ejecución del objetivo.
// Method invocation. Invoking a member (go) of an object (a). Hence
// inside "go" this === a
a.go();
// Function invocation. Invoking a function directly and not as a member
// of an object. Hence inside "f" this === window
f();
// Function invocation.
var example = a.go;
example();