Object.defineProperty в ES5? - PullRequest
       59

Object.defineProperty в ES5?

8 голосов
/ 30 сентября 2010

Я вижу сообщения о «новом» Object.create, который делает перечисление настраиваемым. Однако он опирается на метод Object.defineProperty. Я не могу найти кросс-браузерную реализацию для этого метода.

Мы застряли в записи для старого Object.create? Я не могу писать вещи, которые не будут работать в IE6 / 7.

Ответы [ 3 ]

14 голосов
/ 02 октября 2010

Есть несколько вещей, которые вы не можете эмулировать из метода 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 без аргумента properties , вы можете, однако я бы порекомендовал вам обнаружить вещи, которые нельзя эмулировать.

Ниже будет более безопасная версия Крокфорда 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;
    };
  })();
}

В любом случае, используйте ее осторожно.

4 голосов
/ 03 апреля 2011

Если вы хотите хорошую реализацию defineProperty (), взгляните на https://github.com/kriskowal/es5-shim

К сожалению, вы не можете сделать перечисление настраиваемым в среде ES3. Эта прокладка позволит вам вызывать API в любой среде, но свойства по-прежнему будут перечисляемыми в ES3.

2 голосов
/ 30 сентября 2010

за что стоит,

Object.defineProperty работает в ie8 и FF4.

Это означает, что стоит включить функцию sniff и реализовать ее там, где это полезно, поскольку вы надеетесь, что в ближайшие несколько лет произойдет обновление с 6/7 до 8/9.

Еще один момент, о котором следует опасаться, это то, что свойство dontEnum содержит ошибку в JScript

Вам придется обойти способ использования свойства dontEnum в IE.

[Изменить]:

Вот документация для Internet Explorer и ссылка на спецификацию ES5 (стр. 122, 15.2.3.6)

...