javascript
javascript之原型
一、初識原型
?? ???JS的引用類型會內置一個特殊的屬性prototype。默認的prototype是object類型的,是引用類型。既然默認的prototype是object類型的,那么prototype也會有一個原型,并且指向object的原型。
另外補充一點,function的原型可直接訪問,object的不行。
示例:
function SuperType(){};SuperType.age=18;SuperType.prototype.color=[“red”,”blue”];var t1=new SuperType ();t1.name=”hh”;var t2=new SuperType ();t2.qq=”aa”;SuperType,t1,t2原型關系示意圖:
定義function SuperType時,編譯器會為其分配一個prototype屬性,并在內存中開辟一片區域用于存放SuperType的原型的數據,假設這片區域的地址為0xA。然后讓SuperType的prototype指向0xA。由SuperType創建出來的t1和t2的prototype也指向內存地址0xA。如果有SuperType.prototype.color.push(“green”),則t1和t2的color也會變為[“red”,”blue”,”green”]。因為SuperType,t1,t2的原型指向的是同一個地址的數據。這個過程可以這么比喻:把原型比喻為你的銀行卡賬戶,假設有一萬塊錢。當有人盜刷你的銀行卡,刷走了4000,然后你去銀行查看你賬戶余額,當然的會剩下6000。因為你跟盜刷你銀行卡的人所持的銀行卡指向的是同一個賬戶。
??? SuperType.prototype.color.push(“green”)后,示意圖如下:
二、 原型鏈
其實在上面的示意圖中,順著箭頭走,如Test—>Test的原型—>Object的原型,就是一條原型鏈了。當然t2—>Test的原型—>Object的原型也是一條原型鏈。下面對原形鏈進行補充,說明原型鏈在繼承體系中是怎么工作的。
示例:
function SuperType(){}; SuperType.age=18; SuperType.prototype.color=[“red”,”blue”];function SubType(){} SubType.property=”property”; SubType.prototype=new SuperType(); SubType.prototype.test=function(){alert(“test”);}function Child(){} Child.prototype=new SubType(); var t1=new SuperType (); t1.name=”hh”; var t2=new SuperType (); t2.qq=”aa”;var s=new SubType(); var c=new Child();注意,SubType的原型被重新賦值了,SubType.prototype=new SuperType();
所以SubType的原型是SuperType的一個對象實例。
上述代碼的原型鏈示意圖如下:
三、重置原型
要重置原型,只要對原型重新賦值即可。例如:function Person(){} Person.prototype={ name:”Leo” } 需要注意的是,Person原型重寫后,Person的原型為{ name:”Leo”}。{ name:”Leo”}是一個匿名的Object實例,所以其constructor,為Object。也就是說重寫后Person的原型的constructor為Object。如果constructor重要,可以為其增加一個constructor屬性,如下:Person.prototype={????????? name:”Leo”,????????? constructor:Person}不過此時還會有一個問題,這樣設置的constructor將會使constructor變成是可枚舉的。所以,如果想讓它變為不可枚舉的,可用Object.defineProperty進行設置。
四、原型的動態性
示例:
function Person(){}var p=new Person();Person.prototype.sayHi=function(){alert(“Hi”);};p.sayHi();//這里沒問題,因為p在調用sayHi時,會先從自身找sayHi,找不到則會沿//著原形鏈去尋找,然后在Person的原型中找到了sayHi,于是就執行?
原型動態性之-------重寫原型的問題
function Person(){}var p=new Person();Person.prototype={sayName: function(){alert(“Hi”);},constructor:Person}p.sayName();//此時將會報錯,p沒有sayName方法?
這里為何p.sayName會報錯,Person的原型不是有sayName么?
且看下面的示意圖:
五、原型共享所引發的問題
原型的優點就是共享。例如:
function Person (){} Person.prototype.sayName=function(){}; var p1=new Person (); var p2=new Person ();在原型中定義sayName函數,于是p1,p2對象有同一個sayName。而不會在內存中分配兩次內存來分別存放p1的sayName和p2的sayName。而缺點也是由共享所致。共享對于函數而言,是合適的,但是對于其他屬性而言,可能就會出問題。示例如下:
function Person(){} Person.prototype.color=[“red”,”green”]; var p1=new Person(); var p2=new Person(); alert(p1.color);//輸出red,green alert(p2.color); //輸出red,green p2.color.push(“blue”); alert(p1.color); //輸出red,green,blue。注意,這里我并沒有更改p1的color;alert(p2.color); //輸出red,green,blue這里我們可以發現,p2的color進行更改之后,p1的color也跟著更改,這正是原型共享所引發的問題。
六、原型鏈與instanceof實現原理
假設a instanceof b,那么會從a的原形鏈中找出是否有跟b的原型相等的原型,如果找到則返回true,否則返回false。
示例如下:
function SuperType(){} function SubType(){} function Test(){} SubType.prototype=new SuperType(); var s=new SubType(); console.log(s instanceof SubType);//打出true,這是因為s的原型等于SubType的原型 SubType.prototype=new SuperType(); console.log(s instanceof SubType);//打出false示意圖如下:(省略了百度上的文字說明而改為圖片說明)
以上是百度經驗里關于 javascript原型 的介紹。
延伸:
1.構造函數中的return
構造函數在沒有return的情況下新的實例默認返回undefined;如果構造函數中有return語句,
分兩種情況:
- return 基本類型,返回函數
- return 對象,返回對象。
2.原型模式的執行流程
- 先查找構造函數實例里的屬性或方法,如果有,就立即返回。
- 如果構造函數的實例沒有,就去它的原型對象里找,如果有,就立即返回
?拜讀了風雨后見彩虹的文章
轉載于:https://www.cnblogs.com/Merrys/p/8012661.html
總結
以上是生活随笔為你收集整理的javascript之原型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浏览器兼容--条件样式,选择符前缀,样式
- 下一篇: TextView使用实例