JS中原型鏈中的prototype與_proto_的個人理解與詳細總結(**************************************************************)


一直認為原型鏈太過復雜,尤其看過某圖后被繞暈了一整子,今天清理硬盤空間(渣電腦),偶然又看到這圖,勾起了點回憶,於是索性復習一下原型鏈相關的內容,表達能力欠缺邏輯混亂別見怪(為了防止新人__(此處指我)__被在此繞暈,圖片就放在末尾了。)

以下三點需要謹記

1.每個對象都具有一個名為__proto__的屬性;

2.每個構造函數(構造函數標准為大寫開頭,如Function(),Object()等等JS中自帶的構造函數,以及自己創建的)都具有一個名為prototype的方法(注意:既然是方法,那么就是一個對象(JS中函數同樣是對象),所以prototype同樣帶有__proto__屬性);

3.每個對象的__proto__屬性指向自身構造函數的prototype;

思路擴展如下

復制代碼
 1             function Fun(){
 2             }
 3 //            我創造了一個函數Fn
 4 //            這個函數由Function生成(Function作為構造函數)
 5             var fn=new Fun()
 6 //            我創建了一個函數fn
 7 //            這個函數由Fn生成(Fn作為構造函數)
 8             
 9             
10             console.log(fn.__proto__===Fun.prototype)    //true
11 //            fn的__proto__指向其構造函數Fun的prototype
12             console.log(Fun.__proto__===Function.prototype)        //true
13 //            Fun的__proto__指向其構造函數Function的prototype
14             console.log(Function.__proto__===Function.prototype)    //true
15 //            Function的__proto__指向其構造函數Function的prototype
16 //            構造函數自身是一個函數,他是被自身構造的
17             console.log(Function.prototype.__proto__===Object.prototype)    //true
18 //            Function.prototype的__proto__指向其構造函數Object的prototype
19 //            Function.prototype是一個對象,同樣是一個方法,方法是函數,所以它必須有自己的構造函數也就是Object
20             console.log(Fun.prototype.__proto__===Object.prototype)         //true
21 //             與上條相同
22 //             此處可以知道一點,所有構造函數的的prototype方法的__都指向__Object.prototype(除了....Object.prototype自身)
23             console.log(Object.__proto__===Function.prototype)        //true
24 //            Object作為一個構造函數(是一個函數對象!!函數對象!!),所以他的__proto__指向Function.prototype
25             console.log(Object.prototype.__proto__===null)        //true
26 //            Object.prototype作為一切的源頭,他的__proto__是null
27 
28 //            下面是一個新的,額外的例子
29 
30             var obj={}
31 //            創建了一個obj
32             console.log(obj.__proto__===Object.prototype)        //true
33 //            obj作為一個直接以字面量創建的對象,所以obj__proto__直接指向了Object.prototype,而不需要經過Function了!!
34 
35 //            下面是根據原型鏈延伸的內容
36 //            還有一個上文並未提到的constructor,  constructor在原型鏈中,是作為對象prototypr的一個屬性存在的,它指向構造函數(由於主要講原型鏈,這個就沒在意、);
37 
38             console.log(obj.__proto__.__proto__===null)        //true
39             console.log(obj.__proto__.constructor===Object)        //true
40             console.log(obj.__proto__.constructor.__proto__===Function.prototype)        //true
41             console.log(obj.__proto__.constructor.__proto__.__proto__===Object.prototype)    //true    
42             console.log(obj.__proto__.constructor.__proto__.__proto__.__proto__===null)        //true
43             console.log(obj.__proto__.constructor.__proto__.__proto__.constructor.__proto__===Function.prototype)    //true
44             
45             
46 //            以上,有興趣的可以一一驗證  F12搞起.
         
復制代碼

 

為了方便記憶可以得出如下結論(如有錯誤歡迎斧正.....)

prototype是構造函數獨有的屬性;

對象的__prototype__屬性通常與其構造函數的prototype屬性相互對應;

所有構造函數的的prototype方法的__都指向__Object.prototype(除了....Object.prototype自身);

 

需要注意的指向是

Function的__proto__指向其構造函數Function的prototype;

Object作為一個構造函數(是一個函數對象!!函數對象!!),所以他的__proto__指向Function.prototype;

Function.prototype的__proto__指向其構造函數Object的prototype;

Object.prototype的__prototype__指向null(盡頭);

 

