Object.defineProperty в ES5?
Я вижу сообщения о "новом" Object.create, который делает перечисление настраиваемым. Однако он опирается на метод Object.defineProperty. Я не могу найти кросс-браузерную реализацию для этого метода.
Мы застряли писать для старого Object.create? Я не могу писать вещи, которые не будут работать в IE6/7.
3 ответа
Есть несколько вещей, которые вы не можете эмулировать из ECMAScript 5 Object.create
метод в среде ECMAScript 3
Как вы видели, аргумент свойств создаст вам проблемы, поскольку в реализациях на основе E3 нет способа изменить атрибуты свойства.
Object.defineProperty
Метод, как упоминал @Raynos, работает на IE8, но частично его можно использовать только в элементах DOM.
Также свойства аксессора доставят вам проблемы, они могут быть имитированы широко поддерживаемыми нестандартными методами, такими как __defineGetter__
/ __defineSetter__
но, опять же, вы не можете изменить атрибуты свойства.
Другая проблема в стороне от дескрипторов свойств заключается в том, что Object.create
метод может принять null
в качестве аргумента, чтобы создать объект, который не наследует ни от чего.
Этого нельзя подражать Крокфорду Object.create
шим, потому что когда new
Оператор используется с функцией конструктора, которая имеет prototype
свойство, содержащее null
-или любое другое не-объектное значение-, новый объект будет наследоваться от Object.prototype
в любом случае по умолчанию.
В некоторых реализациях -V8, Spidermonkey, Rhino и т. Д.- они имеют возможность установки __proto__
свойство, которое может быть использовано для установки null
[[Prototype]], но, опять же, это нестандартно и наверняка никогда не будет работать в IE.
Я бы порекомендовал, если вы хотите настроить старые браузеры так, чтобы они не использовали эти функции, поскольку в этих средах невозможно заставить их работать должным образом.
Если вы все еще хотите использовать Object.create
без использования аргумента свойств вы можете, однако я бы порекомендовал вам обнаружить вещи, которые нельзя эмулировать.
Следующее было бы более безопасной версией Крокфорда Object.create
шим:
if (typeof Object.create != 'function') {
(function () {
var F = function () {};
Object.create = function (o) {
if (arguments.length > 1) { throw Error('Second argument not supported');}
if (o === null) { throw Error('Cannot set a null [[Prototype]]');}
if (typeof o != 'object') { throw TypeError('Argument must be an object');}
F.prototype = o;
return new F;
};
})();
}
В любом случае, используйте это осторожно.
Если вы хотите хорошую реализацию defineProperty(), взгляните на https://github.com/kriskowal/es5-shim
К сожалению, вы не можете сделать перечисление настраиваемым в среде ES3. Эта прокладка позволит вам вызывать API в любой среде, но свойства по-прежнему будут перечисляемыми в ES3.
Для чего это стоит,
Object.defineProperty работает в ie8 и FF4.
Это означает, что стоит включить функцию sniff и внедрить ее там, где это полезно, поскольку вы надеетесь, что в ближайшие несколько лет произойдет обновление с 6/7 до 8/9.
Другой момент, о котором следует опасаться, это то, что свойство dontEnum содержит ошибку в JScript.
Вам придется обойти способ использования свойства dontEnum в IE.
[Редактировать]:
Вот документация для Internet Explorer и ссылка на спецификацию ES5 (Страница 122, 15.2.3.6)