Установка прототипа функции как прототипа другой функции для создания подклассов (с Object.setPrototypeOf ())) - PullRequest
0 голосов
/ 28 ноября 2018

Я не уверен, имеет ли заголовок какой-либо смысл, но я пытаюсь установить прототип функции на прототип "подклассов".

Для следующего примера;

Я пытаюсь сделать следующее: у меня есть user и paidUser.paidUser - это subclass из user

Функция User Factory:

    function userCreator(name, score) {
      this.name = name;
      this.score = score;
    }
    userCreator.prototype.sayName = function(){console.log("hi");}
    userCreator.prototype.increment = function(){this.score++;}

И я могу создать нового пользователя с ключевым словом new.пока все хорошо.

const user1 = new userCreator("Phil", 5);

Теперь, подходя к Subclassing.(accountBalance - это просто глупое свойство, специально для paidUser для моего примера)

    function paidUserCreator(paidName, paidScore, accountBalance){
      userCreator.call(this, paidName, paidScore);
      this.accountBalance = accountBalance;
    }

Теперь я хочу установить prototype моего userCreator как prototype из paidUserCreator Factory Function

Следующая строка отлично работает, но я ее не совсем понимаю.Функция Object.create должна создать пустой объект, и этот параметр должен быть пустым __proto__.

paidUserCreator.prototype =Object.create(userCreator.prototype);

paidUserCreator.prototype.increaseBalance = function(){
  this.accountBalance++;
}

Еще один момент, который я не понимаю:

Почемуследующая строка не работает?

Object.setPrototypeOf(paidUserCreator, userCreator.prototype);

Для завершения:

const paidUser1 = new paidUserCreator("Katarina", 4, 12);

PS: Да, я знаю, что ключевое слово Class намного чище и приятнее для чтения, но я хочунаучитесь делать это таким образом.

1 Ответ

0 голосов
/ 28 ноября 2018

Начиная с последнего вопроса:

Почему не работает следующая строка?

Object.setPrototypeOf(paidUserCreator, userCreator.prototype);

Будет, но вам нужно установить прототипpaidUserCreator.prototype не функция paidUserCreator, поэтому, когда экземпляр ищет что-то на paidUserCreator.prototype и не находит его, он смотрит на userCreator.prototype.

function userCreator(name, score) {
  this.name = name;
}
userCreator.prototype.sayName = function() {
  console.log("hi");
}

function paidUserCreator(paidName, paidScore, accountBalance) {
  userCreator.call(this, paidName, paidScore);
}
Object.setPrototypeOf(paidUserCreator.prototype, userCreator.prototype);

let p = new paidUserCreator("Mark", 98, 200.5)
p.sayName()

paidUserCreator.prototype = Object.create(userCreator.prototype) аналогично.Object.create создает новый объект и устанавливает его прототип так, чтобы он указывал на переданный объект. Когда вы делаете это, вы заменяете paidUserCreator.prototype новым объектом, прототип которого связан с userCreator.prototype.Одно предостережение: если на paidUserCreator.prototype есть что-то, что вам нужно, оно будет потеряно, потому что вы заменяете весь объект, а не просто устанавливаете прототип.

function userCreator(name, score) {
    this.name = name;
}
userCreator.prototype.sayName = function(){console.log("hi");}

function paidUserCreator(paidName, paidScore, accountBalance){
    userCreator.call(this, paidName, paidScore);
}

// points to the paidUserCreator function
console.log(paidUserCreator.prototype.constructor)

// replace protoype with new object
paidUserCreator.prototype = Object.create(userCreator.prototype);

// now paidUserCreator.prototype has no constructor property
// so it defers to paidUserCreator
console.log(paidUserCreator.prototype.constructor)
...