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

JavaScript no tiene __setitem__ y obviamente este ejemplo no funciona.JavaScript equivalente a Python's __setitem__

en Python __setitem__ funciona como:

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 

¿Es posible aplicar __setitem__ comportamiento en JavaScript? Todas las soluciones complicadas serían útiles.

Respuesta

7

No, pero hay planes para apoyar una función similar en JavaScript 2. La siguiente sintaxis literal de objeto ha sido sugeridas en Mozilla bug 312116 y parece que podría ser la forma en que se llevará a cabo para los literales de objetos:

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

Asumo set también contaría con el apoyo (como set * (property, value) {...}).

+0

Se ve bien! ¿Podría publicar un enlace a la página que se sugirió? – NVI

+0

@NV: Está en algún error en bugzilla.mozilla.org. No pude encontrarlo con algunas búsquedas simples, así que puede llevarte un tiempo encontrarlo. –

+0

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

10

¿Es posible implementar el comportamiento __setitem__ en JavaScript?

No. No hay getter/setter para propiedades arbitrarias en JavaScript.

En Firefox puede utilizar JavaScript 1.5 captadores y definidores + 's para definir x y y propiedades que Square sus valores en la asignación, por ejemplo .:

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

pero que tendría que declarar un colocador para cada propiedad nombrada que quería usar por adelantado. Y no funcionará en todos los navegadores.

1

No creo que pueda anular el operador [] en la versión actual de Javascript. En Javascript actual, los objetos son, en gran medida, solo matrices asociativas, por lo que el operador [] simplemente agrega un par de clave/valor a la matriz que es el objeto.

Puede escribir métodos que establezcan valores específicos o incluso cuadren un número y agreguen el valor como un par clave/valor, pero no sobrecarguen el operador [].

Javascript2 tiene algunas especificaciones para la sobrecarga del operador, pero esa especificación es MIA.

5

usted puede hacer esto (como objetos en javascript son también matrices asociativas):

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í, puedo. Pero el __setitem__ de Python es mucho más bonito. – NVI

+2

ok, lo renombré a '_', puede ser más parecido a un pitón ... – manji

+1

Oh, veo la ironía. ¿Cómo se puede implementar obj.x + = 2 o algo así? – NVI

5

No existen setters y getters verdaderos en las versiones de Javascript comúnmente implementadas, por lo que si desea emular el efecto, debe usar una sintaxis diferente. Para una propiedad obj.x, usar obj.x() para acceder al valor de la propiedad y obj.x(123) para establecer el valor parece una sintaxis bastante conveniente.

Se puede implementar como esto:

// 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; 
} 

Ahora propiedades generadas por make_property apoyar la sintaxis deseada y los valores cuadrados que se les asigna:

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

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