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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 05:37:06  来源:igfitidea点击:

Cross-browser Getter and Setter

javascriptinternet-explorercross-browsergettergetter-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 IE8and 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 在北美几乎已经死了。