1. 程式人生 > >對js原型簡單的理解和圖解

對js原型簡單的理解和圖解

最近在努力的學習js中,今天就抽了個空把自己理解的原型,記下一下在筆記中,以後自己檢視,有空在會把原型鏈記錄一下。

1.prototype

prototype:是一個函式的屬性,每個函式中都會有一個prototype屬性,這個屬性是一個指標,指向一個物件。

該如何檢視prototype

建立一個Person函式,開啟chrome裡面,F12開啟開發者工具在Sources,在最右邊的Watch視窗 +中輸入Person就可以檢視Person所有的屬性和方法。

prototype定義

每個函式都有一個prototype屬性,這個屬性是指向一個物件的引用,這個物件稱為原型屬性。

圖例解釋

   function Person() {}
   var p = new Person();

上面程式碼的過程中發生了什麼將用下圖表示

prototype作用

原型物件包含例項共享的方法和屬性,這個函式用作建構函式時呼叫,使用new操作符呼叫的時候,新建立的物件會從原型物件上得到同樣的屬性和方法。
如何理解,下面請出__proto__來解釋.

2.proto

proto:是一個物件擁有的內建屬性,是js內部使用尋找原型鏈的屬性,通過該屬性可以允許使用例項物件直接訪問原型。

**注意,prototype是函式的內建屬性,__proto__是物件的內建屬性**

    function Person() {}
    var p = new Person();
    // 以前不能直接使用 p直接訪問物件原型
    // 現在有了 __proto__ 後
    // p.__proto__ 也可以直接訪問物件原型
    // 那麼 p.__proto__ === Person.prototype

該如何檢視__proto__

同檢視prototype一樣,在chrome和FF中的開發者工具中檢視

proto 有什麼用?

  • 可以訪問原型
  • 由於在開發中除非特殊要求, 不要使用例項去修改原型的成員. 因此屬性開發時使用較少
  • 但是再除錯過程中非常方便, 可以輕易的訪問原型進行檢視成員

圖例解釋

3.constructor

講到這裡還缺少一個constructor

constructor:屬性返回對建立此物件的函式的引用。

新增的物件預設是沒有 constructor 屬性

constructor其實沒有什麼用處,只是JavaScript語言設計的歷史遺留物。
由於constructor屬性是可以變更的,所以未必真的指向物件的建構函式,只是一個提示。
不過,從程式設計習慣上,我們應該儘量讓物件的constructor指向其建構函式,以維持這個慣例。

圖例解釋

4總結

function Student(name,age){
  this.name=name;
  this.age=age;
}

Student.prototype={
  sayHellow:function(){
    console.log("你好")
  }
}

var p =new Student("張三",19);
p.sayHellow();

1.首先,預解析過程,宣告建構函式Student,同是建立Student的原型Student.prototype;

2.創建出一個新的原型物件,修改Student的原型指向,指向新的原型,新的原型中沒有constructor,舊的原型中的constructor依舊指向Student;
問題:為什麼不是覆蓋遠來的Student.prototype,下面程式碼可以論證;

 function Person(){};
    var p1=new Person();
    Person.prototype={
        sayHello:function(){
        console.log("你好");
       }
    }
 var p2=new Person();
 //p1還是擁有constructor,而p2的指向已經改變了並且擁有sayHello函式

3.使用new 建立建構函式的物件,然後將物件的引用交給建構函式的this.
4.在建構函式內部,利用物件的動態特效,給剛剛創建出的物件提供屬性

  • 建構函式在呼叫的時候傳入引數,"張三"和19
  • 然後給屬性賦值
  • 物件賦值完畢,然後將物件的引用賦值給p

5.執行呼叫方法p.sayHello

  • 首相p中沒有找到sayHello方法
  • 然後進入新的原型物件中檢視是否有sayHello方法
  • 找到就呼叫sayHello方法
  • 如果在原型中還未找到sayHello方法,會繼續在上層原型中查詢看是否有sayHello,如果都未查詢到會返回undefined,查詢到直接呼叫
  • 在方法中列印“你好”;
  • 方法呼叫結束

圖例解釋