javaScript中實例,類,原型等是js語言的核心概念,在充分理解並掌握的情況下,才能在編程中得心應手。近期進行知識歸類總結,對js中的實例,類,類的原型,實例的原型,類的prototype,實例的prototype進行一個總結。
核心概念:prototype指的是原型對象, __proto__指的是原型
看一個簡單的例子:
class a{
constructor(options){
console.log('options',options)
this.testThis()
}
ready(){
console.log('a的ready屬性')
}
testThis(){
this.ready()
}
}
class b extends a {
constructor(options){
super(options)
this.testExtendsThis()
}
testExtendsThis(){
console.log('testExtendsThis')
}
}
接下來分別創建實例A, 實例B,並獲取實例A的原型,實例B的原型,類a的protoype, 類b的prototype,a的原型,b的原型等,並進行比較。
const B = new b();
const A = new a();
const get_proto_a = Object.getPrototypeOf(a)
const get_proto_b = Object.getPrototypeOf(b)
const get_proto_B = Object.getPrototypeOf(B)
const get_proto_A = Object.getPrototypeOf(A)
const proto_a = a.prototype;
const proto_b = b.prototype;
const proto_A = A.prototype;
const proto_B = B.prototype;
const get_get_proto_b = Object.getPrototypeOf(get_proto_b);
const get_get_proto_B = Object.getPrototypeOf(get_proto_B)
進行比較:
//類的原型和類 得出 類的原型等於其繼承的類
console.log(get_proto_b === a)//true
//類的原型對象prototype和類的原型 二者沒有直接聯繫
console.log(_.isEqual(get_proto_a, a.prototype))//false 這裏判斷兩個對象不能直接使用===
//實例的原型 和實例 實例的原型指向實例
console.log(_.isEqual(get_proto_B , B))//true 這裏判斷兩個對象不能直接使用===
//實例的原型如果有繼承,再指向自身後,指向繼承類的實例
console.log(_.isEqual(get_get_proto_B , new a()))//true 這裏判斷兩個對象不能直接使用===
//實例的原型指向實例的構造函數的prototype
console.log(get_proto_A === A.constructor.prototype)//true
//實例的構造函數指向類
console.log(A.constructor.prototype === a.prototype)//true
//實例的原型的原型,指向其構造函數繼承類的實例
console.log(get_get_proto_B === get_proto_A)//true
//console.log(A.prototype)//實例默認沒有原型對象
總結:通過上面的代碼歸結出規律:
1,實例的原型指向實例(先指向自身),類的原型指向類
2,實例的原型指向實例的構造函數的prototype
3,實例的構造函數指向類
4,實例的原型對象默認不存在
5,實例不能被繼承
引申:
Class 作爲構造函數的語法糖,同時有prototype
屬性和__proto__
屬性,因此同時存在兩條繼承鏈。
(1)子類的__proto__
屬性,表示構造函數的繼承,總是指向父類。
(2)子類prototype
屬性的__proto__
屬性,表示方法的繼承,總是指向父類的prototype
屬性。
子類實例的__proto__
屬性的__proto__
屬性,指向父類實例的__proto__
屬性。也就是說,子類的原型的原型,是父類的原型。
參考:http://es6.ruanyifeng.com/#docs/class-extends#Object-getPrototypeOf