javascript繼承

javascript是一門比較難精通的語言,緣由是其餘語言提供機制,javascript提供方法。
在我看來,語言如java,python比較好學的語言有一個特色:關鍵字多。java提供extends,implements,以及特定的包管理機制。python特殊的文本結構,大量API等。這些語言可使初學者快速上手,由於大多數需求的知足都是靠機制。語言提供的關鍵字,庫管理,API。一句話就是你們寫的代碼都同樣,思路同樣,代碼就同樣(或差異不大,由於設計模式的存在,有結構差別,但底層結構也相同)。
另外一種語言提供做用域,內存佈局,語言自己的默認設置等。這種語言如c,c++,javascript,函數式語言。自己是帶有一種編譯器或解釋器的感受。就是用戶身在其中,須要知道一些編譯器開發人員才須要的知識。就以javascript來講吧,要想實現繼承,你就得了解解釋器在讀取一個對象的屬性的過程當中是怎麼尋找的(原型鏈)。c語言:宏,你得了解預處理器;全局變量,鏈接器;C++:struct和class的區別,vptr,多繼承等。
說這麼多,只是想爲本身花了半年學javascript的痛苦吐槽一下,並無比較語言的意思,莫噴!java那種思路一下,代碼差異不大的優點在企業級開發中才能體現,so i love java!絕沒有瞧不起的意思。javascript

繼承是什麼

以java爲例:java

class Parent{python

String name; //private field
Parent(String name){
    this.name = name;
}

}c++

class Child{設計模式

int id;  //private field
Child(String name,int id){
    super(name);
    this.id = id;
}

}函數

繼承的重點:佈局

1.Child實例化以前,Parent必須實例化
2.Child對象可使用Parent對象的方法和屬性
3.Child能夠添加本身的方法,若是方法名相同,則覆蓋Parent的方法
4.Child能夠添加本身的靜態方法,能夠繼承Parent的父類方法this

簡單繼承

這也是網上比較多的繼承方法(類式繼承):prototype

function Parent () {
    this.ParentValue = true;  //private field
}

Parent.staticP = 1;

Parent.prototype.getValue = function () {
    return this.ParentValue;
}

function Child () {
    this.ChildValue = true;  //private field
}

Child.prototype = new Parent();

Child.prototype.getValue = function () {
    return this.ChildValue;
}

Child.staticC = 1;

這種方式不能知足上面的4個條件:
1.知足,可是不是徹底相同。Parent在Child定義時就已經實例化了,Parent實例化太超前了,致使全部Child對象同享一個Parent實例,若是一個Child對象改變了Parentvalue,全部Child對象都發生改變。
2.知足
3.知足
4.不知足
因此說基本知足2.5條吧設計

知足條件的繼承

function Parent () {
    this.ParentValue = true;  //private field
}

Parent.staticP = 1;

Parent.prototype.getValue = function () {
    return this.ParentValue;
}

function Child (p,c) {
    Parent.call(this,p);
    this.ChildValue = c;  //private field
}

Child.staticC = 1;
inheritPrototype(Parent,Child);


Child.prototype.getValue = function () {
    return this.ChildValue;
}


function inheritPrototype (Parent,Child) {
    merge(Parent,Child); //將Parent上的屬性放置到Parent上
    var p = inheritObject(Parent.prototype);
    p.constructor = Child;
    return p;
}

function inheritObject (o) {
    function F(){}
    F.prototype = o;
    return new F();
}

//將Parent上的屬性放置到Parent上
function merge (dist,source) {
    for(attr in source){
        if(source.hasOwnProperty(attr)){
            if(!dist.hasOwnProperty(attr)){
                dist[attr] = source[attr];
            }
        }
    }
}

更好的寫法

我參考Backbone的實現
Backbone依賴Underscore

function Parent () {
    this.ParentValue = true;  //private field
}
Parent.staticP = 1;


function Child (p,c) {
    Parent.call(this,p);
    this.ChildValue = c;  //private field
}


function extend(Parent,Child,protoProps,staticProps){
    _.extend(Child, Parent, staticProps);

    Child.prototype = _.create(Parent.prototype, protoProps);
    Child.prototype.constructor = Child;

    return Child;
}

extend(Parent,Child,{
    getValue: function() {
        return this.ParentValue;
    }
}, {    
    staticC: 1
});
是否是更方便呢!
相關文章
相關標籤/搜索