Javascript 中经典原型制作方法中的“this”是如何工作的
How `this` works from a Classical Method of Prototyping in Javascript
我正在 Javascript 学习面向对象编程。
我从这里 http://www.objectplayground.com/ 获得了这个视频课程,我对经典方法的原型方法有了相当多的了解。
在观看课程时,我被下面显示的经典方法与子类一起工作的示例暂停了:
//superclass
function Answer(value){
this._val = value;
}
//define prototype property 'get' for the superclass
Answer.prototype.get = function fn1(){
return this._val;
}
//subclass
function FirmAnswer(value){
Answer.call(this,value);
}
FirmAnswer.prototype = Object.create(Answer.prototype);
FirmAnswer.prototype.constructor = FirmAnswer;
//define prototype property 'get' for subclass
FirmAnswer.prototype.get = function fn2(){
return Answer.prototype.get.call(this);
}
var luckAnswer = new FirmAnswer(7);
luckAnswer.get(); //7
问题:
根据我对 call
函数的理解,它将 this
设置为当前上下文,例如来自 FirmAnswer
函数的这一行 Answer.call(this,value)
,因此 Answer
中的 _val
将设置为 FirmAnswer
而不是 Answer
(如果我错了请纠正我)。
所以如果上面的分析是正确的,那么我很困惑,为什么 get
属性 of the FirmAnswer.prototype
returns Answer.prototype.get.call(this)
而不仅仅是 Answer.prototype.get()
,因为在调用 new FirmAsnwer(7)
?
时 this
已经设置为 FirmAnswer
请给我一些启发,因为我现在很困惑。我很确定我很了解原型方法,但经典方法让我很困惑。
提前致谢!
既然你编辑了代码,就没有必要了:
//define prototype property 'get' for subclass
FirmAnswer.prototype.get = function fn2(){
return Answer.prototype.get.call(this);
}
因为 FirmAnswer.prototype
在您执行此操作时已经具有 get 函数:
FirmAnswer.prototype = Object.create(Answer.prototype);
它将get函数从Answer.prototype
复制到FirmAnswer.prototype
所以,你可以删除它:
//superclass
function Answer(value){
this._val = value;
}
//define prototype property 'get' for the superclass
Answer.prototype.get = function fn1(){
return this._val;
}
//subclass
function FirmAnswer(value){
Answer.call(this,value);
}
FirmAnswer.prototype = Object.create(Answer.prototype);
FirmAnswer.prototype.constructor = FirmAnswer;
var luckAnswer = new FirmAnswer(7);
luckAnswer.get(); //7
不相关,因为编辑问题
这是一段奇怪的代码,包含一个错误和其他无法解释的地方。
错误是这一行:
FirmAnswer.prototype.get = Object.create(Answer.prototype);
这显然是无意义的代码,尤其是当 FirmAnswer.prototype.get
在两行之后被设置为更合理的代码时。我相当确定它应该是:
FirmAnswer.prototype = Object.create(Answer.prototype);
这是 ES6 之前的原型继承的正常方式 Javascript。
结束无关紧要
我不明白为什么 FirmAnswer.prototype.get
被设置为另一个方法,一旦上述错误被修复,无论如何调用都会被委托给 Answer.prototype.get
。
但是,您问了一个具体问题:为什么需要这一行:
return Answer.prototype.get.call(this);
为什么我们不能 Answer.prototype.get()
?当我们执行 Answer.call(this,value);
时,它仅为该调用设置上下文(this
值)。它只影响构造函数。如果你做了 Answer.prototype.get()
,函数调用的上下文实际上是 Answer.prototype
,它没有 _val
属性.
然而,这都是无关紧要的,因为实际上并不需要该方法。这是更合理形式的代码:
//superclass
function Answer(value){
this._val = value;
}
//define prototype property 'get' for the superclass
Answer.prototype.get = function fn1(){
return this._val;
}
//subclass
function FirmAnswer(value){
Answer.call(this,value);
}
FirmAnswer.prototype = Object.create(Answer.prototype);
FirmAnswer.prototype.constructor = FirmAnswer;
var luckAnswer = new FirmAnswer(7);
console.log(luckAnswer.get()); //7
函数 FirmAnswers 构造函数正在将其传递给函数 Answer,其中 Answer 正在设置 this._val。因此,如果您要在控制台中查看 luckanswer
FirmAnswer { _val: 7 }
是FirmAnswer类型的对象,_val为7
当您将 FirmAnswer.prototype.get 设置为一个命名的匿名函数,该函数 returns 调用 Answer.prototype.get 您再次将 FirmAnswers this 传递给原型,该原型基本上是复制原型.
我正在 Javascript 学习面向对象编程。 我从这里 http://www.objectplayground.com/ 获得了这个视频课程,我对经典方法的原型方法有了相当多的了解。
在观看课程时,我被下面显示的经典方法与子类一起工作的示例暂停了:
//superclass
function Answer(value){
this._val = value;
}
//define prototype property 'get' for the superclass
Answer.prototype.get = function fn1(){
return this._val;
}
//subclass
function FirmAnswer(value){
Answer.call(this,value);
}
FirmAnswer.prototype = Object.create(Answer.prototype);
FirmAnswer.prototype.constructor = FirmAnswer;
//define prototype property 'get' for subclass
FirmAnswer.prototype.get = function fn2(){
return Answer.prototype.get.call(this);
}
var luckAnswer = new FirmAnswer(7);
luckAnswer.get(); //7
问题:
根据我对 call
函数的理解,它将 this
设置为当前上下文,例如来自 FirmAnswer
函数的这一行 Answer.call(this,value)
,因此 Answer
中的 _val
将设置为 FirmAnswer
而不是 Answer
(如果我错了请纠正我)。
所以如果上面的分析是正确的,那么我很困惑,为什么 get
属性 of the FirmAnswer.prototype
returns Answer.prototype.get.call(this)
而不仅仅是 Answer.prototype.get()
,因为在调用 new FirmAsnwer(7)
?
this
已经设置为 FirmAnswer
请给我一些启发,因为我现在很困惑。我很确定我很了解原型方法,但经典方法让我很困惑。
提前致谢!
既然你编辑了代码,就没有必要了:
//define prototype property 'get' for subclass
FirmAnswer.prototype.get = function fn2(){
return Answer.prototype.get.call(this);
}
因为 FirmAnswer.prototype
在您执行此操作时已经具有 get 函数:
FirmAnswer.prototype = Object.create(Answer.prototype);
它将get函数从Answer.prototype
复制到FirmAnswer.prototype
所以,你可以删除它:
//superclass
function Answer(value){
this._val = value;
}
//define prototype property 'get' for the superclass
Answer.prototype.get = function fn1(){
return this._val;
}
//subclass
function FirmAnswer(value){
Answer.call(this,value);
}
FirmAnswer.prototype = Object.create(Answer.prototype);
FirmAnswer.prototype.constructor = FirmAnswer;
var luckAnswer = new FirmAnswer(7);
luckAnswer.get(); //7
不相关,因为编辑问题
这是一段奇怪的代码,包含一个错误和其他无法解释的地方。
错误是这一行:
FirmAnswer.prototype.get = Object.create(Answer.prototype);
这显然是无意义的代码,尤其是当 FirmAnswer.prototype.get
在两行之后被设置为更合理的代码时。我相当确定它应该是:
FirmAnswer.prototype = Object.create(Answer.prototype);
这是 ES6 之前的原型继承的正常方式 Javascript。
结束无关紧要
我不明白为什么 FirmAnswer.prototype.get
被设置为另一个方法,一旦上述错误被修复,无论如何调用都会被委托给 Answer.prototype.get
。
但是,您问了一个具体问题:为什么需要这一行:
return Answer.prototype.get.call(this);
为什么我们不能 Answer.prototype.get()
?当我们执行 Answer.call(this,value);
时,它仅为该调用设置上下文(this
值)。它只影响构造函数。如果你做了 Answer.prototype.get()
,函数调用的上下文实际上是 Answer.prototype
,它没有 _val
属性.
然而,这都是无关紧要的,因为实际上并不需要该方法。这是更合理形式的代码:
//superclass
function Answer(value){
this._val = value;
}
//define prototype property 'get' for the superclass
Answer.prototype.get = function fn1(){
return this._val;
}
//subclass
function FirmAnswer(value){
Answer.call(this,value);
}
FirmAnswer.prototype = Object.create(Answer.prototype);
FirmAnswer.prototype.constructor = FirmAnswer;
var luckAnswer = new FirmAnswer(7);
console.log(luckAnswer.get()); //7
函数 FirmAnswers 构造函数正在将其传递给函数 Answer,其中 Answer 正在设置 this._val。因此,如果您要在控制台中查看 luckanswer FirmAnswer { _val: 7 }
是FirmAnswer类型的对象,_val为7
当您将 FirmAnswer.prototype.get 设置为一个命名的匿名函数,该函数 returns 调用 Answer.prototype.get 您再次将 FirmAnswers this 传递给原型,该原型基本上是复制原型.