JavaScript的閉包、繼承和多態(tài)筆記


閉包

函數(shù)對象可以通過作用域鏈相互關(guān)聯(lián),函數(shù)體內(nèi)部的變量都可以保存在函數(shù)作用域內(nèi),這種特性稱之為“閉包”。
當(dāng)一個函數(shù)嵌套了另外一個函數(shù),外部函數(shù)將嵌套的函數(shù)對象作為返回值返回的時候,我們會發(fā)現(xiàn)函數(shù)定義時的作用域鏈(函數(shù)內(nèi)的變量)到函數(shù)執(zhí)行時依然有效(被調(diào)用)。

閉包典型應(yīng)用實例:簡單計數(shù)器

需求: 簡單計數(shù)器。計數(shù)器對象counter,屬性add、subtract、reset。調(diào)用add(),計數(shù)器+1;調(diào)用substract(),計數(shù)器-1;調(diào)用reset(),計數(shù)器歸零

//實例代碼1
function counter(){
    var result = 0 ;
    return{
        add: function(){ return result++; },
        subtract: function(){ return result--; },
        reset: function(){ return result=0; }
    };
}
var counter1 = counter(), counter2 = counter();
counter1.add()                \\ => 0
counter2.add()                \\ => 0
counter1.add()                 \\ => 1
counter1.reset()               \\ => 0
//以上感覺沒有問題。
counter1.reset()               \\0
counter1.subtract()          \\0
counter1.add()                \\-1
counter1.add()                \\0
//以上輸出就很奇怪了,為什么在第一次subtract是0,后調(diào)用add,結(jié)果為-1?
實例代碼2
function counter(){
    var result = 0;
    var func ={};
    func.add = function(){
        result++;
        return result;
    };
    func.subtract= function(){
        result--;
        return result;
    };
    func.reset= function(){
        result=0;
        return result;
    };
    return func;
}
//result是一個函數(shù)內(nèi)的局部變量,但是卻起到了全局變量的效果,并且不會相互影響??梢詼p少代碼之前的相互干擾,減少耦合性。
var counter1 = counter(), counter2 = counter();
counter1.reset()               \\0
counter1.subtract()          \\-1
counter1.add()                \\0
counter1.add()                \\1
//輸出正常,^ . ^

繼承

以前學(xué)習(xí)java中有類和實例的概念。在JavaScript中,不區(qū)分類和實例的概念,而是通過原型(prototype)來實現(xiàn)面向?qū)ο缶幊獭?br> 原型繼承:
比如,創(chuàng)建一個Array對象
var arr = [ 1, 2, 3 ];
其原型鏈?zhǔn)牵?br> arr ----> Array.prototype ----> Object.prototype ----> null
因此Array.prototype定義了indexOf()、shift()等方法,因此可以再Array對象上直接調(diào)用這些方法。
實例:

//父類  人,具有屬性 名字和介紹自己的方法。
function person(name){
    this.name = name;                                      //必須使用this進行綁定
    this.hello = function(){
        alert("Hello, I'm "+this.name+".");
    };
}
//小明對象,繼承人的屬性和方法。
var xiaoming = new person("小明");      //必須有new關(guān)鍵詞,變成構(gòu)造函數(shù)
xiaoming.name;
xiaoming.hello();

父類還可以寫成這樣:

function person(objname){
    this.name = objname || "Unnamed";
}
 person.prototype.hello()= function(){
    alert("Hello, I'm "+this.name+".");
 }

在ES6以后,新的關(guān)鍵詞class可以定義類了。

class person{
    constructor(name) {                               //包含了構(gòu)造函數(shù)constructor
        this.name = name;
    }

    hello() {                                                  //沒有function關(guān)鍵詞
        alert('Hello, ' + this.name + '!');
    }
}

同時繼承更加的方便,可以直接采用extends關(guān)鍵詞實現(xiàn)

class seniorPerson  extends person{
    constructor(name,sex){
        super(name);
        this.sex = sex;
    }
    
    mySex(){
        alert('I am a'+this.sex+'.');
    }
}

多態(tài)

在學(xué)習(xí)java的時候,多態(tài)實際上是重載(Reload)或者重寫(Rewrite)。

  • 重載:多個方法,方法名相同,參數(shù)的個數(shù)或者參數(shù)的類型不一樣。
  • 重寫:子類重寫父類的方法。

在JavaScript中如果函數(shù)名相同,后面的會把前面的函數(shù)覆蓋掉,因此不存在重載。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容