Posso usare y-combinatore per ottenere riferimento oggetto per questa chiusura?
-
10-10-2019 - |
Domanda
questa chiusura funziona:
var o = {
foo: 5
};
o.handler = function(obj){
return function() {
alert(obj.foo);
};
}(o);
o.handler(); //alert('5')
è possibile definire gestore in-line, magari con qualcosa di simile ad un'operazione Y-Combinator?
var o = {
foo: 5,
handler: function(obj){
return function() {
alert(obj.foo);
};
}(o); //pointer to o? -----------------------------
};
per curiosità accademica, non sto cercando di fare questo nel codice di produzione
Soluzione
No, questo non è possibile, perché al momento della definizione del letterale oggetto, il o
variabile non è definita, e il riferimento this
al momento della definizione non o
riferimento.
Se è stato utilizzato un riferimento temporaneo per this
nella funzione esterna e superato in chiusura, che avrebbe funzionato, ma non sarebbe in grado di passare in un oggetto per ottenere la proprietà foo
fuori.
var o = {
foo: 5,
handler:function(){
var self = this;
return function() {
alert(self.foo);
};
}
};
var h = o.handler();
h();
Altri suggerimenti
Questo non è possibile con un oggetto letterale da solo , come altri hanno segnalato. Tuttavia, il processo può essere avvolto. Che sia o meno "aggiunge nulla" è discutibile. Questa non è la stessa cosa di un Y-Combinator (forse la metà di esso?), Perché non sta cercando di dare un "nome ricorsivo" (per quanto posso dire Y-combinatori assumere funzioni di prima classe e le chiusure o una modo per simulare tale).
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)
}
}
})
Non-testato, ma mostra un approccio che potrebbero essere prese. Ci sono problemi sottili con questo e una catena di prototipi su dict
/ res
, se del caso -. Un esercizio per il lettore
Felice di codifica.
Si potrebbe utilizzare la parola chiave this
qui:
var o = {
foo: 5,
handler: function() {
alert(this.foo);
}
};
Questo è un approccio molto più semplice ... In realtà, il tuo approccio non è nemmeno possibile, come o
non è definito quando si fa riferimento ad esso.