javascript 跨浏览器的 Getter 和 Setter
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9106936/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cross-browser Getter and Setter
提问by ryanve
This works in modern Chrome/Firefox/Opera but fails in IE8. Haven't tried it in IE9. How can I make this cross-browser compatible, including IE7+? (Fiddle here.)
这在现代 Chrome/Firefox/Opera 中有效,但在 IE8 中失败。没有在IE9中尝试过。如何使此跨浏览器兼容,包括 IE7+?(在这里摆弄。)
var foo = {
get test(){ return 'Works'; }
};
// foo.test should be 'Works'
I've seen some usage with __defineGetter__
but that threw an 'unrecognized method' error in IE8.
我已经看到了一些用法,__defineGetter__
但这在 IE8 中引发了“无法识别的方法”错误。
采纳答案by ryanve
I don't believe you can.
我不相信你能。
In IE8
and lower, property access is mere property access. There's no way to run function code without explicitly invoking the function.
在IE8
及更低版本中,财产访问只是财产访问。如果不显式调用函数,就无法运行函数代码。
I think in IE8 you may be able to with DOM elements, but I don't believe it works for regular native objects.
我认为在 IE8 中您可以使用 DOM 元素,但我认为它不适用于常规本机对象。
回答by Mason Zhang
Here is the workaroundfor IE6/7/8. I performed the test and it works very well!
这是IE6/7/8的解决方法。我进行了测试,效果很好!
Update: The link is broken, you can see the code of from my testing here:
更新:链接已损坏,您可以在此处查看我的测试代码:
// Super amazing, cross browser property function, based on http://thewikies.com/
function addProperty(obj, name, onGet, onSet) {
// wrapper functions
var
oldValue = obj[name],
getFn = function () {
return onGet.apply(obj, [oldValue]);
},
setFn = function (newValue) {
return oldValue = onSet.apply(obj, [newValue]);
};
// Modern browsers, IE9+, and IE8 (must be a DOM object),
if (Object.defineProperty) {
Object.defineProperty(obj, name, {
get: getFn,
set: setFn
});
// Older Mozilla
} else if (obj.__defineGetter__) {
obj.__defineGetter__(name, getFn);
obj.__defineSetter__(name, setFn);
// IE6-7
// must be a real DOM object (to have attachEvent) and must be attached to document (for onpropertychange to fire)
} else {
var onPropertyChange = function (e) {
if (event.propertyName == name) {
// temporarily remove the event so it doesn't fire again and create a loop
obj.detachEvent("onpropertychange", onPropertyChange);
// get the changed value, run it through the set function
var newValue = setFn(obj[name]);
// restore the get function
obj[name] = getFn;
obj[name].toString = getFn;
// restore the event
obj.attachEvent("onpropertychange", onPropertyChange);
}
};
obj[name] = getFn;
obj[name].toString = getFn;
obj.attachEvent("onpropertychange", onPropertyChange);
}
}
回答by braitsch
There is a "definePropery" method that will essentially allow you to create accessor methods (getters/setters) on Objects without the need to invoke a function call like setProp() / getProp().
有一个“definePropery”方法,它基本上允许您在对象上创建访问器方法(getter/setter),而无需调用像 setProp()/getProp() 这样的函数调用。
The syntax is a little weird but I've been able to get this to work on Firefox, Chrome, Safari and IE9.
语法有点奇怪,但我已经能够让它在 Firefox、Chrome、Safari 和 IE9 上运行。
Say I have JavaScript Object called "Person".
假设我有一个名为“Person”的 JavaScript 对象。
function Person()
{
// set a default value //
this.__name = 'John';
// add getter & setter methods //
Object.defineProperty(this, "name", {
get: function() {
// additional getter logic
return this.__name;
},
set: function(val) {
this.__name = val;
// additional setter logic
}
});
}
var p = new Person();
console.log(p.name); // 'John'
p.name = 'Stephen';
console.log(p.name); // 'Stephen'
More info on Mozilla's site here.
有关 Mozilla 网站的更多信息,请点击此处。
回答by Matt Lo
You cannot, the syntax is not supported in browsers that did not implement it. Its going to be quite a while before you'll be able to use that syntax without having CBC problems. Be grateful IE6 is pretty much dead in North America.
你不能,没有实现它的浏览器不支持该语法。您还需要很长时间才能使用该语法而不会出现 CBC 问题。感谢 IE6 在北美几乎已经死了。