¿Puedo usar Y-Combinator para obtener referencia de objeto para este cierre?
-
10-10-2019 - |
Pregunta
funciona este cierre:
var o = {
foo: 5
};
o.handler = function(obj){
return function() {
alert(obj.foo);
};
}(o);
o.handler(); //alert('5')
Es posible definir manejador en línea, tal vez con algo parecido a una operación Y-Combinator?
var o = {
foo: 5,
handler: function(obj){
return function() {
alert(obj.foo);
};
}(o); //pointer to o? -----------------------------
};
por curiosidad académica, no estoy tratando de hacer esto en el código de producción
Solución
No, esto no es posible, porque en el momento de la definición del objeto literal, la o
la variable no está definida, y la referencia this
en el momento de definición no hace referencia o
.
Si ha utilizado una referencia temporal para this
en la función externa y se la pasó en el cierre, que funcionaría, pero no sería capaz de pasar de un objeto a obtener la propiedad de foo
.
var o = {
foo: 5,
handler:function(){
var self = this;
return function() {
alert(self.foo);
};
}
};
var h = o.handler();
h();
Otros consejos
Esto no es posible con un objeto literal por sí mismo , como otros han señalado. Sin embargo, el proceso puede ser envuelto. Tiempo o no "añade nada" es discutible. Esto no es lo mismo que un Y-Combinator (tal vez la mitad de ella?), Ya que no está tratando de dar un "nombre recursivo" (por lo que yo puedo decir Y-combinadores asumen las funciones de primera clase y cierres o una manera de simular tales).
function bindMany (dict, res) {
res = res || {}
for (var k in dict) {
if (dict.hasOwnProperty(k)) {
var v = dict[p]
res[k] = v instanceof Function ? v(res) : v
}
}
return res
}
var o = bindMany({
foo: 5,
handler: function(obj){
return function() {
alert(obj.foo)
}
}
})
No-probadas, pero muestra un enfoque que podría tomarse. Hay problemas con este sutiles y una cadena de prototipo en dict
/ res
, en su caso -. Un ejercicio para el lector
Happy codificación.
Se podía utilizar la palabra clave this
aquí:
var o = {
foo: 5,
handler: function() {
alert(this.foo);
}
};
Esto es mucho más fácil enfoque ... En realidad, su enfoque no es aún posible, como o
no está definida cuando se hace referencia a la misma.