Кросс-браузер Getter и Setter

Это работает в современных браузерах Chrome/Firefox/Opera, но не работает в IE8. Не пробовал в IE9. Как я могу сделать этот кросс-браузер совместимым, включая IE7 +? (здесь скрипка.)

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

// foo.test should be 'Works'

Я видел некоторое использование с __defineGetter__, но это заставило ошибку "непризнанного метода" в IE8.

Ответ 1

Я не верю, что ты можешь.

В IE8 и ниже доступ к свойствам является простым доступом к объектам. Нет способа запуска кода функции без явного вызова функции.

Я думаю, что в IE8 вы можете использовать элементы DOM, но я не думаю, что он работает для обычных собственных объектов.

Ответ 2

Вот обходной путь для 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);

    }
}

Ответ 3

Существует метод definePropery, который по существу позволит вам создавать методы доступа (getters/seters) на объектах без необходимости вызова вызова функции, такого как setProp()/getProp().

Синтаксис немного странный, но я смог заставить его работать в Firefox, Chrome, Safari и IE9.

Скажем, у меня есть 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 здесь.

Ответ 4

Вы не можете, синтаксис не поддерживается в браузерах, которые его не реализовали. Это будет довольно долго, прежде чем вы сможете использовать этот синтаксис без проблем CBC. Будьте благодарны IE6 в значительной степени мертв в Северной Америке.