将一个函数的原型设置为另一个用于进行子类化的函数的原型(使用Object.setPrototypeOf()))

时间:2018-11-28 20:35:32

标签: javascript prototype

我不确定标题是否真正有意义,但是我试图将函数原型设置为“子类”原型。

例如:

我想做的是:我有一个userpaidUserpaidUsersubclass中的user

用户工厂功能:

    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的{​​{1}}设置为userCreator prototype的{​​{1}}

下面的代码行之有效,但我不太理解。 paidUserCreator函数应该创建一个空对象,并且空对象Factory Function必须是给定的参数。

Object.create

我不明白的另一点是:

为什么以下行不起作用?

__proto__

完成:

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

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

PS:是的,我知道Object.setPrototypeOf(paidUserCreator, userCreator.prototype); 关键字更简洁易读,但我想学习如何使用这种方式。

1 个答案:

答案 0 :(得分:2)

从最后一个问题开始:

  

为什么以下行不起作用?

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)