2009-11-10 16 views
7
var obj = {} 
obj.__setitem__ = function(key, value){ 
    this[key] = value * value 
} 
obj.x = 2 // 4 
obj.y = 3 // 9 

JavaScript non ha __setitem__ e questo esempio ovviamente non funziona.equivalente JavaScript di Python __setitem__

in Python __setitem__ funziona come:

class CustomDict(dict): 
    def __setitem__(self, key, value): 
    super(CustomDict, self).__setitem__(key, value * value) 

d = CustomDict() 
d['x'] = 2 # 4 
d['y'] = 3 # 9 

E 'possibile implementare __setitem__ comportamento in JavaScript? Sarebbero utili tutti gli stratagemmi complicati.

risposta

7

No, ma ci sono piani per supportare una funzionalità simile in JavaScript 2. La seguente sintassi letterale oggetto è stato suggerito su Mozilla bug 312116 e sembra che potrebbe essere come sarà fatto per letterali oggetto:

({ 
    get * (property) { 
    // handle property gets here 
    } 
}) 

sto assumendo insieme sarebbe anche essere supportate (come set * (property, value) {...}).

+0

Sembra carino! Potresti postare un link alla pagina lì è stato suggerito? – NVI

+0

@NV: È in qualche bug su bugzilla.mozilla.org. Non sono riuscito a trovarlo con alcune semplici ricerche, quindi potrebbe essere necessario un po 'di tempo per trovarlo. –

+0

@NV: trovato: https://bugzilla.mozilla.org/show_bug.cgi?id=312116 –

10

È possibile implementare il comportamento __setitem__ in JavaScript?

No. Non c'è getter/setter per proprietà arbitrarie in JavaScript.

In Firefox è possibile utilizzare JavaScript 1.5 getter 's + e setter per definire x e y proprietà che piazza i loro valori in missione, ad es .:

var obj= { 
    _x: 0, 
    get x() { return this._x; }, 
    set x(v) { this._x=v*v; } 
}; 
obj.x= 4; 
alert(obj.x); 

ma si dovrà dichiarare un setter per ogni proprietà denominata che si desidera utilizzare in anticipo. E non funzionerà cross-browser.

1

Non penso che sia possibile sovrascrivere l'operatore [] nella versione corrente di Javascript. Nel Javascript corrente, gli oggetti sono in gran parte solo array associativi, quindi l'operatore [] aggiunge solo una coppia chiave/valore all'array che è l'oggetto.

È possibile scrivere metodi che impostano valori specifici o addirittura un quadrato e aggiunge il valore come coppia chiave/valore, ma non sovraccaricando l'operatore [].

Javascript2 ha alcune specifiche per l'overloading dell'operatore, ma quella specifica è MIA.

5

si può fare questo (come oggetti in JavaScript sono anche gli array associativi):

var obj = {}; 
obj._ = function(key, value){ 
    this[key] = value * value; 
} 
obj._('x', 2); // 4 
obj._('y', 3); // 9 

alert(obj.x + "," + obj.y); //--> 4,9 
+1

Sì, posso. Ma __setitem__ di Python è molto più carino. – NVI

+2

ok, l'ho rinominato in '_', potrebbe essere più simile a Python ... – manji

+1

Oh, vedo l'ironia. Come puoi implementare obj.x + = 2 o qualcosa del genere? – NVI

5

Non ci sono veri setter e getter nelle versioni Javascript comunemente implementate, quindi se si desidera emulare l'effetto è necessario utilizzare una sintassi diversa. Per una proprietà obj.x, utilizzando obj.x() per accedere al valore della proprietà e obj.x(123) per impostare il valore sembra una sintassi piuttosto comoda.

può essere implementato in questo modo:

// Basic property class 
function Property(value) { 
    this.setter(value); 
} 

Property.prototype.setter = function(value) { 
    this.value = value * value; 
} 

Property.prototype.getter = function() { 
    return this.value; 
} 

Property.prototype.access = function(value) { 
    if (value !== undefined) 
     this.setter(value); 
    return this.getter(); 
} 


// generator function to add convenient access syntax 
function make_property(value) { 
    var prop = new Property(value); 
    function propaccess(value) { 
     return prop.access(value); 
    } 
    return propaccess; 
} 

Ora proprietà generati dal make_property supportano la sintassi desiderata e valori quadrati sono assegnati:

var obj = { 
    x: make_property(2) 
}; 

alert(obj.x()); // 4 
obj.x(3);  // set value 
alert(obj.x()); // 9