一个。两个原型



很多人都知道Javascript是继承的原型,每个构造函数都有一个原型成员,可以通过它的继承来放置Javascript。华丽的浪漫

事实上,用这个属性完成Javascript的继承是不可能的。

对于我们在代码中用来完成继承的原型,我们没有什么要说的。你可以查资料。

另一个隐形原型成员。

每个实例都有一个指向原型的原型属性,这个原型无法访问。当然,它不能被修改,因为这是维护Javascript继承的基础。

复制代码代码如下所示:

构造函数声明

函数的郭艳思(){ }

功能(guoyansiex){ }

原型继承

GuoyansiEx。原型=新郭艳思();

创建对象

VaR G1 =新GuoyansiEx();

VaR G2 =新GuoyansiEx();



上面的代码中的对象可以用下面的图表来演示



两。原型维护



构造函数的构造函数总是指向构造函数的构造函数的一个实例。我们认为现在是对的。

复制代码代码如下所示:

函数的郭艳思(){ }

var obj1 =新郭艳思();

console.log(obj1构造函数= = =。guoyansi); / /真的



事实上,构造函数本身没有构造函数的属性,那么这个属性是从哪里来的呢

答案是:从原型。

因此得出以下结论

复制代码代码如下:obj1 = = = guoyansi。构造函数,构造函数= = = guoyansi原型。

现在我们可以通过构造函数查找构造函数了,我们可以进一步改进上面的图片。



复制代码代码如下所示:

功能(guoyansiex){ }

GuoyansiEx。原型=新郭艳思();

console.log(guoyansiex。构造函数= = = guoyansiex) / /假



根据上面的图片,上面的结果应该是真的,但是为什么是假的呢



现在做一个分析。

guoyansiex的原型是由guoyansi实例改写,然后在guoyansiex原型实例构造函数是自然也guoyansi。

在guoyansi实例构造函数是从Guoyansi.prototype。Guoyansi.prototype没有改写。

因此,Guoyansi.prototype指出了guoyansi构造函数(constructor);



根据以上分析,得出以下结论

复制代码代码如下:GuoyansiEx = = = guoyansi。构造函数构造函数= = = guoyansi;

如果在开发过程中对构造函数方向的要求非常精确,您可以执行以下操作。

复制代码代码如下所示:

方法:***

功能(guoyansi){ }

功能(guoyansiex){ }

GuoyansiEx。原型=新郭艳思();

GuoyansiEx。原型。构造函数= guoyansiex; / /构造函数复位。



复制代码代码如下所示:



方法二

**

功能(guoyansi){ }

函数的GuoyansiEx(){

这arguments.callee构造函数=;

}

GuoyansiEx。原型=新郭艳思();



复制代码代码如下所示:



方法三

**

功能(guoyansi){ }

函数的GuoyansiEx(){

这guoyansiex构造函数=;

}

GuoyansiEx。原型=新郭艳思();



三。看不见的原型有什么用



可见的原型链可以在他身上操作以完成我们的继承。所以我们看不见或操作不可见的原型链。它有什么用

面向对象继承有一个特点:相似性。子类类似于父类。因此,在子类中,不能删除父类继承的成员。也就是说,子类必须具有父类的特性。

为了维护这个特性,Javascript在对象内部生成一个不可见的原型属性,并且不允许用户访问。因此用户可以任意修改构造函数。

它不会破坏具有父类的子类的属性。

简而言之:Javascript的原型继承机制需要一个内部原型,而用户需要继承外部原型。



四。在Firefox引擎SpiderMonkey __proto__



这是代码。

复制代码代码如下所示:

功能(guoyansi){ }

郭艳思。原型。年龄= 24;

功能(guoyansiex){ }

var obj1 =新郭艳思();

GuoyansiEx。原型= obj1;

GuoyansiEx。原型。构造函数= guoyansiex; / /构造函数复位。

var obj2 =新GuoyansiEx();



我现在想进入这个年龄。对父类guoyansi原型性质的对象

这就是思维方式。

第一步:obj2 = = = = > obj2.constructor.prototype

第二部分:obj2。构造函数的原型= = = > GuoyansiEx.prototype;

第三部分:GuoyansiEx的原型= = = >以此;

第四部分:obj1 = = = = >。构造函数guoyansi

第五部分:guoyansi.prototype.age



这是这样写的:console.log(obj2。构造函数的原型。构造函数的原型。年龄) / / 24;

最终结果是24。

最后的结果是24。可以正常执行,但在许多书籍中,构造函数在修改后无法在父类中找到原型。我不知道发生了什么事。



在Firefox中,提出了一个更简洁的特性。_proto_

在SpiderMonkey,一个名叫_proto_属性被添加到任何创建的对象指向的构造函数使用原型。

事实上,我们上面提到的无形的原型链就是这个地方的公众。

这样可以访问到这个年龄。

console.log(obj2。__proto__。__proto__。年龄); / / 24

这确实是对父类的原型属性的成功访问,但是这个属性只适用于Firefox,在其他浏览器中也是错误的。

对象已扩展的Object.getPrototypeOf()在E5,和所有的父类可以访问。

复制代码代码如下所示:

功能(guoyansi){ }

郭艳思。原型。年龄= 24;

功能(guoyansiex){ }

var obj1 =新郭艳思();

GuoyansiEx。原型= obj1;

GuoyansiEx。原型。构造函数= guoyansiex; / /构造函数复位。

var obj2 =新GuoyansiEx();

VaR原= object.getprototypeof(obj2);

当(原){

console.log(原。构造函数);

原= object.getprototypeof(原);

}

console.log(原型对象+原);



结果是:guoyansiex

guoyansi

对象

对象的原型null



人们认为这应该是Javascript面向对象的精髓之一。