我正在查看JS原型继承的视频解释(https://www.youtube.com/watch?v=qMO-LTOrJaE)。 有些事情我不明白。让我解释一下
var Bear = function(type) { //PARENT
this.type;
this.hasFur = true;
}
Bear.prototype.kingdom = 'Animalia'; //ASSIGNING TO PARENT'S PROTOTYPE
var Grizzly = function(type) { //CHILD
this.species = 'Brown Bear';
}
Grizzly.prototype = Object.create(Bear.prototype); //INHERITING FROM PARENT
var grizzly1 = new Grizzly('grizzly');
console.log(grizzly1.hasFur); //prints undefined //members in parent's constructor not accessible
console.log(grizzly1.kingdom); //prints Animalia //however, members in parent's prototype is accessible

但是只要将以下行添加到Grizzly构造函数中,
var Grizzly = function(type){
Bear.call(this, type); //ADDED
this.species = 'Brown Bear';
}
你能够从父母那里获取所有东西,而不仅仅是它的原型
console.log(grizzly1.hasFur); //prints true
console.log(grizzly1.kingdom); //prints Animalia
但是,以下面的方式继承,即使在Child构造函数中没有@Bear.call(this)行,也允许子进入父对象中的所有内容。
Grizzly.prototype = new Bear();
所以它真的以这种方式继承了一切。有人可以解释这种行为是什么以及它发生的原因吗?
还有什么不同的JavaScript继承方式。考虑最佳实践以及原因,最好使用哪一个。
答案 0 :(得分:4)
有些事我不明白。让我解释一下
var Bear = function(type) { //PARENT
this.type;
this.hasFur = true;
}
Bear.prototype.kingdom = 'Animalia'; //ASSIGNING TO PARENT'S PROTOTYPE
var Grizzly = function(type) { //CHILD
this.species = 'Brown Bear';
}
Grizzly.prototype = Object.create(Bear.prototype); //INHERITING FROM PARENT
var grizzly1 = new Grizzly('grizzly');
console.log(grizzly1.hasFur); //prints undefined //members in parent's constructor not accessible
console.log(grizzly1.kingdom); //prints Animalia //however, members in parent's prototype is accessible
在上面分享的代码段中,grizzly1.hasFur
为undefined
,因为Bear
的构造函数尚未执行。第Grizzly.prototype = Object.create(Bear.prototype);
行只是继承父原型方法和属性。
但是只要将以下行添加到Grizzly构造函数中,
var Bear = function(type) { //PARENT
this.type;
this.hasFur = true;
}
Bear.prototype.kingdom = 'Animalia'; //ASSIGNING TO PARENT'S PROTOTYPE
var Grizzly = function(type) { //CHILD
Bear.call(this, type); //ADDED
this.species = 'Brown Bear';
}
Grizzly.prototype = Object.create(Bear.prototype); //INHERITING FROM PARENT
var grizzly1 = new Grizzly('grizzly');
console.log(grizzly1.hasFur); //prints undefined //members in parent's constructor not accessible
console.log(grizzly1.kingdom);
grizzly1.hasFur
现在是true
,因为现在在grizzly
的构造函数中,调用Bear
的构造函数类,使用call
更改其上下文。由于上下文已更改,this. hasFur
会在此操作中分配其true
值,this
现在引用grizzly
的实例。
但是,以下面的方式继承,即使在Child构造函数中没有//Bear.call(this)行,也允许子进入父对象中的所有内容。 Grizzly.prototype = new Bear();
这里发生的是,创建了一个Bear类的新实例。现在Bear类的任何实例都可以访问在实例化构造函数类(即function Bear
时定义的原型方法和内部属性。现在,在创建实例之后,将其分配给Grizzly
的原型链。因此Grizzly
的任何新实例不仅访问Grizzly
的内部属性,而且还充当Bear类的新实例。
还有哪些在JavaScript中继承的方式
我肯定建议你研究设计模式。你可以谷歌出来不同的书籍。我喜欢阅读 JavaScript:好的部分和学习JavaScript设计模式。你可能会喜欢其他一些书来清理你的基础知识。 Javascript中有很多可数的东西,如这些,闭包等,需要清晰的概念。
考虑最佳做法及其原因,最好使用哪一个。
我更喜欢原型继承的最佳实践是:
在构造函数类中说A
function A () {
this.privateProp = something;
}
A.prototype.public = something;
所以请参阅声明构造函数类中的那些属性和方法,您希望保持私有。将其暴露在原型链中。
希望这有帮助。
答案 1 :(得分:2)
检查出来:
var Bear = function(type){ //PARENT
this.type;
this.hasFur = true;
}
alert(new Bear().hasFur);
了解此 如何在警告框中为您提供true
。想想,为什么这样做,而不是你的例子?
想到了吗?
这是因为在这段代码中:
var Bear = function(type){ //PARENT
this.type;
this.hasFur = true;
}
您将该功能分配给Bear
,因此new Bear()
无法Bear.prototype
访问该功能。这将有效:
Bear.prototype.kingdom = 'Animalia'; //ASSIGNING TO PARENT'S PROTOTYPE
var Grizzly = function(type){ //CHILD
this.species = 'Brown Bear';
}
Grizzly.prototype = Object.create(new Bear()); // Modified line
var grizzly1 = new Grizzly();
alert(grizzly1.hasFur); // Prints true now.
alert(grizzly1.kingdom);