#類 以前就是建構函式
繼承
先宣告兩個類,並在父類上追加一個smock方法
function Parent() {
}
Parent.prototype.smock = function () {
console.log('吸菸');
}
function Child() {
}複製程式碼
然後讓Child的原型指向Parent的例項,這樣child例項上就有了Parent的方法了
function Parent() {
this.name = 'hahah'
}
Parent.prototype.smock = function () {
console.log('吸菸');
}
function Child() {
}
Child.prototype = new Parent;
let child = new Child;
child.smock()
}
Parent.prototype.smock = function () {
console.log('吸菸');
}
function Child() {}
Child.prototype = new Parent;
let child = new Child;child.smock()
複製程式碼
執行結果就是“吸菸”;
執行原理如圖所示:Child類分配一個原型空間prototype,每個prototype都有constrcutor區域,new Child得到的是一個child的例項,例項上有__proto__屬性,child.__proto__指向的就是Child.prototype;同理Parent也是這樣。現在
Child.prototype = new Parent;複製程式碼
我讓Child類上的prototype等於了new出的Parent例項,也就是parent(就是上面那條1藍色線),那麼child上就有了parent上面的公有屬性和私有屬性了,那麼執行child.smock()就是得到想要的結果了。
我們還可以驗證一下
console.log(child.__proto__.__proto__ == Parent.prototype);複製程式碼
驗證結果為true
我們也可以看一下constructor指向誰
console.log(child.constructor);複製程式碼
繼承Object.create
Object.create只繼承公有方法。
Child.prototype = Object.create(Parent.prototype);
let child = new Child;複製程式碼
但是child上面沒有name(私有屬性),但是有smock方法(公有)
怎麼實現的呢:
function create(pa) {
function Fn() { } //相當於構建一個類,類的原型指向父類的原型
Fn.prototype = pa;
return new Fn
}
//兒子查詢時,可以查詢到父類的原型,所以可以拿到父類的公有方法
Child.prototype = create(Parent.prototype);
let child = new Child;
child.smock()複製程式碼
流程圖如下:(黃色線部分:create的方法就是改變了Child的prototype的指向。)
而此時child的constructor是Parent,要是想讓它變回Child
function create(pa,paranm) {
function Fn() { } //相當於構建一個類,類的原型指向父類的原型
Fn.prototype = pa;
let fn = new Fn;
fn.constructor = param.constructor.value;
return fn
}
//兒子查詢時,可以查詢到父類的原型,所以可以拿到父類的公有方法
Child.prototype = create(Parent.prototype,{constructor:{value:Child}});
// Child.prototype = Object.create(Parent.prototype,{constructor:{value:Child}});
let child = new Child;複製程式碼
如果想繼承靜態屬性可以這樣做
Child.__proto__ = Parent複製程式碼
定義屬性
defineProperty
let obj = {};
Object.defineProperty(obj,'a',{
enumerable:true,//是否可列舉
configurable:true,//可配置
// writable:true,//是否可修改 但是不能跟get,set同在,否則會報錯
set(val){
console.log(val);
},
get(){
console.log(100)
},
// value:11
})
console.log(obj.a)複製程式碼
es6的繼承
extends能繼承私有屬性
class Parent{
constructor(name){
this.name = name
}
getnaem(){
return this.name
}
}
class Child extends Parent {
複製程式碼
constructor(name,age){
super(name)//子類有建構函式必須使用super 類似於call(this,name)
this.age = age
}複製程式碼
}let child = new Child('ww',9);console.log(child.name)
name 是可以拿到的,getname也能拿到(公有私有都能拿到)
靜態方法通過類來呼叫
class Parent{
constructor(name){
this.name = name
}
getname() {
return this.name
}
//通過類來繼承
static fu(){
return 100
}
}
Parent.fn()複製程式碼