Object.create еще не стандарт на нескольких браузерах, например, IE8, Opera v11.5, Konq 4.3 не имеют его. Вы можете использовать версию Object.create для Douglas Crockford для этих браузеров, но это не включает второй параметр «объект инициализации», используемый в ответе CMS.
Для кросс-кода браузера одним из способов получить инициализацию объекта в то же время является настройка объекта Object.create от Crockford.Вот один способ: -
Object.build = function(o) {
var initArgs = Array.prototype.slice.call(arguments,1)
function F() {
if((typeof o.init === 'function') && initArgs.length) {
o.init.apply(this,initArgs)
}
}
F.prototype = o
return new F()
}
Это поддерживает Крокфорд прототипичного наследование, а также проверяет наличие какого-либо метод инициализации в объекте, а затем запускает его с параметром (ами), как, скажем, новый человек («Джон»,» Smith "). Ваш код становится: -
MY_GLOBAL = {i: 1, nextId: function(){return this.i++}} // For example
var userB = {
init: function(nameParam) {
this.id = MY_GLOBAL.nextId();
this.name = nameParam;
},
sayHello: function() {
console.log('Hello '+ this.name);
}
};
var bob = Object.build(userB, 'Bob'); // Different from your code
bob.sayHello();
Так боб наследует метод SayHello и теперь имеет собственные свойства ID = 1 и имя = 'Bob'. Конечно, эти свойства записываются и перечислимы. Это также гораздо более простой способ инициализации, чем для объекта ECMA Object.create, особенно если вас не беспокоят доступные для записи, перечислимые и настраиваемые атрибуты.
Для инициализации без метода инициализации следующего Крокфорда моды могут быть использованы: -
Object.gen = function(o) {
var makeArgs = arguments
function F() {
var prop, i=1, arg, val
for(prop in o) {
if(!o.hasOwnProperty(prop)) continue
val = o[prop]
arg = makeArgs[i++]
if(typeof arg === 'undefined') break
this[prop] = arg
}
}
F.prototype = o
return new F()
}
Это заполняет UserB собственных свойств, в том порядке, они определены, используя параметры Object.gen слева направо после параметра userB. Он использует цикл for (prop in o), поэтому по стандартам ECMA порядок перечисления свойств не может быть гарантирован так же, как и порядок определения свойства. Тем не менее, несколько примеров кода, проверенных на (4) основных браузерах, показывают, что они одинаковы, если используется фильтр hasOwnProperty, а иногда даже если нет.
MY_GLOBAL = {i: 1, nextId: function(){return this.i++}}; // For example
var userB = {
name: null,
id: null,
sayHello: function() {
console.log('Hello '+ this.name);
}
}
var bob = Object.gen(userB, 'Bob', MY_GLOBAL.nextId());
В некоторой степени проще сказать, чем Object.build, так как userB не нуждается в методе init. Кроме того, userB не является конструктором, но выглядит как обычный одноэлементный объект. Таким образом, с помощью этого метода вы можете создавать и инициализировать обычные обычные объекты.
Когда принятый ответ имеет меньше голосов, чем вопрос, может быть, принятый ответ неприемлем? @CMS заставил бы вас написать фабричную функцию, которая использует 'Object.create' внутри, чтобы получить те же одноступенчатые функции, что и' new UserA ('bob'); '. –
Возможно, это самый * приемлемый ответ, учитывая, что у него больше всего голосов из 6 ответов. –
См. Также [Понимание различий между Object.create() и новым SomeFunction()] (http://stackoverflow.com/q/4166616/1048572) – Bergi