【问题标题】:JavaScript equivalent of Python's __setitem__JavaScript 等价于 Python 的 __setitem__
【发布时间】:2010-12-15 06:53:05
【问题描述】:
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__ 行为?所有棘手的解决方法都会有所帮助。

【问题讨论】:

    标签: javascript python syntactic-sugar


    【解决方案1】:

    是否可以在 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);
    

    但是您必须为每个要使用的命名属性提前声明一个 setter。而且它不能跨浏览器工作。

    【讨论】:

      【解决方案2】:

      不,但有计划支持 JavaScript 2 中的类似功能。Mozilla bug 312116 上建议了以下对象文字语法,似乎它可能是对象文字的方式:

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

      我假设 set 也会受到支持(如 set * (property, value) {...})。

      【讨论】:

      • 看起来不错!你能在建议的页面上发布一个链接吗?
      • @NV:这是 bugzilla.mozilla.org 上的一些错误。我通过一些简单的搜索找不到它,因此您可能需要一段时间才能找到它。
      【解决方案3】:

      你可以这样做(因为 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
      

      【讨论】:

      • 是的,我可以。但是 Python 的 setitem 更漂亮。
      • 哦,我看到了讽刺意味。你如何实现 obj.x+=2 或类似的东西?
      【解决方案4】:

      在常用的 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;
      }
      

      现在由make_property 生成的属性支持所需的语法和为其分配的平方值:

      var obj = {
         x: make_property(2)
      };
      
      alert(obj.x()); // 4
      obj.x(3);       // set value
      alert(obj.x()); // 9
      

      【讨论】:

        【解决方案5】:

        我认为您不能在当前版本的 JavaScript 中覆盖 [] 运算符。在当前的 JavaScript 中,对象在很大程度上只是关联数组,因此 [] 运算符只是将键/值对添加到作为对象的数组中。

        您可以编写设置特定值的方法,甚至对数字求平方并将值添加为键/值对,但不能通过重载 [] 运算符来实现。

        JavaScript2 对运算符重载有一些规范,但该规范是 MIA。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-11-18
          • 2017-10-04
          • 1970-01-01
          • 2023-04-11
          • 2010-12-03
          • 1970-01-01
          • 2015-11-26
          • 2023-04-09
          相关资源
          最近更新 更多