宝哥软件园

Javascript旅程对象原型链的起源

编辑:宝哥软件园 来源:互联网 时间:2021-11-23

从问题开始:function base(){ } varbase=new base()上面两行代码会创建多少个对象?要回答这个问题,首先要明确Javascript中对象的概念。在Javascript中,几乎所有的东西都是对象(数组、函数、数字、对象……),C#中没有类的概念。对象的本质是名称-值对的集合,其中名称为字符串类型,可以称为“property”,value包括各种对象(string、number、boolean、array、function……),指的是property的值。既然对象包含数组、函数、数字、对象……我们如何区分它们?答案是类型。Typeof返回一个字符串,如type of(null)=“object”,type of(false)=“boolean”,type of(1)=“number”。因为它总是返回一个字符串,对于typeof (typeof x),不管x是什么,它总是返回“string”。

ConstructorJS中没有类,所以类中没有构造函数,那么对象是如何创建的呢?使用构造函数:构造函数。构造函数实际上是一个函数,所以它也是一个对象。开始时,function Base(){}是一个构造函数,var b=new Base()使用这个构造函数(通过关键字new)创建了一个名为b的对象,此时我们可以得出结论,前两行代码中至少创建了两个对象:一个是Base,它是一个函数类型的对象,另一个是Base,它是一个对象类型的对象。Function()和Object()是两个重要的预定义构造函数。所有函数(如开头的Base())都是由function()构造的;对象的原型将被所有对象继承,如下所述。

函数创建过程相当于varBase=newfunction(“这。a=1”)在执行function Base(){this.a=1}时,也就是说,这一行代码本身将使用预定义的function()构造函数来构造函数类型对象(即Base)。js在这个创建过程中会做什么?1、首先当然会创建一个对象,Base指向这个对象。type of this object=" function "(9502 . 163.com)。

2.将__proto__属性附加到Base,使其等于构造函数的原型(也是预定义的)。这是非常重要的一步,也是常规的一步。(规则:)执行任何类似的varx=new X()时,X的原型将被赋给X的__proto__即x.__proto__和X . proto此时将指向同一个对象。

3.为Base创建一个调用属性,它是一个函数。因此,我们可以这样写:base.call ()

4.为基础创建一个构造属性,它也是一个函数。当执行var base=new Base()时,将调用此Construct属性。5、为Base创建范围、长度等属性,省略。6.为Base创建原型属性:首先,用新的object()创建一个对象,并为此对象创建一个名为构造函数的属性。属性值设置为“基本”。然后将Base的原型设置为这个新创建的对象。伪代码如下:var x=new Object();x .构造函数=Basebase . prototype=x;让我们关注2和6。从2可以看出,由构造函数构造的任何对象(包括对象和函数)都将有一个__proto__属性,该属性指向构造函数的原型属性。注意__proto__是私有财产,在IE上是看不到的。我用的是chrome,所以看得见。从6可以看出,任何用新Function()构造的函数都会有一个原型属性,它是用新Object()构造的,初始公共属性只有一个构造函数。

然后原型链在下一步6中分析伪代码,这是为函数创建原型的步骤:var x=new Object();//看2中的规则,会有x.__proto__=Object.prototype.x .构造函数=Basebase . prototype=x;此时,我们用Base()构造一个对象:var Base=new Base();//看2中的规则,必有底子。__proto__=Base.prototype,即=x.//所以有底子。_ _原型_ _。_ _ proto _ _=x . _ _ proto _ _//和x.__proto__=Object.prototype(参见前面的代码片段)//所以,base。_ _原型_ _。_ _ proto _。因为用Function()创建构造函数时的关键步骤6,所有对象的原型链的顶部都得到保证,最后它们都指向object . prototype

属性查找如果我们想读取一个对象的属性,JS会怎么做?比如有一个对象叫xxx,我们执行alert(xxx.a),也就是我们读取xxx的A属性,那么JS首先会在xxx本身寻找A属性,如果没有找到,就会在xxx中寻找A属性。__proto__,然后上原型链,如果找到了就返回(如果没有找到,就返回undefined)。举个例子:

根据上图,base本身没有构造函数属性,但是base.constructor确实可以返回函数base,因为Base。__proto__具有此属性。(什么叫贱。_ _ proto _ _ _?也就是Base.prototype,在上面构建Function的第6步的伪代码中,将Base本身赋给Base . prototype . constructor .)Object作为“基类”另外,因为任何对象的原型链的顶端都是Object.prototype,所以Object.prototype中定义的属性会通过原型链被所有对象继承。这样,预定义的对象成为所有对象的“基类”。这是原型链的继承。

从上图中可以看到,Object.prototype的一些属性已经被预定义了,我们将添加另一个名为propertyA的属性,所以这个属性和预定义的属性一样,可以从基础中读取。原型继承已经知道,对于var XXX=new Object();有xxx。__原型_ _ _=对象.原型;对于var XXX=new Base();有XXX。_ _原型_ _。_ _ proto _ _=object.prototype它看起来像什么?从c#的角度来看,很像Base是object的子类,即Base()构造的object比Object()构造的Object在原型链中低一级。这是通过将Base.prototype指向由对象()创建的对象来完成的。所以很自然,如果我想定义一个从Base继承的构造函数,我只需要将构造函数的原型指向一个由Base()构造的对象。函数派生类(){ } var Base=new Base();派生. Derived.prototype=basevar d=new DEVELOPED();//很容易算出:d。_ _原型_ _。_ _原型_ _。_ _ proto _=对象。原型。计算过程:d.__proto__指向Derived.prototype,这是基数;然后__proto__。__proto__指向基数。__proto__,即Base.prototype,即一个新对象()创建的东西,假设它是o;然后__proto__。__原型_ _。__proto__指向o.__proto__,它是对象原型。回答第一个问题和几个新问题。这两行代码至少创建了三个对象:base、Base和Base.prototype顺便说一下,Base没有prototype属性,只有函数类型的对象在构建时才会使用prototype属性创建。

d.constructor将返回什么?构造函数Base()和派生类()都为空。如果有代码,将如何执行?待续。参见下一节。

更多资讯
游戏推荐
更多+