js的面向對象總結

之前看過js高程3,但又有些忘計了,想想我以前寫的js代碼全是過程化,確實要換一種編程風格了。
大多數編程語言如php,java,c#,ts的面向對象都是

類->實例

但js卻不是這樣,js不區分類和實例,或者可以說js沒有這種類的這種概念,只是通過原型來模擬一種面向對象編程。
在通過原型實現面向對象之前,要了解一個屬性,_proto__,所有對象都會在其內部初始化一個屬性,就是proto,當我們訪問一個對象的屬性時,如果這個對象內部不存在這個屬性,那麼他就會去proto裏找這個屬性,當然proto本身也一個對象 ,所有如果屬性還找到就會繼續找,直到找到object對象。
一、直接確定proto屬性

var Person={
    name:'zcj',
    height:1.2,
    code:function(){
        console.log(this.name+"is code js");
    }
}
var zcj={
    name:'zcj'
}
zcj.__proto__=Person;
zcj.code()

上例代碼原型鏈如下,具體也可以想像成zcj.code屬性查找鏈條(根據這個規則一級一級往上找直到找到object這就叫原型鏈)。

zcj->zcj.__proto__(Person)->Person.__proto__(Object.prototype)->Object.prototype.__proto__(null)

驗證一下

//結果爲null
console.log(zcj.__proto__.__proto__.__proto__)

首先來看一張原型神圖
首先來看一張原型神圖
二、通過new關鍵字來確定proto屬性
不寫new,這就是一個普通函數,它返回undefined。但是,如果寫了new,返回當前方法體內的this,也就是說,不需要在最後寫return this,並且這個this的proto屬性指向的是構造函數的prototype屬性,
1.不寫return返回的是Person函數體內的this,寫了return返回return之前的this,如下所示加了return返回的this少了hello屬性

function Person(name){
    this.name=name;
    this.obj={};
    //return 'hhhh'
    this.hello=function(){
        console.log('Hello,'+this.name+'!') 
    }
}
var zcj=new Person('zcj');
console.log(zcj);
console.log(zjc.__proto__);

最好把屬性和方法放到Person.prototype中,如果我們通過new Person()創建了很多對象,這些對象的hello函數實際上只需要共享同一個函數就可以了,這樣可以節省很多內存。

function Person(name){
    this.name=name;
    this.obj={};
    //return 'hhhh'
}
Person.prototype.hello=function(){
    console.log('Hello,'+this.name+'!') 
}
var zcj=new Person('zcj');
console.log(zcj);

利用js的原型來實現類的繼承特性

function Student(proto){
    this.name=proto.name||'unNamed';
}
function PrimaryStudent(proto){
    //調用student函數把被調用函數的this等於調用函數體的this
    Student.call(this,proto)
    this.grade=proto.grade||1;
}
function F(){

}
F.prototype=Student.prototype;
PrimaryStudent.prototype=new F();
//強加一個constuctor屬性指向primarystudent
PrimaryStudent.prototype.constructor=PrimaryStudent
PrimaryStudent.prototype.getGride=function(){
    return this.grade;
}
var zcj=new PrimaryStudent({
    name:'小明',
    grade:2
});
console.log(zcj)

zcj對象的原型鏈

zcj.__proto__(Primarystudent.prototype)->Primarystudent.prototype.__proto__(F.prototype(Student.prototype))->F.prototype(Student.prototype).__proto__->Object.prototype.__proto->null

嗯,很麻煩是吧,好了大神都知道了,es6己經支持class關鍵字了啊,利用es6的class來實現,ES6引入的class和原有的JavaScript原型繼承有什麼區別呢?實際上它們沒有任何區別,class的作用就是讓JavaScript引擎去實現原來需要我們自己編寫的原型鏈代碼。簡而言之,用class的好處就是極大地簡化了原型鏈代碼,google是支持的,其他瀏覽器不支持的話就可以用一些編譯工具,如babel

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章