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

JavaScript没有__setitem__,这个例子显然不起作用。Python的等价物__setitem__

在蟒蛇__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__行为?所有棘手的解决方法将有所帮助。

回答

7

没有,但有以下对象文字语法已建议对在JavaScript 2支持类似的功能计划Mozilla bug 312116,似乎,这可能是它如何会为对象文本来完成:

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

我假设组也将支持(如set * (property, value) {...})。

+0

看起来不错!你可以发布一个链接到那里建议的页面吗? – NVI 2009-11-11 00:35:37

+0

@NV:它在bugzilla.mozilla.org上有一些bug。我找不到一些简单的搜索,所以它可能需要你一段时间才能找到它。 – 2009-11-11 01:28:05

+0

@NV:找到它:https://bugzilla.mozilla.org/show_bug.cgi?id=312116 – 2009-11-11 01:32:51

10

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

不。没有getter/setter在JavaScript中的任意属性。

在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预先命名的属性。它不会跨浏览器工作。

1

我不认为你可以在当前版本的Javascript中覆盖[]运算符。在当前的Javascript中,对象主要只是关联数组,所以[]运算符只是将一个键/值对添加到作为对象的数组中。

您可以编写方法来设置特定值或甚至将数字平方并将该值添加为键/值对,但不会重载[]运算符。

Javascript2对操作符重载有一些规范,但该规范是MIA。

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 
+1

是的,我可以。但Python的__setitem__更漂亮。 – NVI 2009-11-11 00:09:59

+2

好吧,我把它改名为'_',可能更像python一样...... – manji 2009-11-11 00:17:42

+1

哦,我看到了讽刺。你怎么能实现obj.x + = 2或类似的东西? – NVI 2009-11-11 00:29:59

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

现在,通过make_property生成的属性支持它们被分配期望的语法和平方值:

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

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