1. 程式人生 > >【修真院web小課堂】原型

【修真院web小課堂】原型

1.背景介紹

 JavaScript 中,萬物皆物件。

 JavaScript根據"原型鏈"(prototype chain)模式,來實現繼承。

2.知識剖析

2.1 物件

JavaScript中,物件是有區別的,分為普通物件和函式物件,Object ,Function 是JS自帶的函式物件,function定義方式本質上還是new Function方式。

function  f1(){};
var f2 = function(){};
var f3 = new Function('str','console.log(str)');
var o3 = new f1();
var o1 = {};
var o2 =new Object();


console.log(typeof  Object);  //function
console.log(typeof  Function);  //function
console.log(typeof o1);   //object
console.log(typeof o2);   //object
console.log(typeof o3);   //object
console.log(typeof  f1);   //function
console.log(typeof  f2);   //function

console.log(typeof  f3);   //function

2.2 物件繼承

Brendan Eich參考C++和Java,做了簡化設計,將new命令引入JavaScript中,new後面跟物件的建構函式,用來建立物件。這樣做有個缺點:無法共享方法和屬性。

比如,在DOG物件的建構函式中,設定一個例項物件的共有屬性species。
  function DOG(name){
    this.name = name;
    this.species = '犬科';
  }


然後,生成兩個例項物件:
  var dogA = new DOG('大毛');
  var dogB = new DOG('二毛');


這兩個物件的species屬性是獨立的,修改其中一個,不會影響到另一個。
  dogA.species = '貓科';
  alert(dogB.species); // 顯示"犬科",不受dogA的影響


每一個例項物件,都有自己的屬性和方法的副本。這不僅無法做到資料共享,也是極大的資源浪費。

 Brendan Eich決定為建構函式設定一個prototype屬性。這個屬性包含一個物件,所有例項物件需要共享的屬性和方法,都放在這個物件裡面;那些不需要共享的屬性和方法,就放在建構函式裡面。例項物件一旦建立,將自動引用prototype物件的屬性和方法。也就是說,例項物件的屬性和方法,分成兩種,一種是本地的,另一種是引用的。

3.常見問題

訪問物件原型的方法有哪些?

4.解決方案

獲取例項物件obj的原型物件,有三種方法
                    1. obj.__proto__
                    2. obj.constructor.prototype
                    3. Object.getPrototypeOf(obj)

                    上面三種方法之中,前兩種都不是很可靠。最新的ES6標準規定,__proto__屬性只有瀏覽器才需要部署,其他環境可以不部署。而obj.constructor.prototype在手動改變原型物件時,可能會失效。

5.編碼實戰

6.拓展思考

 1.Object.__proto__ === Function.prototype // true


                    2.Function.__proto__ === Function.prototype // true


                    3.Function.prototype.__proto__ === Object.prototype //true

7.提問

1.函式是怎麼來的,物件又是怎麼來的。

函式包含在物件內,也是一種物件,而物件是由函式建立的,函式也是由函式建立的餓。

2.函式和物件最終都指向誰。

函式也是一種物件,物件也是物件,而物件是由函式建立的,最終的指向都是null

3.獲取函式和物件原型的區別是什麼。

本質上來說是沒有什麼區別的,因為你獲取函式原型的話就是一個物件,而物件又是由函式建立的,非要說區別的話可能就是,使用的方法不一樣了。