Javascript 动态getter和setter-一种可能性

Javascript 动态getter和setter-一种可能性,javascript,metaprogramming,undefined,getter-setter,Javascript,Metaprogramming,Undefined,Getter Setter,我正在努力解决一个最近浮现在我脑海中的问题。 假设我们希望并且知道如何在javascript中使用动态getter和setter,更像php中的动态getter和setter(uuu-get,uu-set)。但是由于javascript没有一个catch-all属性,我们唯一能做的就是提供一个可能的键列表,并迭代在这些键上添加getter和setter,希望没有其他键会出现 但问题到目前为止还没有得到解决。因此,我想到的下一个方法是对try和catch使用一个讨厌的黑客攻击,因此任何时候对象中的

我正在努力解决一个最近浮现在我脑海中的问题。 假设我们希望并且知道如何在javascript中使用动态getter和setter,更像php中的动态getter和setter(uuu-get,uu-set)。但是由于javascript没有一个catch-all属性,我们唯一能做的就是提供一个可能的键列表,并迭代在这些键上添加getter和setter,希望没有其他键会出现

但问题到目前为止还没有得到解决。因此,我想到的下一个方法是对
try
catch
使用一个讨厌的黑客攻击,因此任何时候对象中的名称都将被取消定义,以使用
catch
作为获取工具(至少),然后恢复代码,这是一件很难而且可能是毫无意义的事情。但是我的第二个问题就从这里来了,在这样的用法中:

console.log(g.someundefinedproperty); 
结果将是调用
console.log
,显示
未定义的
,不会抛出任何异常。
然后我想到了:如果我使用原始的
窗口呢。未定义的
getter和setter,毕竟每次我把一个单词或某事拼错了,它都必须被调用

所以我试过了

Object.defineProperty(window, 'undefined', {
    get : function ()
    {
         // functional code, including getting the caller and figuring out
         // where we are, and what we have to do... easy :D

         console.log('works');
    },
    set : function ()
    {
         // some couple more fine hacks here
         console.log('this too');
    }
});
但不幸的是,窗口的
undefined
属性是
可配置的:false
。 除了
未定义
和内部
窗口
属性外,其他尝试的黑客还克隆了
窗口
对象。在新对象上定义新的
undefined
(请注意讽刺),然后
window=mybetterwindow

由于这没有引起任何问题,我的希望很高,但系统再次让我失望,因为
窗口
无法被设计覆盖。 我猜它有自己的getter,它会根据
窗口中的原型重新关联。prototype
或者更好的
窗口。prototype
(注意大写)

作为本次实验的最后一步,我在这个原型hitted run上重新定义了
undefined
。没有结果,什么都没有改变。。。我尝试创建一个
新窗口()
,但是
窗口
不是构造函数,失败

由于我已经没有了主意,我发现自己在这里写这篇请求帮助的文章。 如果您有任何想法如何解决动态getter和setter问题(
生命、宇宙和其他一切存在的问题
),而不以任何方式修改。。。我使用对象的方式(作为奖励,它不需要打破时空结构中的
漏洞)或语法,我恳请你说话或永远保持沉默:)

但不幸的是,window的未定义属性是
可配置的:false

这是事实,只是因为。以前,它是可覆盖的

如果我使用原始的
窗口会怎么样?未定义的
getter和setter,毕竟每次我搞错一个单词或什么的时候都必须调用它

不,那是行不通的。与全局变量“未定义”之间存在差异。每次遇到未定义的值时(例如在
typeof(void 0)
中),仅当您显式使用该变量时(例如在
g.someprop==undefined
中),才会对该变量求值

有没有办法解决动态的getter和setter问题

只有一个解决方案:。不幸的是,这只是一份和谐草案,目前只是一份

另请参见或实现轮询解决方案的方法(通过
setInterval
检查更改)


对于干净的解决方案,您当前必须使用显式getter函数,您可以传递属性名称(
g.get(“someundefinedproperty”)
)。

您试图完成的(任何未定义属性的全局getter)超出了跨浏览器JavaScript的范围

最接近的功能是使用
\uuuu defineGetter\uuu
向所有对象添加特定属性:

var o = Object.prototype;
o.__defineGetter__("testo", function() { return "yo in testo"; });
alert({}.testo);
alert((new Date()).testo);

如果可以提前预测可能未定义的属性的名称,这可能会很有用。即使如此,为一个可能未定义的属性向所有对象添加一个访问器仍然是一种非常粗糙和糟糕的形式

更好的选择是在可能访问未定义的属性时重构代码:

function getter(o, n) {
 return typeof o[n] == 'undefined' ? 'some default value' : o[n];
}
var obj = { hello: 'world' };
alert(getter(obj, 'hello'));
alert(getter(obj, 'an_undefined_property'));
更好的选择是使用mixin设置您需要访问的任何默认属性,例如通过


你有没有想要解决的现实问题?我认为重新定义未定义的
确实有可能打破时空结构的一个漏洞。也许这就是为什么在ES5中被禁止的原因。这是一个有趣的问题,但我预计大多数答案和评论都会告诉您,catch-all访问器是不需要的,而且是有害的。见鬼,你甚至以PHP为例当然,如果我不这样做的话,在这里没有任何意义。这是我所研究的框架必须遵循的设计。实现您想要的唯一方法是使用ECMAScript 6代理,它们在现代引擎上可用(IIRC,它们在FF4+和Chrome 19+上可用)。另见:@helly0d是的,上帝知道你试过了:D。我对这个问题也很感兴趣。
var defaults = {
 required: 'this property is required'
};
var my_object = {
 something_else: 'this is something else'
};
var o = jQuery.extend({}, defaults, my_object);

// o.required === 'this property is required'
// o.something_else === 'this is something else'