JavaScript相当于Python的__setitem__

NVI*_*NVI 8 javascript python syntactic-sugar

var obj = {}
obj.__setitem__ = function(key, value){
  this[key] = value * value
}
obj.x = 2  // 4
obj.y = 3  // 9
Run Code Online (Sandbox Code Playgroud)

JavaScript没有__setitem__,这个例子显然不起作用.

在python __setitem__中的工作方式如下:

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
Run Code Online (Sandbox Code Playgroud)

是否可以在JavaScript中实现__setitem__行为?所有棘手的解决方法都会有所帮助.

bob*_*nce 10

是否可以在JavaScript中实现__setitem__行为?

不.在JavaScript中没有任何属性的getter/setter.

在Firefox中,您可以使用JavaScript 1.5 +的getter和setter来定义xy赋值的元素,例如:

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

但是你必须为你想要提前使用的每个命名属性声明一个setter.它不会跨浏览器工作.


Eli*_*rey 7

不,但是有计划在JavaScript 2中支持类似的功能.在Mozilla bug 312116上已经提出了以下对象文字语法,似乎它可能是如何为对象文字做的:

({
  get * (property) {
    // handle property gets here
  }
})
Run Code Online (Sandbox Code Playgroud)

我假设set也会得到支持(as set * (property, value) {...}).


man*_*nji 5

你可以这样做(因为javascript中的对象也是关联数组):

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
Run Code Online (Sandbox Code Playgroud)


sth*_*sth 5

通常实现的Javascript版本中没有真正的setter和getter,所以如果你想模拟效果,你必须使用一些不同的语法.对于属性obj.x,使用obj.x()访问属性的值并obj.x(123)设置值似乎是一个相当方便的语法.

它可以像这样实现:

// 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;
}
Run Code Online (Sandbox Code Playgroud)

现在生成的属性make_property支持所需的语法和方形值:

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

alert(obj.x()); // 4
obj.x(3);       // set value
alert(obj.x()); // 9
Run Code Online (Sandbox Code Playgroud)