JavaScript中相当于Python的__setitem__是什么

9 投票
5 回答
1319 浏览
提问于 2025-04-15 15:53
var obj = {}
obj.__setitem__ = function(key, value){
  this[key] = value * value
}
obj.x = 2  // 4
obj.y = 3  // 9

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

在JavaScript中,有没有办法实现__setitem__的功能?任何巧妙的解决方法都很有帮助。

5 个回答

5

在常见的JavaScript版本中,其实并没有真正的“设置器”和“获取器”。所以如果你想要模拟这种效果,就得用一些不同的写法。比如说,对于一个属性 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;
}

现在通过 make_property 生成的属性就支持这种写法,并且会对赋给它们的值进行平方处理:

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

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

在JavaScript中可以实现__setitem__的功能吗?

不可以。JavaScript没有针对任意属性的获取器和设置器。

在Firefox浏览器中,你可以使用JavaScript 1.5及以上版本的获取器和设置器,来定义一些属性,比如xy,让它们在赋值时自动平方,例如:

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

不过,你必须提前为每个想要使用的属性声明一个设置器。而且这种方法在不同的浏览器中可能不兼容。

7

不,这个功能目前还不支持,但有计划在JavaScript 2中加入类似的功能。有人在Mozilla的一个问题页面上提出了以下的对象字面量语法,看起来这可能是将来实现对象字面量的方式:

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

我假设也会支持set功能(像这样 set * (property, value) {...})。

撰写回答