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.
this
tendrá en su lugar el valor deundefined
en 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:
this
no se puede usar para referirse al objeto dentro de un literal deObject
. Así quevar obj = {me: this}
no dará como resultado queme
refiera aobj
, ya quethis
solo 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();