跨浏览器的 Getter 和 Setter

发布于 2025-01-02 10:40:29 字数 317 浏览 0 评论 0原文

这在现代 Chrome/Firefox/Opera 中有效,但在 IE8 中失败。 IE9没试过。我怎样才能使这个跨浏览器兼容,包括IE7+? (在这里小提琴。)

var foo = { 
    get test(){ return 'Works'; } 
};

// foo.test should be 'Works'

我已经看到了 __defineGetter__ 的一些用法,但这引发了“无法识别的方法” ' IE8 中的错误。

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.)

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

注定孤独终老 2025-01-09 10:40:29

这是 IE6/7/8 的解决方法。我进行了测试,效果非常好!

更新:链接已损坏,您可以在此处查看我的测试代码:

    // 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);

    }
}

Here is the workaround for IE6/7/8. I performed the test and it works very well!

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);

    }
}
后知后觉 2025-01-09 10:40:29

我不相信你可以。

在 IE8 及更低版本中,属性访问仅仅是属性访问。如果不显式调用函数,则无法运行函数代码。

我认为在 IE8 中你也许可以使用 DOM 元素,但我不相信它适用于常规的本机对象。

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.

I think in IE8 you may be able to with DOM elements, but I don't believe it works for regular native objects.

热鲨 2025-01-09 10:40:29

有一个“definePropery”方法,本质上允许您在对象上创建访问器方法(getter/setter),而无需调用像 setProp() / getProp() 这样的函数调用。

语法有点奇怪,但我已经能够让它在 Firefox、Chrome、Safari 和 IE9 上运行。

假设我有一个名为“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'

有关 Mozilla 网站的更多信息此处

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().

The syntax is a little weird but I've been able to get this to work on Firefox, Chrome, Safari and IE9.

Say I have JavaScript Object called "Person".

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.

傲性难收 2025-01-09 10:40:29

不能,未实现该语法的浏览器不支持该语法。您需要相当长的一段时间才能使用该语法而不会出现 CBC 问题。值得庆幸的是,IE6 在北美几乎已经消亡了。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文