2012-05-22 12 views
12

È problematico fare riferimento a un oggetto letterale all'interno di una funzione che è parte di quello molto letterale? Sembra funzionare bene, ma voglio essere sicuro che non ci siano altre implicazioni.Javascript: oggetto Riferimento letterale nella funzione della propria chiave anziché 'this'

Ecco un esempio di cosa sto parlando:

invece di:

var obj = { 
    key1: "it", 
    key2: function(){return this.key1 + " works!"} 
}; 
alert(obj.key2()); 

utilizzando:

var obj = { 
    key1: "it", 
    key2: function(){return obj.key1 + " works!"} 
}; 
alert(obj.key2()); 

risposta

16

Entrambe possono essere problematiche.

var obj = { 
    key1: "it", 
    key2: function(){ return this.key1 + " works!" } 
}; 
var func = obj.key2; 
alert(func()); // error 

Quando func non è chiamato come metodo di obj, this può fare riferimento a qualcosa d'altro (qui: l'oggetto globale "window").

var obj = { 
    key1: "it", 
    key2: function(){ return obj.key1 + " works!" } 
}; 
var newref = obj; 
obj = { key1: "something else"; }; 
alert(newref.key2()); // "something else works" 

Qui si accedere all'oggetto da un altro riferimento, sebbene il obj nella funzione può ora puntare a qualche altro oggetto.

Quindi dovrai scegliere quale caso è più probabile. Se si vuole veramente per renderlo sicuro, è possibile utilizzare una chiusura in cui obj è l'ambito e non possono essere modificati:

var obj = (function(){ 
    var local = { 
     key1: "it", 
     key2: function(){ return local.key1 + " works always!" } 
    }; 
    return local; 
})(); 

o bind() la funzione all'oggetto:

var obj = { 
    key1: "it", 
    key2: function(){ return this.key1 + " works always!" } 
} 
obj.key2 = obj.key2.bind(obj); 
0

Non credo che ci siano implicazioni di fuori della parte superiore della mia testa Assicurati di non farlo accidentalmente in qualsiasi momento:

var obj = { 
    key1: "it", 
    key2: key1 + " works!" 
} 

Come quello causerà un errore. Oltre a questo, dovresti essere bravo!

1

Ci sarà una differenza nel binding con scope variabile. Se si modificano obj tardi, si modificare il valore di ritorno di key2:

var newobj = obj; 
obj = { key1: "new" }; 
alert(newobj.key2()); 

Ora avvisi "! Nuovi lavori", perché anche se si sta chiamando key2() sull'oggetto originale (che è ora newobj), il il riferimento a obj.key1 ora si associa al valore della nuova istanza obj. L'utilizzo di this impedisce che ciò accada.

Demo: http://jsfiddle.net/m6CU3/

1

Se non si utilizza prototipo oggetto, è CZN andare così. poiché tutte le istanze dell'oggetto restituiranno il valore dell'istanza obj ...

1

Uno o entrambe queste tecniche possono essere applicate a seconda della situazione.

Il valore di this all'interno di una funzione dipende da come è stata richiamata la funzione.Se si chiama una funzione come proprietà di un oggetto come questo:

obj.key2(); 
//or 
obj["key2"](); 

Poi this sarà quell'oggetto. Se l'oggetto è stato creato tramite un oggetto letterale o altri mezzi non è rilevante.

Ma è possibile utilizzare .call() o .apply() per chiamare una funzione e impostare esplicitamente this su un altro oggetto.

Considera anche:

var obj = { 
    key1: "it", 
    key2: function(){return this.key1 + " works!"} 
}; 
alert(obj.key2()); // alerts "it works!" 

var func = obj.key2; 
alert(func())​;  // alerts "undefined works!" 

Sto installando func per fare riferimento alla stessa funzione di obj.key2, ma definendola come func() fa non impostato this a obj.

Per ulteriori informazioni dare un'occhiata a what MDN has to say about this.

Problemi correlati