JavaScript 1.9.3 / ECMAScript 5 представляет Object.create
, который Douglas Crockford среди других защищал в течение долгого времени. Как я заменяю new
в коде ниже с Object.create
?
var UserA = function(nameParam) {
this.id = MY_GLOBAL.nextId();
this.name = nameParam;
}
UserA.prototype.sayHello = function() {
console.log('Hello '+ this.name);
}
var bob = new UserA('bob');
bob.sayHello();
(Примите MY_GLOBAL.nextId
существует).
Лучшее, которое я могу придумать:
var userB = {
init: function(nameParam) {
this.id = MY_GLOBAL.nextId();
this.name = nameParam;
},
sayHello: function() {
console.log('Hello '+ this.name);
}
};
var bob = Object.create(userB);
bob.init('Bob');
bob.sayHello();
Кажется, нет никакого преимущества, таким образом, я думаю, что не получаю его. Я, вероятно, являюсь слишком неоклассическим. Как я должен использовать Object.create
создать пользователя 'боб'?
Имея только один уровень наследования, ваш пример может не позволить вам увидеть реальные преимущества Object.create
Этот метод позволяет легко реализовать дифференциальное наследование, когда объекты могут напрямую наследоваться от других объектов.
На вашем примере userB
, я не думаю, что ваш метод init
должен быть публичным или даже существовать, если вы снова вызовете этот метод на существующем экземпляре объекта, свойства id
и name
изменятся.
Object.create
позволяет инициализировать свойства объекта, используя его второй аргумент, например:
var userB = {
sayHello: function() {
console.log('Hello '+ this.name);
}
};
var bob = Object.create(userB, {
'id' : {
value: MY_GLOBAL.nextId(),
enumerable:true // writable:false, configurable(deletable):false by default
},
'name': {
value: 'Bob',
enumerable: true
}
});
Как видите, свойства могут быть инициализированы на втором аргументе Object.create
, объектным литералом, используя синтаксис, аналогичный используемому методами Object.defineProperties
и Object.defineProperty
.
Он позволяет устанавливать атрибуты свойства (перечислимые
, записываемые
или конфигурируемые
), что может быть действительно полезно.
Вы должны создать специальную функцию Object.create ()
. Тот, который решает проблемы Crockfords, а также вызывает вашу функцию init.
Это будет работать:
var userBPrototype = {
init: function(nameParam) {
this.name = nameParam;
},
sayHello: function() {
console.log('Hello '+ this.name);
}
};
function UserB(name) {
function F() {};
F.prototype = userBPrototype;
var f = new F;
f.init(name);
return f;
}
var bob = UserB('bob');
bob.sayHello();
Здесь UserB похож на Object.create, но настроен для наших нужд.
Если хотите, вы также можете позвонить:
var bob = new UserB('bob');