Ответ 1
Есть несколько вещей, которые нельзя эмулировать из метода ECMAScript 5 Object.create
в среде ECMAScript 3.
Как вы видели, аргумент свойств даст вам проблемы, поскольку в реализациях на основе E3 существует no way для изменения атрибутов свойств.
Метод Object.defineProperty
, упомянутый как @Raynos, работает на IE8, но частично, его можно использовать только в элементах DOM.
Также свойства аксессора дадут вам проблемы, их можно было бы имитировать с помощью широко распространенных нестандартных методов, таких как __defineGetter__
/__defineSetter__
, но вы не можете изменить атрибуты свойств.
Другая проблема, помимо дескрипторов свойств, заключается в том, что метод Object.create
может принимать null
в качестве аргумента, чтобы создать объект, который не наследует ничего.
Эту нельзя эмулировать с помощью Crockford Object.create
shim, потому что когда оператор new
используется с конструкторской функцией, которая имеет свойство prototype
, содержащее null
или любое другое значение, отличное от объекта, но созданный объект по умолчанию будет наследовать от Object.prototype
.
В некоторых реализациях -V8, Spidermonkey, Rhino и т.д. - они имеют свойство setteable __proto__
, которое может быть использовано для установите null
[[Prototype]], но опять же, это нестандартное, и наверняка он никогда не будет работать в IE.
Я бы рекомендовал, если вы хотите настроить таргетинг на старые браузеры, чтобы не использовать эти функции, поскольку нет способа заставить их работать должным образом в этих средах.
Если вы все еще хотите использовать Object.create
, не используя аргумент свойств, вы могли бы, однако, я бы рекомендовал вам обнаружить вещи, которые нельзя эмулировать.
Ниже приведена более безопасная версия Crockford Object.create
shim:
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;
};
})();
}
В любом случае, используйте его осторожно.