los - javascript getelementbyid value
¿Por qué es necesario JavaScript bind()? (4)
El problema en el ejemplo 1 es ''esto'' que se refiere al nombre global en lugar del objeto myName.
Entiendo el uso de bind () para establecer el valor de esto en un objeto específico, por lo que resuelve el problema en el ejemplo 1, pero ¿por qué ocurre este problema en primer lugar? ¿Es solo la forma en que se creó Javascript?
También me pregunto por qué el ejemplo 3 resuelve el problema y la diferencia entre los ejemplos 2 y 3.
this.name = "John"
var myName = {
name: "Tom",
getName: function() {
return this.name
}
}
var storeMyName = myName.getName; // example 1
var storeMyName2 = myName.getName.bind(myName); // example 2
var storeMyName3 = myName.getName(); // example 3
console.log("example 1: " + storeMyName()); // doesn''t work
console.log("example 2: " + storeMyName2()); // works
console.log("example 3: " + storeMyName3); // works
¿Por qué es necesario JavaScript bind ()?
El valor de
this
está determinado por
cómo
se
llama
una función.
Si
eres tú
quien llama a la función, generalmente no es necesario usar
.bind
, ya que tienes control sobre cómo llamar a la función y, por lo tanto, es
this
valor.
Sin embargo, a menudo no eres tú quien llama a la función. Las funciones se pasan a otras funciones como devoluciones de llamada y controladores de eventos. Son llamados por otro código y usted no tiene control sobre cómo se llama la función y, por lo tanto, no puede controlar a qué se referirá esto.
Si su función requiere que se establezca en un valor específico y usted no es el que llama a la función, debe
.bind
la función a un valor específico de
this
.
En otras palabras:
.bind
permite establecer el valor de
this
sin llamar a la función
ahora
.
Aquí hay una comparación de las funciones de referencia / llamada:
+-------------------+-------------------+
| | |
| time of | time of |
|function execution | this binding |
| | |
+-------------------+-------------------+-------------------+
| | | |
| function object | future | future |
| f | | |
| | | |
+-------------------+-------------------+-------------------+
| | | |
| function call | now | now |
| f() | | |
| | | |
+-------------------+-------------------+-------------------+
| | | |
| f.call() | now | now |
| f.apply() | | |
| | | |
+-------------------+-------------------+-------------------+
| | | |
| f.bind() | future | now |
| | | |
+-------------------+-------------------+-------------------+
También me pregunto por qué el ejemplo 3 resuelve el problema y la diferencia entre los ejemplos 2 y 3.
Los ejemplos 1/2 y 3 no podrían ser más diferentes.
storeMyName
y
storeMyName2
contienen
funciones
, que se
storeMyName2
en el futuro, mientras que
storeMyName3
contiene el resultado de llamar a
myName.getName()
en ese momento
.
Material de lectura adicional:
- ¿Cómo funciona la palabra clave "this"?
- MDN - esto
- YDKS - esto y prototipos de objetos
- ¿Cómo acceder al contexto correcto ''this'' dentro de una devolución de llamada?
El método
bind()
crea una nueva función que, cuando se llama, tiene esta palabra clave establecida en el valor proporcionado, con una secuencia dada de argumentos que precede a cualquier proporcionada cuando se llama a la nueva función.
Entonces, cuando ejecutas
var storeMyName = myName.getName;
la primera vez, toma el
name
global (this.name = "John")
Cuando utiliza la función
bind()
, comienza a referirse al nombre definido en el cierre actual (myName en este caso) y, por lo tanto, imprime
Tom
Tercera vez, dado que la función se llama de inmediato, su alcance está dentro de su propio objeto local y, por lo tanto, imprime el valor en el cierre
Tom
La vinculación es el mecanismo por el cual puede cambiar el contexto (aquí su contexto predeterminado es global) de ejecución.
Según tu ejemplo:
var storeMyName = myName.getName;
Desde la línea anterior está ejecutando la función
storeMyName
en contexto global, por lo que para esta ejecución
this.name
será la línea superior (es decir, global one / "John").
var storeMyName2 = myName.getName.bind(myName);
Para la línea anterior, está cambiando
explícitamente
el contexto de ejecución para la función
storeMyName2
(al decir que no quiero ejecutar esta función como función global, quiero ejecutar esta función en el contexto del objeto
myName
, por lo que en este caso
this.name
será ser "Tom")
var storeMyName3 = myName.getName(); // example 3
Y para esta línea anterior, solo está ejecutando la función en el contexto del objeto
myName
, lo que es más importante, no está ejecutando
storeMyName3
y es por eso que su contexto no es global.
Una analogía que me gusta, que nunca he visto en ningún lado: Digamos que tienes un objeto foo con una función de
bar
.
Cuando vincula la función de barra a otra variable (o la pasa como un parámetro de función, que es el caso más común con devoluciones de llamada), no vincula / pasa la función con su objeto envolvente sino solo la función "desnuda".
Por lo tanto, con la función "desnuda",
this
significa el objeto global.
Una pequeña demostración
var foo = "global foo"; //foo set on the global object
var a = {foo : "object foo", bar : function(){return this.foo;}};
var bound = a.bar;
console.log(bound());//returns "global foo", not "object foo"
bound
solo apunta a la
function(){return this.foo;}