JavaScript物件導向-原型的重寫
在上一篇文章中我們介紹了原型的記憶體模型,透過4張圖分析了原型在各個階段的狀態。下面我們將首先要介紹一些常用的原型和物件屬性的偵測方法。我們還是以上一篇文章的Person類別為例子,建立Person類別的程式碼如下:
function Person(){}; Person.prototype.name = "Leon"; Person.prototype.age = 22; Person.prototype.say = fucntion(){ alert(this.name + "," + this.age); } var p1 = new Person(); var p2 = new Person(); p2.name = "Ada"; p1.say(); p2.say();
1、偵測某個物件是否是某個函數的原型
alert(Person.prototype.isPrototypeOf(p1)); //true
該方法可以偵測p1的原型是否為Person。
2、偵測某個物件的constructor
alert(p1.constructor == Person); //true
3、偵測某個屬性是否是自己的屬性
alert(p1.hasOwnProperty("name")); //false alert(p2.hasOwnProperty("name")); //true
物件p1在自己的空間中沒有name屬性,所以回傳false。而物件p2重新為name屬性進行了賦值,在它的空間中存在name屬性,所以回傳true。
4、透過delete刪除自己空間中的屬性
delete p2.name; p2.say(); alert(p2.hasOwnProperty("name")); //false
我們可以使用delete來刪除物件自己空間中的某個屬性,如上面程式碼所示。
5、透過in屬性偵測某個物件在原型或自己中是否包含有某個屬性
alert("name" in p1); //在原型中有,所以为true alert("name" in p2); //在自己的空间中有,所以为true
如果某個屬性在原型和自己的空間中都沒有,得到的結果就是false。
6、自訂方法檢測某個屬性是否在原型中存在
function hasPrototypeProperty(obj,prop){ return(!obj.hasOwnProperty(prop) && (prop in obj)); }
上面程式碼中我們自訂了一個偵測某個屬性是否在原型中存在的方法,可以如下使用這個方法:
alert(hasPrototypeProperty(p1,"name")); //true alert(hasPrototypeProperty(p2,"name")); //false
因為p1物件的name屬性是存在於原型中的,所以回傳true,而p2物件的name屬性是在自己空間中的,所以回傳false。
重寫原型
如果我們像前面那樣寫程式碼,會有大量的Person.prototype.xxx語句,這樣不便於我們閱讀和理解。我們可以透過類似Json格式來重寫原型,程式碼如下:
//重写原型 Person.prototype = { name:"Leon", age:22, say:function(){ alert(this.name+ "," + this.age); } } var p1 = new Person(); p1.say();
在使用上面的方法對原型進行重寫之後,由於原型重寫了,而且沒有透過Person.prototype來指定,此時的constructor不會再指向Person,而是指向了Object。
alert(p1.constructor == Person); //false
如果constructor對於你的程式來說真的比較重要,可以在json中聲明原型的指向。
Person.prototype = { constructor:Person, //手动指定constructor name:"Leon", age:22, say:function(){ alert(this.name+ "," + this.age); } }
原型重寫的問題
在對原型進行重寫的時候,我們可能會遇到下面的一些問題。下面我們先來看一段會出現問題的原型重寫的程式碼,然後再對程式碼中每個階段進行記憶體模型分析。程式碼如下:
// 创建Person类 function Person(){} var p1 = new Person(); //在Person的原型上添加了sayHi()方法 Person.prototype.sayHi = function(){ alert(this.name + "Hi!"); } p1.sayHi(); //输出: undefined:hi! // 对Person原型进行重写 Person.prototype = { constructor:Person, //手动指定constructor name:"Leon", age:22, say:function(){ alert(this.name+ "," + this.age); } } var p2 = new Person(); p2.sayHi(); p2.say();//正确 p1.say();//报错
在上面的程式碼中,我們首先建立了一個Person類,此時Person原型的記憶體模型如下圖所示:
接著我們創建了p1對象,然後在Person的原型中新增了一個sayHi()方法。此時Person原型的記憶體模型如下圖所示:
var p1 = new Person(); //在Person的原型上添加了sayHi()方法 Person.prototype.sayHi = function(){ alert(this.name + "Hi!"); } p1.sayHi(); //输出: undefined:hi!
注意現在的記憶體模型,由於在這種狀態中,在p1物件自己的空間和Person原型中都沒有name屬性,所以執行p1.sayHi()方法的時候,this.name屬性為undefined,最終的輸出結果為undefined:hi!。
再接下來我們對Person原型進行了重寫,在原型中加入了一些屬性和方法。
// 对Person原型进行重写 Person.prototype = { constructor:Person //手动指定constructor name:"Leon", age:22, say:function(){ alert(this.name+ "," + this.age); } } p1.sayHi(); //输出: undefined:hi!
此時的原型內存模型如下圖所示:
原型重寫之後,JavaScript會為原型分配一塊新的內存,Person類指向新的原型對象,而原來創建的p1對象的_ proto_屬性仍然指向前面的原型物件。
這時候,如果我們在執行p1.sayHi(),程式不會報錯,但是執行的結果仍然是undefined:hi!,因為在p1物件和它所指向的原型中都沒有name屬性。
最後,在原型重寫之後,我們建立了物件p2。
var p2 = new Person(); p2.sayHi();
此時的原型記憶體模型如下圖所示:
新建立的p2物件的_proto_屬性指向的是重寫後的原型對象,如果此時執行p2.sayHi()方法,那麼在p2物件和它所指向的原型上都沒有sayHi()方法,所以程式會報錯。
如果此時執行p1.say()方法,由於在p1和它指向的原型中都沒有say()方法,所以程式會報錯。
透過上面的原型記憶體模型的分析,我們可以知道原型重寫位置會直接影響物件的屬性和方法,在重寫前創建的物件和在重寫後創建的物件擁有的屬性和方法是不一樣的。上面的幾張記憶體模型圖一定要時時謹記在腦海中。
以上就是JavaScript物件導向-原型的重寫的內容,更多相關內容請關注PHP中文網(www.php.cn)!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

PHP中OOP最佳實務包括命名約定、介面與抽象類別、繼承與多型、依賴注入。實戰案例包括:使用倉庫模式管理數據,使用策略模式實現排序。

Go語言支援物件導向編程,透過型別定義和方法關聯實作。它不支援傳統繼承,而是透過組合實現。介面提供了類型間的一致性,允許定義抽象方法。實戰案例展示如何使用OOP管理客戶訊息,包括建立、取得、更新和刪除客戶操作。

JavaScript中的HTTP狀態碼取得方法簡介:在進行前端開發中,我們常常需要處理與後端介面的交互,而HTTP狀態碼就是其中非常重要的一部分。了解並取得HTTP狀態碼有助於我們更好地處理介面傳回的資料。本文將介紹使用JavaScript取得HTTP狀態碼的方法,並提供具體程式碼範例。一、什麼是HTTP狀態碼HTTP狀態碼是指當瀏覽器向伺服器發起請求時,服務

在Golang(Go語言)中並沒有傳統意義上的類別的概念,但它提供了一種稱為結構體的資料類型,透過結構體可以實現類似類別的物件導向特性。在本文中,我們將介紹如何使用結構體實現物件導向的特性,並提供具體的程式碼範例。結構體的定義和使用首先,讓我們來看看結構體的定義和使用方式。在Golang中,結構體可以透過type關鍵字定義,然後在需要的地方使用。結構體中可以包含屬

Go語言支援物件導向編程,透過struct定義對象,使用指標接收器定義方法,並透過介面實現多態。物件導向特性在Go語言中提供了程式碼重用、可維護性和封裝,但也存在缺乏傳統類別和繼承的概念以及方法簽章強制型別轉換的限制。

透過掌握追蹤物件狀態、設定斷點、追蹤異常和利用xdebug擴展,可以有效調試PHP物件導向程式碼。 1.追蹤物件狀態:使用var_dump()和print_r()檢視物件屬性和方法值。 2.設定斷點:在開發環境中設定斷點,偵錯器會在執行到達斷點時暫停,以便檢查物件狀態。 3.追蹤異常:使用try-catch區塊和getTraceAsString()取得異常發生時的堆疊追蹤和訊息。 4.利用偵錯器:xdebug_var_dump()函數可在程式碼執行過程中檢查變數的內容。

JavaScript和WebSocket:打造高效率的即時搜尋引擎引言:隨著網路的發展,使用者對即時搜尋引擎的要求也越來越高。傳統的搜尋引擎在進行搜尋時,使用者需要點擊搜尋按鈕後才能得到結果,這種方式無法滿足使用者對於即時搜尋結果的需求。因此,採用JavaScript和WebSocket技術來實現即時搜尋引擎成為了一個熱門的話題。本文將詳細介紹使用JavaScri
