我正在努力解决最近出现的问题。 假设我们想要并且知道如何在javascript中使用动态getter和setter,更像是php中的那些(__ get,__ set)。但是由于javascript没有全能属性,我们唯一能做的就是提供一个可能的键列表,并迭代添加getter和setter,并且希望别人都不会来。
但问题到目前为止尚未解决。因此,我想到的下一个方法是使用try
和catch
的讨厌的黑客攻击,因此任何时候在对象中未定义名称以使用catch
作为getter(至少)然后恢复代码,努力,也许毫无意义的事情要做。但是从这里出现了我的第二个问题,在这样的用途中:
console.log(g.someundefinedproperty);
结果是调用console.log
显示undefined
,没有任何异常被抛出。
然后它来找我:如果我会使用原始的window.undefined
吸气剂和定位器,毕竟每次我搞砸并拼错一个单词或什么时都必须调用它。
所以我试过
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
属性为configurable : false
。
尝试的其他黑客正在克隆除window
和内部undefined
属性之外的window
对象。在新对象上定义新的undefined
(请注意具有讽刺意味)然后window = mybetterwindow
;
由于这没有任何问题,我的希望很高,但是系统失败了,因为window
无法被设计覆盖。
我猜测它有它自己的吸气剂,它根据window.prototype
中的原型或更好的Window.prototype
(注意大写)来重新定位。(/ p>
作为我在这个实验中的最后一步,我在这个原型hitted run上重新定义了undefined
。无济于事,没有任何改变......我尝试创建new Window()
,但Window
不是构造函数,失败!
由于我已经没有想法,我发现自己在这里写这个求助的恳求。
如果您有任何想法如何解决动态getter和setter问题,(the existencial problem of life, universe and everything else
),以一种不以任何方式修改的方式...我使用对象的方式(并且作为奖励它不need to break
hole
中的fabric of time and space
或语法,我恳请您说话或永远保持沉默:)。
答案 0 :(得分:5)
但不幸的是,窗口的未定义属性是
configurable: false
仅在EcmaScript 5.1之后才是这样。以前,它是可以覆盖的。
如果我会使用原始的
window.undefined
getter和setter,那么每当我搞砸并拼错一个单词或什么的时候必须调用它。
不,它不会奏效。 undefined value和全局变量“undefined”之间存在差异。每次遇到未定义值时(例如在typeof (void 0)
中),只有在您明确使用<(1 {1}})时才会评估变量。
如何解决动态getter和setter问题?
只有一个解决方案:Proxies
。不幸的是,它只是一个和谐的草案,目前只有supported in Firefox' Javascript 1.8.5。
另请参阅实施轮询解决方案的Is there an equivalent of the __noSuchMethod__ feature for properties, or a way to implement it in JS?,Detect when a new property is added to a Javascript object?或How to detect when a property is added to a JavaScript object?(通过g.someprop === undefined
检查更改)。
对于干净的解决方案,您当前必须使用显式的getter函数,该函数会传递属性名称(setInterval
)。
答案 1 :(得分:2)
您尝试完成的任务(任何未定义属性的全局getter)超出了跨浏览器JavaScript的范围。
最接近的功能是使用__defineGetter__
将特定属性添加到所有对象:
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设置您需要访问的任何默认属性,例如通过jQuery.extend
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'