【修真院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.獲取函式和物件原型的區別是什麼。
本質上來說是沒有什麼區別的,因為你獲取函式原型的話就是一個物件,而物件又是由函式建立的,非要說區別的話可能就是,使用的方法不一樣了。