前言
以前覺得原型,原型鏈,構造就是后端的繼承,后來發(fā)現(xiàn)這種想法是十分粗陋的,所以這次打算好好梳理下他們三者的關系。
首先我們先名詞解釋下:
1.原型(對象原型):
# 每個函數(shù)都有對象原型(prototype)
let tiger= function (kind, color ) {
this.kind= kind;
this.color = color ;
};
# 實例對象是沒prototype的
let oneTiger = new tiger("東北虎", "白色");
# undefined
oneTiger.prototype;
#函數(shù)是有的,{constructor: ?}
tiger.prototype
#繼承頂級function年齡屬性
Function.prototype.age = 26;
# undefined
tiger.age;
#繼承頂級對象出生屬性
Object.prototype.birth = 1993;
oneTiger.birth;
從上面的可以看出,定義在函數(shù)上的屬性實例化后就沒了;對象則一直存在。這邊就涉及到一個難點了,函數(shù)屬性到底干啥了?
2.構造(constructor):
后端可能一眼就看出來了,這個是類的構造函數(shù),在js里最初沒有類,所以這邊我們叫他構造器(等于后端的構造函數(shù))。這個構造器專門為function而設計的,這個構造器指向function的引用。
function Person() {
}
var p = new Person()
console.log(Person.prototype); // Object{}
console.log(p.prototype); // undifined
console.log(p.constructor); //function Person(){}
此處的p是通過 Person函數(shù)構造出來的,所以p的constructor屬性指向Person
console.log(Person.constructor); //function Function(){}
之前提過,每個函數(shù)其實是通過new Function()構造的
console.log({}.constructor); // function Object(){}
每個對象都是通過new Object()構造的
console.log(Object.constructor); // function Function() {}
Object也是一個函數(shù),它是Function()構造的
console.log([].constructor); //function Array(){}
從上面可以看出,對象也是函數(shù)創(chuàng)建的!
3.原型鏈(繼承)
實例對象與原型之間的連接(繼承),就叫原型鏈(原型繼承)。proto(隱式連接)
proto是個內置屬性,指向了它的構造函數(shù)原型。這句話什么意思?
# 執(zhí)行下這個就能發(fā)現(xiàn),
tiger.__proto__ === Object.prototype;
總結
在對象原型上定義屬性,構造器指向函數(shù)的引用(多用于修正原型指向),最后通過原型鏈隱式將他們串了起來。簡單的將就是可以通過在prototype上定義公共屬性給實例函數(shù)使用,與后端繼承十分相似。