Используя “Object.create” вместо “нового”

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 создать пользователя 'боб'?

364
задан Yves M. 23 April 2019 в 04:39
поделиться

2 ответа

Имея только один уровень наследования, ваш пример может не позволить вам увидеть реальные преимущества 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.

Он позволяет устанавливать атрибуты свойства (перечислимые, записываемые или конфигурируемые), что может быть действительно полезно.

246
ответ дан 23 November 2019 в 00:11
поделиться

Вы должны создать специальную функцию 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');
2
ответ дан 23 November 2019 в 00:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: