一个非常常见的原型链采访问题,如果您知道并知道为什么,那么我认为您不需要看不起。如果您只知道iTeke观察,也许在阅读它之后,就可以知道并知道为什么。
首先,让我们找出原型对象是什么?有什么用?
我们创建的每个构造函数都有一个原型属性。此属性是指向对象的指针。该对象是原型对象。原型对象包含通过调用构造函数生成的实例对象共享的所有属性和方法。显然,使用原型对象的优点是所有实例对象都可以共享他包含的属性和方法。
其中有三个主要实体,构造函数,原型对象和实例对象。实例对象是通过调用构造函数生成的,然后将原型对象中的方法称为实例对象的方法。这三个之间的关系?
构造函数的原型属性指向其原型对象,然后原型对象具有构造函数属性,指向其构造函数。当监视构造器生成一个实例对象时,内部实例包含指针,指向构造函数的原型对象以及结构函数的原型对象。该指针在Safari,Chrome,Firefox中的实现称为__proto__。
清楚地解决此之后,让我们看看原始链是什么
或该代码,请考虑为什么Person1可以调用Sayname方法。实际上,当读取实例对象的属性时,您将首先从对象本身找到属性。也就是说,该对象的__proto__属性指向的对象,因此Person1实际上称为Person.Protype上的Sayname方法。因此,如何判断此属性是否存在于实例本身或原型对象中。您可以使用HasownProperty方法
如果此属性在实例对象本身中不存在,则它将返回false,否则将返回。
嗯?这个harsownproperty方法在哪里?person.protype上没有这样的方法。实际上,此方法来自object.protype。如何找到object.protype?实际上,它是通过原型链发现的。在这里,我们需要澄清一件东西。原型对象本质上是一个对象,并且该对象实际上是新对象(),因此,在这里,person.prototype .__ proto ========= object.prototype,是的,是的,您可以看到,所有原型对象实际上也是对象。它可以说是一个调用对象构造函数的实例对象。因此,原型点原型的__ proto是对象构造函数的原型属性的对象。首先,实例对象没有它,然后它不在他的原型对象person.protype中。然后我找到了object.protype。这是原型链。_proto___逐层找到它。如果object.prototype尚未找到,则将为null
刚才我们提到,所有原型对象实际上都是对象构造器生成的实例对象。那么对象构造函数是如何来自的?
构造函数也是一个函数。每个函数都是调用funch构造函数的实例,因此可以像这样编写函数的功能
但是,我们通常不会以这种方式编写,也不建议这样做,但是从这个表达式中,我们可以推断出对象构造函数函数实际上是调用函数构造函数的实例。因此,对象构造函数的__ proto指向函数。原型,让我们再次向上推。功能构造函数从何而来?不,函数构造函数是顶部构造函数,就像对象一样。Prototype是顶部原型对象。但是,在JS的实现中,我们会发现函数构造函数的__ proto指向函数。prototype.prototype和函数。Prototype.tructor指向函数构造函数。它看起来像功能构造函数吗?相同,说它不必纠缠不清是没有意义的。
这是这个经典原型链的另一张图片。我上面的分析实际上涵盖了这张照片的大部分。尚未提到的是foo构造函数的__proto___。它也被充分理解,因为每个函数都是通过调用函数构造函数生成的实例。
现在让我们看一下文章开头的采访问题
a.type,找到类型属性,首先是本身,然后沿其__proto属性查找。这里a是一个函数,因此他的__proto指向函数。
a.type,找到类型的属性,没有相同的A本身,然后是一个.__ proto__指向A.prototype,因为A是一个呼叫构造函数的实例对象,然后否。属性类型,值为x
在理解原始链之后,让我们看一下如何基于原型链实现继承。基本思想是使用原型来使一种参考类型继承另一种参考类型的属性和方法。在构造函数,原型和实例之间。每个构造函数都有一个原型对象。原型对象包含指向构造函数的指针(构造函数)。(__ proto__),那么,如果我们让原型对象等于另一个构造函数的实例,会发生什么?根据我们上面的分析,该原型对象将包含一个指向另一个原型对象的指针,对应,另一个原型对象也有一个指向其构造函数的指针。也许它有点周围,让我们看看代码更清晰
实现继承的关键是该行代码
调用Supertype构造函数,然后将生成的实例直接分配给子类型的原型对象。根据上面的分析,这条代码线实现了原型对象的实例,等于另一个构造函数。nowsupertype.protype,换句话说,supertype.protype是subtype.protype the Prototype链上的上层。
好的,让我们看一下上述代码。当我们在实例实例上调用getSupertypevalue方法时,我们将首先在自己中找到它,然后转到subtype.protype查找,然后转到supertype.protype.protype to Findokay,我在这里找到它。
这里有一个小问题要注意。当我们重写子类型的原型对象时,现在subtype.prototype.constructor并不是指向构造函数子类型,因为subtype.protype.protype现在是构造函数supertype的示例,他的constructor属性的sothe值实际上是他的constructor attribute的sothe属性。继承的supertype.protype。因此,他的Constructionor和Supertype.Protype现在指出了Supertype。通常,除非您故意去替换构造函数,否则不会有任何问题
此代码将报告错误。创建不是函数。实际上,我没有找到这种方法。请注意,我发现的是第二个创建。让我们分析为什么找不到它。然后,在此方法的内部,在此代码中重写了新的this.constructor()。它是一个调用父构建器的实例。返回后,然后调用其创建方法,但是在这种情况下找不到此方法,因此报告错误。实际上,此代码的原始意图是调用createConstructor.prototype的创建方法,因此您只需要在这里引用构造函数
好的,基本上已经完成。我希望本文能使您对原型和原型链有更深入的了解。