Javascript原型继承-真正理解概念 [英] Javascript Prototypal Inheritance - Truly understanding the concept

查看:100
本文介绍了Javascript原型继承-真正理解概念的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在看这段视频说明( https://www.youtube.com/观看?v = qMO-LTOrJaE )来了解JS原型继承. 我有些不懂让我解释一下

I was looking at this video explanation(https://www.youtube.com/watch?v=qMO-LTOrJaE) of JS prototypal inheritance. There's something I don't understand. Let me explain

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构造函数中,

But as soon as you add the following line to the Grizzly constructor,

var Grizzly = function(type){
  Bear.call(this, type); //ADDED
  this.species = 'Brown Bear';
}

您可以从父级访问所有内容,而不仅仅是原型

you're able to access everything from the parent, not just it's prototype

console.log(grizzly1.hasFur);  //prints true
console.log(grizzly1.kingdom); //prints Animalia

但是,通过以下方式继承,即使子构造函数中没有////Bear.call(this)行,子对象也可以访问父对象中的所有内容.

However, inheriting in the below fashion, gives the child access to everything in the parent even without the line //Bear.call(this) in the Child constructor.

Grizzly.prototype = new Bear();

因此,它确实以这种方式继承了所有内容.有人可以解释这种行为是什么以及为什么会发生吗?

So it truly inherits everything this way. Can someone explain what's this behavior and why it happens ?

在JavaScript中继承的方式也有哪些.考虑最佳做法以及原因,最好使用哪一种.

Also what are the different ways of inheriting in JavaScript. Which one is the best to use considering best practices and why.

推荐答案

有些事情我不明白.让我解释一下

There's something I don't understand. Let me explain

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.hasFurundefined,因为尚未执行Bear的构造函数. Grizzly.prototype = Object.create(Bear.prototype);行仅继承父原型方法和属性.

In the code snippet shared above, grizzly1.hasFur is undefined as the constructor function for Bear is not yet executed. The line Grizzly.prototype = Object.create(Bear.prototype); just inherits the parent prototypal methods and properties.

但是只要将以下行添加到Grizzly构造函数中,

But as soon as you add the following line to the Grizzly constructor,

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的构造函数中,使用call更改其上下文来调用Bear的构造函数类.由于上下文已更改,this. hasFur获得了在此操作中分配的true值,现在this引用grizzly的实例.

grizzly1.hasFur is now true because now within the constructor function of grizzly, the constructor class for Bear is invoked changing its context using a call. The this. hasFur gets its true value assigned in this operation as here due to the changed context, this now refers to the instance of grizzly.

但是,通过以下方式继承,即使在Child构造函数中没有////Bear.call(this)行,也可以使子级访问父级中的所有内容. Grizzly.prototype = new Bear();

However, inheriting in the below fashion, gives the child access to everything in the parent even without the line //Bear.call(this) in the Child constructor. Grizzly.prototype = new Bear();

这里发生的是,创建了Bear类的新实例.现在,在实例化构造函数类(即function Bear)时,Bear类的任何实例都可以访问定义的原型方法和内部属性.现在,在创建实例之后,将其分配给Grizzly的原型链.因此,Grizzly的任何新实例不仅可以访问Grizzly的内部属性,而且还可以充当Bear类的新实例.

What happens here is, a new instance of the Bear class is created. Now any instance of the class Bear can have access to the prototypal methods and internal properties defined while instantiating the constructor class i.e. function Bear. Now after the instance being created, this gets assigned to the prototypal chain of Grizzly. So any new instance of Grizzly not only access the internal properties of Grizzly, but also behaves as a new instance of the Bear class.

此外,在JavaScript中继承的方式有哪些

Also what are the different ways of inheriting in JavaScript

我绝对建议您学习设计模式.您可以为此搜索出不同的书籍.我喜欢阅读 JavaScript:优秀部分学习JavaScript设计模式.您可能会喜欢其他一些书籍来理清基础知识. Javascript中很少有诸如此类的东西,闭包等,它们需要清晰的概念.

I would definitely suggest you to study design patterns. You can google out different books for it. I loved reading JavaScript: The Good Parts and Learning JavaScript Design Patterns. You might love some other books for clearing up your fundamentals. There are few countable things in Javascript like these, closures, etc., which needs crystal clear conceptions.

考虑最佳实践及其原因,哪个是最适合使用的.

Which one is the best to use considering best practices and why.

我更喜欢原型继承的最佳实践是: 在构造函数类中,说A

The best practice in prototypal inheritance ,I prefer,is: In the constructor class say A

function A () {
   this.privateProp = something;
}
A.prototype.public = something;

因此,请参见仅在构造函数类中声明要保留私有的那些属性和方法.其余的将其保留在原型链中.

So see declare only those properties and methods inside the constructor class, which you wanna keep private. Rest keep it exposed in prototype chain.

希望这会有所帮助.

这篇关于Javascript原型继承-真正理解概念的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