JS中原型鏈中的prototype與_proto_的我的理解與詳細總結

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

如下三點須要謹記前端

1.每一個對象都具備一個名爲__proto__的屬性;java

2.每一個構造函數(構造函數標準爲大寫開頭,如Function(),Object()等等JS中自帶的構造函數,以及本身建立的)都具備一個名爲prototype的方法(注意:既然是方法,那麼就是一個對象(JS中函數一樣是對象),因此prototype一樣帶有__proto__屬性);編程

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

思路擴展以下架構

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是構造函數獨有的屬性;this

對象的__prototype__屬性一般與其構造函數的prototype屬性相互對應;spa

全部構造函數的的prototype方法的__都指向__Object.prototype(除了....Object.prototype自身);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 喜歡1

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');

 

ps:

javascript中__proto__和prototype的區別

400?w5=441&h5=266&rf=groupPhoto

400?w5=295&h5=254&rf=groupPhoto

400?w5=446&h5=389&rf=groupPhoto

javascript是基於對象的,換一種說法是基於原型(鏈)的。

每個函數都有一個prototype(原型)屬性,這個屬性是一個對象,它的用途是包含能夠由特定類型的全部實例共享的屬性和方法。prototype是經過調用構造函數來建立的那個對象的原型(屬性)對象。

Javascript中對象的prototype屬性,能夠返回對象的 原型對象 的引用。

怎麼理解原型(鏈)?
圖1
函數(對象)有prototype屬性->對應了一個原型對象->每一個原型對象都有一個constructor屬性->包含一個指向prototype屬性所在函數的指針

每個實例都有一個內部屬性__proto__->指向原型對象

這裏提到的幾個屬性或對象: Person.prototype;//->原型對象 Person.prototype.constructor;//->指向構造函數
  p.__proto__;//->指向原型對象

相關文章
相關標籤/搜索