Какие сценарии модернизатора существуют для новых функций ECMAScript 5? - PullRequest
16 голосов
/ 19 июня 2010

ECMAScript 5 имеет довольно много приятных дополнений. Джон Резиг имеет хороший обзор здесь .Вот хорошая таблица совместимости ECMAScript 5 .

Многие из этих вещей могут быть "подделаны" для браузеров, которые еще не поддерживают эти функции.Знаете ли вы какие-либо сценарии, которые могут сделать это?Мне особенно интересен Object.create.

Например, JSON-скрипт Дугласа Крокфорда проверяет, существуют ли функции JSON перед их созданием.

Если бы было больше похожего на JSON, мы могли бы включить их, когда нам нужно будет использовать новые функции.

Ответы [ 4 ]

40 голосов
/ 19 июня 2010

Крокфорд рекомендует этот вид Object.create шим:

if (typeof Object.create != "function") {
  Object.create = function (o) {
    function F(){}
    F.prototype = o;
    return new F;
  };
}

Но, пожалуйста не делайте этого .

Проблема этого подхода заключается в том, что ES5 Object.create имеет сигнатуру 2 аргумента : первый - объект для наследования, а второй (необязательно) - объект, представляющий свойства (или, скорее, дескрипторы ) для добавления во вновь созданный объект.

Object.create(O[, Properties]); // see 15.2.3.5, ECMA-262 5th ed.

Мы имеем несовместимую реализацию с 2 различными поведениями . В средах с собственным Object.create метод знает, как обрабатывать второй аргумент; в средах без собственного Object.create это не так.

Каковы практические последствия?

Что ж, если есть какой-то код (скажем, сторонний скрипт), который хочет использовать Object.create, то разумно, чтобы этот код сделал это:

if (Object.create) {
  var child = Object.create(parent, properties);
}

- по сути, если предположить, что если Object.create существует, он должен соответствовать спецификациям - принять второй аргумент и добавить соответствующие свойства к объекту.

Но с вышеупомянутой прокладкой второй аргумент просто игнорируется. Нет даже признаков того, что что-то пошло неправильно по-другому. Так сказать, тихая ошибка, которую довольно больно обнаружить и исправить.

Можем ли мы сделать лучше?

Ну, на самом деле невозможно создать полностью соответствующую Object.create шимму, используя только (стандартные) средства ES3 . Лучшее решение - создать собственный метод-обертку.

Однако есть несколько альтернативных (менее чем оптимальных) вещей, которые вы можете попробовать:

1) Уведомить пользователя о невозможности работы со вторым аргументом

if (!Object.create) {
  Object.create = function (o) {
    if (arguments.length > 1) { 
      throw Error('second argument is not supported'); 
    }
    // ... proceed ...
  };
}

2) Попробуйте обработать второй аргумент:

if (!Object.create) {
  Object.create = function (parent, properties) {
    function F(){}
    F.prototype = parent;
    var obj = new F;
    if (properties) {
      // ... augment obj ...
    }
    return obj;
  }; 
}

Обратите внимание, что "properties" - это объект, представляющий дескрипторы свойств , а не только имена / значения свойств, и его не так-то просто поддерживать (некоторые вещи даже невозможны, например, управление перечислимостью собственность):

Object.create(parent, {
  foo: {
    value: 'bar',
    writable: true
  },
  baz: {
    get: function(){ return 'baz getter'; },
    set: function(value){ return 'baz setter'; },
    enumerable: true
  }
});

Другое несоответствие в оригинальной прокладке заключается в том, что она не заботится о том, чтобы родительский объект был null.

var foo = Object.create(null);

Это создает объект, чей [[Prototype]] равен null; другими словами, объект, который не наследуется ни от чего, даже от Object.prototype (от которого наследуются все нативные объекты в ECMAScript).

foo.toString; // undefined
foo.constructor; // undefined
// etc.

Кстати, это полезно для создания «правильных» хеш-таблиц в ECMAScript.

Можно эмулировать это поведение, но только с использованием нестандартных расширений, таких как «магическое» свойство __proto__ (поэтому реализация будет не очень переносимой или устойчивой). Решение этой проблемы аналогично: либо полностью эмулируйте реализацию ES5, либо сообщайте о несогласованности / сбое.

8 голосов
/ 19 октября 2010

es5-shim http://github.com/kriskowal/es5-shim/

Это было частью автономной среды javascript нарвала, но оно было разорвано само по себе.Он чертовски зрелый и точный.

3 голосов
/ 19 июня 2010

es5 - JavaScript / EcmaScript 5 в 3 - это коллекция, используемая в BitBucket.Object.create, в частности, легко подделать подделка , ставшая популярной Крокфордом и др., Но улучшенная здесь Джастином Лавом , ориентируясь на многие части ES5.

0 голосов
/ 27 июня 2011

Если вы не возражаете против изучения библиотеки и написания некоторого кода самостоятельно, вы можете найти некоторые реализации кода библиотеки ECMAScript 5 по адресу

https://developer.mozilla.org/En/JavaScript/ECMAScript_5_support_in_Mozilla

Например, коддля Array.filter

И затем Крокфорд имеет JSON.parse / stringify в json2.js

https://github.com/douglascrockford/JSON-js

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...