在文章結構順便附送上倆個與原型鏈相關的方法....歡迎使用

1.

hasOwnProperty判斷一個對象是否有名稱的屬性或對象,此方法無法檢查該對象的原型鏈中是否具有該屬性,該屬性必須是對象本身的一個成員。 
如果該屬性或者方法是該 對象自身定義的而不是器原型鏈中定義的 則返回true;否則返回false; 
格式如下: 
 
object.hasOwnProperty(proName);   
括號內必須要加引號,並且直接寫入屬性名
 
2.
 
isPrototypeOf是用來判斷指定對象object1是否存在於另一個對象object2的原型鏈中,是則返回true,否則返回false。 
格式如下: 
object1.isPrototypeOf(object2); 
object1是一個對象的實例; 
object2是另一個將要檢查其原型鏈的對象。 
原型鏈可以用來在同一個對象類型的不同實例之間共享功能。 
如果 object2 的原型鏈中包含object1,那么 isPrototypeOf 方法返回 true。 
如果 object2 不是一個對象或者 object1 沒有出現在 object2 中的原型鏈中,isPrototypeOf 方法將返回 false。 
 
 

 

 

 

 

 

 

 

 

某圖在這里  ps:本文是總結,加個人理解.....圖是好久前留存在電腦的....忘了是在哪看到的...

 

 

 

 

 

JS對象、原型

字數664 閱讀10 評論0 

Q&A:

1. OOP 指什么?有哪些特性

  • OOP,即Object Oriented Programming,面向對象編程,是計算機的一種編程架構,OOP的一條基本規則是,計算機程序由能夠起到子程序作用的單個或對象組合而成。包含屬性和方法的對象是類的實例,而JS中沒有類的概念,而是直接使用對象實現編程任務。
  • 特性
    • 封裝:能夠將一個實體的信息、功能、響應都裝在一個單獨對象中的特性;使編程過程不必拘泥於原理,而是重在實現;
    • 繼承:在不改變源程序的基礎上進行擴充,原功能得以保存,並且子程序能對其進行擴展,避免編寫重復代碼,提高工作效率;
    • 多態:允許將子類類型的指針賦值給父類類型的指針;原生JS是弱類型語言,沒有多態概念。

2. 如何通過構造函數的方式創建一個擁有屬性和方法的對象?

由於函數也是對象的一種,所以繼承了對象原型,可以對其添加屬性和方法,構造函數也是函數,所以用自定義函數的方式,並將首字母大寫以明確是構造函數即可,可以用new操作符創建函數實例驗證。

function Person(name) { this.name = name; this.sayName = function() { console.log(this.name); } }

構造函數

3. prototype 是什么?有什么特性

  • prototype,即原型,每創建一個函數都會有一個prototype屬性,這個屬性是一個指針,指向一個對象,這個對象的用途是包含可以由特定類型的所有實例共享的屬性和方法。
  • 特性:讓所有對象實例共享原型對象所包含的屬性和方法:

    function Person(name) { this.name = name; } Person.prototype.sayName = function() { console.log(this.name); } var p1 = new Person('zhao'), p2 = new Person('kevin'); p1.sayName(); p2.sayName();

    prototype

4. 畫出如下代碼的原型圖

    <script> function People(name) { this.name = name; this.sayName = function() { console.log('my name is:' + this.name); } } People.prototype.walk = function() { console.log(this.name + 'is walking'); } var p1 = new People('飢人谷'); var p2 = new People('前端'); </script>

原型圖

5. 以下代碼中的變量age有什么區別

      function People() { var age = 1; this.age = 10; } People.age = 20; People.prototype.age = 30;
  • var age = 1:age為局部變量;
  • this.age = 10:函數調用時,age為this指向對象的屬性;
  • People.age = 20:構造函數的age變為20;
  • People.prototype.age = 30:原型添加age屬性;

Coding:

1. 創建一個 Car 對象,擁有屬性name、color、status;擁有方法run,stop,getStatus

function Car(name, color, status) { this.name = name; this.color = color; this.status = status; } Car.prototype = { constructor : Car, run: function() { this.status = 'run'; }, stop: function() { this.status = 'stop'; }, getStatus: function() { console.log(this.status); } } var car1 = new Car('BMW', 'red', 'stop');

coding1

本文歸本人和飢人谷所有,如需轉載請注明出處


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM