我知道如何通过执行以下操作为名称已知的属性创建getter和setter:
// A trivial example:
function MyObject(val){
this.count = 0;
this.value = val;
}
MyObject.prototype = {
get value(){
return this.count < 2 ? "Go away" : this._value;
},
set value(val){
this._value = val + (++this.count);
}
};
var a = new MyObject('foo');
alert(a.value); // --> "Go away"
a.value = 'bar';
alert(a.value); // --> "bar2"
现在,我的问题是,是否有可能定义这些全能的吸气剂和定型器?即,为尚未定义的任何属性名称创建getter和setter .
这个概念可以在PHP中使用 __get()
和 __set()
魔术方法(有关这些的信息,请参见the PHP documentation),所以我真的要问是否有相当于这些的JavaScript?
不用说,我理想地喜欢跨浏览器兼容的解决方案 .
4 回答
2013 and 2015 Update (见以下2011年的原始答案):
这改变了ES2015(又名"ES6")规范:JavaScript现在有proxies . 代理允许您创建对象(外观)其他对象的真实代理 . 这是一个简单的示例,它将任何字符串属性值转换为检索的所有上限:
您未覆盖的操作具有默认行为 . 在上面,我们覆盖的所有内容都是
get
,但是有一个可以挂钩的操作列表 .在
get
处理函数的参数列表中:target
是被代理的对象(在我们的例子中是original
) .name
(当然)是要检索的属性的名称,通常是字符串,但也可以是符号 .如果属性是访问者而不是数据属性,
receiver
是在getter函数中应该用作this
的对象 . 在正常情况下,这是代理或从其继承的东西,但它可以是任何东西,因为陷阱可能由Reflect.get
触发 .这使您可以使用所需的catch-all getter和setter功能创建一个对象:
以上的输出是:
注意当我们尝试检索
foo
时,如果它们尚不存在,我们将如何获取"non-existent"消息,并且当我们创建它时再次检索"non-existent"消息,但之后不会 .Answer from 2011 (参见上面的2013年和2015年更新):
不,JavaScript没有't have a catch-all property feature. The accessor syntax you'重新使用在规范的Section 11.1.5中,并且不提供任何通配符或类似的东西 .
当然,您可以实现一个函数来执行此操作,但是我想要使用
f = obj.prop("foo");
而不是f = obj.foo;
和obj.prop("foo", value);
而不是obj.foo = value;
(这是函数处理未知属性所必需的) .FWIW,getter函数(我没有使用setter逻辑)看起来像这样:
但同样,我无法想象你真的想要这样做,因为它改变了你如何使用这个对象 .
在现代Javascript(FF4,IE9,Chrome 5,Safari 5.1,Opera 11.60)中,有
Object.defineProperty
. This example on the MDN很好地解释了defineProperty
如何工作,并使动态getter和setter成为可能 .从技术上讲,这不适用于您正在寻找的任何动态查询,但是如果您的有效getter和setter是由例如对JSON-RPC服务器的AJAX调用定义的,那么您可以在以下方式:
以下可能是解决此问题的原始方法:
为了使用它,属性应该作为字符串传递 . 所以这是一个如何工作的例子:
Edit: 基于我提出的改进的,更加面向对象的方法如下:
你可以看到它工作here .
这对我有用