我正在努力解决最近出现在我脑海中的一个问题。假设我们想要并且知道如何在javascript中使用动态的getter和setter,就像在php (__get,__set)中那样。但是由于javascript没有一个通用的属性,我们唯一能做的就是提供一个可能键的列表,然后迭代,只在这些键上添加getter和setter,并希望以后不会再有其他的。
但到目前为止,这个问题还没有得到解决。因此,我想到的下一种方法是对try
和catch
使用讨厌的技巧,所以任何时候在对象中没有定义名称时,使用catch
作为getter (至少),然后恢复代码,这很难,而且可能是毫无意义的事情。但是从这里我的第二个问题来了,在这样的使用中:
console.log(g.someundefinedproperty);
结果将是对console.log
的调用,显示undefined
,没有抛出任何异常。然后我想到:如果我使用原来的window.undefined
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');
}
});
但不幸的是,window的undefined
属性是configurable : false
。除了undefined
和内部window
属性之外,其他黑客还尝试克隆window
对象。并在新对象上定义新的undefined
(请注意其中的讽刺意味),然后是window = mybetterwindow
;
由于这没有引起任何问题,我的希望很高,但系统再次让我失望,因为window
不能被覆盖,这是设计的。我猜它有自己的getter,并且会根据window.prototype
甚至更好的Window.prototype
(注意大写字母)中的原型重新实例化自己。
作为我在这个实验中的最后一步,我在这个原型上重新定义了undefined
。无济于事,什么也没改变...我尝试创建一个new Window()
,但是Window
不是一个构造函数,失败!
由于我已经没有想法了,我发现自己在这里写了这篇恳求帮助的文章。如果您有任何想法来解决动态的getters和setters问题,(the existencial problem of life, universe and everything else
),以一种不会以任何方式修改...我使用对象的方式(作为奖励,它不会在fabric of time and space
中使用hole
)或语法,我恳求您发言,否则永远保持沉默:)。
发布于 2012-12-12 22:32:06
,但不幸的是,window的未定义属性是
configurable: false
只有在EcmaScript 5.1之后才会出现这种情况。以前,它是可重写的。
如果我使用原始的window.undefined
getter和setter怎么办,毕竟每次我搞砸了,拼错一个单词或什么东西时,都必须调用它。
不,它不会起作用的。 value和全局变量"undefined“之间存在差异。不会在每次遇到未定义的值时计算变量(例如,在typeof (void 0)
中),只有在显式使用它时(例如,在g.someprop === undefined
中)。
有什么办法解决动态的getter和setters问题吗?
只有一个解决方案: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? (通过setInterval
检查更改)。
对于干净的解决方案,您目前必须使用显式的getter函数,您可以传递属性名称(g.get("someundefinedproperty")
)。
发布于 2012-12-12 22:33:05
您要完成的任务(任何未定义属性的全局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'
https://stackoverflow.com/questions/13849533
复制相似问题