javascript原型链维护和继承的详细说明
一、两个原型
很多人都知道javascript是原型继承,每个构造函数都有一个原型成员,可以让javascript的继承变得漂亮。事实上,Javascript继承不能只靠这个属性来完成。关于代码中使用的原型继承的完成,我们就不多说了。你可以查一下资料。另一个隐形原型成员。每个实例都有一个指向原型的原型属性,不能访问,当然也不能修改,因为这是维护javascript继承的基础。
复制的代码如下://构造函数声明函数guoyansi () {}函数guoyansiex () {}//prototype继承guoyansiex。原型=新国岩寺();//创建对象var G1=new GuoyansiEx();var G2=new GuoyansiEx();
下图说明了上述代码中的对象
二.原型维护
由构造函数生成的实例的构造函数属性总是指向构造函数。我们认为暂时是这样。
复制的代码如下:函数Guo yansi(){ } varobj 1=new Guo yansi();console . log(obj 1 . constructor===Guoyansi);//真
其实构造函数本身并没有这个属性,那么这个属性从何而来呢?答案是:来自原型。因此得出以下结论
复制的代码如下: obj1。构造函数===郭岩思。原型。构造函数===郭岩思
既然可以通过构造函数找到构造函数,就可以进一步完善上面的图。
复制的代码如下:函数guoyansiex () {} guoyansiex。原型=新国岩寺();console . log(GuoyansiEx . constructor===GuoyansiEx)//false
根据上图,上面的结果应该是真的,但为什么是假的呢?
现在做个分析。果岩寺的原型被果岩寺的实例改写了。那么果岩寺原型中的构造函数自然是来自果岩寺的实例,果岩寺实例中的构造函数是来自果岩寺. prototype,没有重写,所以果岩寺. prototype的构造函数指向果岩寺(构造函数);
根据以上分析,得出以下结论
复制的代码如下:国言协。构造函数===郭岩思。构造函数===国岩寺;
如果在开发过程中要求构造函数的方向非常精确,可以做以下处理。
复制的代码如下:/**方法1 : * */函数guoyansi () {}函数guoyansiex () {} guoyansiex。原型=新国岩寺();GuoyansiEx . prototype . constructor=GuoyansiEx;//重置构造函数指向。
复制的代码如下:/**方法2 * */函数guoyansi () {}函数guoyansiex () {this。构造函数=参数。被呼叫者;}国言者ex . prototype=新国言者();
复制的代码如下:/**方法3 * */函数guoyansi () {}函数guoyansiex () {this。构造函数=guoyansiex}国言者ex . prototype=新国言者();
隐形原型有什么用?
我们可以在可见的原型链上操作来完成我们的继承,所以我们既不能看到也不能操作这个不可见的原型链。有什么用?面向对象中的继承具有:相似性的特点。子类类似于父类。因此,您不能在子类中删除从父类继承的成员。也就是说,子类必须具有父类的特征。为了维护这个特性,Javascript在对象内部创建了一个不可见的原型属性,用户不允许访问这个属性。这样,用户可以出于任何目的修改构造函数,而不会破坏子类具有父类的属性。简而言之,javascript原型继承机制需要:内部原型,而用户需要外部原型来实现继承。
四.火狐引擎蜘蛛猴中的原型
或者这个代码。
复制代码如下:函数Guo yansi(){ } Guo yansi . prototype . age=24;函数GuoyansiEx(){ } var obj 1=new Guoyansi();GuoyansiEx.prototype=obj1GuoyansiEx . prototype . constructor=GuoyansiEx;//重置构造函数以指向。var obj 2=new GuoyansiEx();
现在我想从obj访问父类国岩寺的原型属性的年龄。思路如下。第一步是: obj 2===obj 2 . constructor . prototype,第二部分是3360 obj 2 . constructor . prototype===guoyansiex . prototype;第三部分:果岩寺。原型===obj1第四部分: obj1。建造师====果岩寺第五部分:果岩寺.原型.时代
把这个写成: console . log(obj 2 . constructor . prototype . constructor . prototype . age)//24;最终结果是24。最终结果是24。可以正常执行,但是很多书说构造函数修改后,类在父类中再也找不到原型了。我不知道发生了什么。
火狐中提到了一个更简洁的属性。默认情况下,_proto_SpiderMonkey会向任何创建的对象添加一个名为_proto_的属性,该属性指向构造函数使用的原型。其实就是上面提到的隐形原型链,只是在这个地方乔装暴露出来的。您可以访问ageconsole.log (obj2。_ _原型_ _。_) //24这确实是对父类原型属性的成功访问,但是这个属性只适用于Firefox,在其他浏览器中会出错。在E5中,对象被扩展为Object.getPrototypeOf(),可以访问父类的所有原型。
复制代码如下:函数Guo yansi(){ } Guo yansi . prototype . age=24;函数GuoyansiEx(){ } var obj 1=new Guoyansi();GuoyansiEx.prototype=obj1GuoyansiEx . prototype . constructor=GuoyansiEx;//重置构造函数以指向。var obj 2=new GuoyansiEx();var proto=object . getprototypeof(obj 2);while(proto){ console . log(proto . constructor);proto=object . getprototypeof(proto);} console . log(' object ' proto的原型);
结果是: guoyanshuigeyansiobjectobject的原型null
个人认为这些应该算是javascript面向对象的精髓之一。让我们参考它们,并根据它们的需求在自己的项目中使用它们
版权声明:javascript原型链维护和继承的详细说明是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。