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)

Другие вопросы по тегам