日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JavaScript面向对象——深入理解默认的继承方式原型链

發布時間:2023/12/31 javascript 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript面向对象——深入理解默认的继承方式原型链 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

描述:

正如我們所了解,JavaScript中的每個函數中都有一個指向某一對象的prototype屬性。該函數被new操作符調用時會創建并返回一個對象,并且該對象中會有一個指向其原型對象的秘密鏈接,通過該秘密鏈接(__proto__),我們就可以在新建的對象中調用相關原型對象的方法和屬性。

而原型對象自身也具有對象固有的普遍特征,因此本身也包含了指向其原型的鏈接,由此就形成了一條鏈,即我們所說的原型鏈。

如下圖所示:在對象A的一系列屬性中,有一個叫__proto__的隱藏屬性,它指向了另外一個對象B。而B的__proto__屬性又指向了對象C,以此類推,直至鏈條末端的Object對象,該對象是JavaScript的最高級對象,語言中所有對象都必須繼承自它。


意義:

在某個屬性不存在對象A中,而存在對象B中時,依然可以將它當做A的屬性來訪問,進而實現代碼的重用。

舉例說明:

function Shape() {this.name = 'Shape';this.toString = function() {return this.name;};}function TwoDShape() {this.name = '2D shape';}function Triangle(side, height) {this.name = 'Triangle';this.side = side;this.height = height;this.getArea = function() {return this.side * this.height/2;}}// 繼承實現TwoDShape.prototype = new Shape();Triangle.prototype = new TwoDShape();// 當我們對對象的prototype屬性進行完全替換時,需要重置這些對象的constructor屬性。TwoDShape.prototype.constructor = TwoDShape;Triangle.prototype.constructor = Triangle;// 驗證是否已經實現繼承var my = new Triangle(5, 10);console.log(my.toString());// 運行結果為:Triangle 解釋:

當我們在用Triangle()構造器創建的實例調用構造器不存在的toString()方法時,JavaScript引擎究竟做了什么?

? ? ? ? ①:遍歷my對象中的所有屬性,但沒有找到一個叫做toString()的方法。

②:查看my.__proto__所指向的對象,該對象是繼承關系構建過程中由new? TwoDShape()所創建的實體。

? ? ? ? ③:JavaScript引擎在遍歷TwoShape實體的過程中依然不會找到toString方法,這時候,__proto__屬性所指向的實體是new Shape()所創建的實體。

④:在new Shape()創建的實體對象中找到toString()方法。

⑤:toString()方法在my對象中調用,并且其this指向my。

繼承后的一些驗證:

①:my的構造函數是:my.constructor === Triangle; 運行結果:ture.

②:my對象同時是上述三個構造器的實例,以下運行結果均為true,即:my同時是三個構造器的實例

my instanceof Shape;? my instanceOf TwoDShape; my instanceOf Triangle;?


擴展:將共享屬性遷移到原型中去

背景描述:當我們用某一個構造器創建對象時,其屬性就會被添加到this中去。并且當被添加的屬性實際上不會隨著實體改變時,這種做法就會顯得很沒有效率。比如在上面的示例中,Shape()構造器是這樣定義的:

function Shape(){this.name = 'Shape'; } 這種實現即意味著我們用new Shape()創建的每個實體都會擁有一個全新的name屬性,并在內存中擁有自己獨立的存儲空間。

解決辦法:將name屬性移到原型上去,這樣一來,所有實體就可以共享這個屬性:

function Shape(){}; Shape.prototype.name = 'Shape'; 將name移到prototype上后,用new Shape()創建對象時,name屬性就不再是新對象的私有屬性了,而是被添加到了該對象的原型中,這樣做的前提是該屬性是不可變的,對象的共享方法就非常適合這種共享形式。

下面對以上的例子進行改造,把符合條件的方法和屬性移到原型中去。

// constructorfunction Shape() {}// argument prototypeShape.prototype.name = 'Shape';Shape.prototype.toString = function() {return this.name;};// another constructorfunction TwoDShape() {}// take care of inheritanceTwoDShape.prototype = new Shape();TwoDShape.prototype.constructor = TwoDShape;//argument prototypeTwoDShape.prototype.name = '2D shape';// another constructorfunction Triangle(side, height) {this.side = side;this.height = height;}// take care of inheritanceTriangle.prototype = new TwoDShape();Triangle.prototype.constructor = Triangle;// argument prototypeTriangle.prototype.name = 'Triangle';Triangle.prototype.getArea = function() {return this.side * this.height/2;}// 驗證是否已經實現繼承var my = new Triangle(5, 10);console.log(my.toString());// 運行結果為:Triangle

在調用my.toString()時,主要區別是查找操作將更多地發生在Shape.prototype中,而不再需要像前面示例中那樣,到由new Shape()所創建的實體對象中查找。




總結

以上是生活随笔為你收集整理的JavaScript面向对象——深入理解默认的继承方式原型链的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。