亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

JS學習筆記 - 代碼復用

cheng10 / 2689人閱讀

摘要:本文章記錄本人在學習中看書理解到的一些東西,加深記憶和并且整理記錄下來,方便之后的復習。但是在開發(fā)的過程中,并不是所有的代碼復用都會使用到繼承。而且整個代碼都無法按照預期來運行。為了修復綁定對象與方法之間的關(guān)系。

  

本文章記錄本人在學習 JavaScript 中看書理解到的一些東西,加深記憶和并且整理記錄下來,方便之后的復習。

js 中復用代碼

說道代碼復用,一般都會涉及到對象繼承。在js中有許多可以選擇的繼承方法。這些方法對于學習和理解多種不同的模式有很大的好處,因為它們有助于提供對語言的掌握程度。

但是在開發(fā)的過程中,并不是所有的代碼復用都會使用到繼承。其中一部原因在于,事實上使用的js庫可能以這樣的或那樣的方式解決了該問題。而另一方面的原因就在于很少需要在js中建立長而且復雜的繼承鏈。在靜態(tài)強類型語言中,繼承可以能是唯一復用代碼的方法。在js中,經(jīng)常有更加簡潔而且優(yōu)美的方法。包括:借用方法、綁定、復制屬性以及從多個對象中混入屬性等許多方法。

混入

混入是針對通過屬性復制實現(xiàn)繼承的思想做進一步的擴展,mix-in模式并不是復制一個完整的對象,而是從多個對象中復制出任意的成員并將這些成員組合成新的對象。

實現(xiàn)mix-in

function mix() {
    var arg, prop, child = {};
    for (arg = 0; arg < arguments.length; arg += 1) {
        for (prop in arguments[arg]) {
            if (arguments[arg].hasOwnProperty(prop)) {
                child[prop] = arguemnts[arg][prop];
            }
        }
    }
    return child;
}

mix-in實現(xiàn)非常簡單,只需要遍歷每個參數(shù),并且復制出傳遞給該函數(shù)的每個對象中的每個屬性。

借用方法

有的時候,我們只需要對象中的一兩個方法,但是又不想和對象形成父-子繼承關(guān)系。只是想是用所需要的方法,而不希望繼承所有那些永遠用不到的屬性和方法。在這種情況下,可以通過使用借用方法模式來實現(xiàn)。

而這個方法是受益于call()apply()的。js中函數(shù)也是對象,并且它們自身也存在一些屬性和方法,比如callapply()。

使用call()apply()分別借用方法:

// call
notmyobj.doStuff.call(myobj, param1, p2, p3);

// apply
notmyobj.doStuff.apply(myobj, [param1, p2, p3]);

在知道notmyobj對象上有doStuff方法的情況下,又想不繼承notmyobj來使用doStuff方法。這個使用call()apply()就派上用場了。

還有一個場景是經(jīng)常使用到借用方法的。那就是借用數(shù)組方法。因為數(shù)據(jù)具有許多很強大的方法,而且有時候需要操作arguments的時候會用上。但是arguments是一個偽數(shù)組,不具有原生數(shù)組強大的方法。這個使用借用方法就派上用場了:

function f() {
    var args = [].slice.call(arguemnts, 1, 3);
    return args;
}
借用和綁定

考慮到借用方法不是通過調(diào)用callapply()就是通過簡單的復制,在借用方法的內(nèi)部,this所指向的對象是基于調(diào)用表達式而確定的,但是有的時候“鎖定”this的值,或者將其綁定到特定的對象并且預先確定該對象。

舉一栗子:

var one = {
    name: "object",
    say: function (greet) {
        return greet + ", " + this.name;
    }
};

// 測試
one.say("hi"); // hi, object

接著另一對象two中沒有say()方法,借用onesay()方法:

var two = {
    name: "another object"
}
// 測試
one.say.call(two, "hi"); // hi, another object

在上面的例子中,借用的say()方法的this是指向two的。但是在什么樣的場景中,應該將函數(shù)指針賦值給一個全局變量,或者將該函數(shù)做為回調(diào)函數(shù)來傳遞?在客戶端編程中有許多事件和回調(diào),因此確實發(fā)生了許多這樣混淆的事件。

舉一個栗子:

// 給變量賦值
// this 將指向全局變量
var say = one.say;
say("hello") // hello, undefined

// 作為回調(diào)傳遞
var yetanother = {
    name: "yet another object",
    method: function (callback) {
        return callback("hola");
    }
};

// 測試
yetanother.method(one.say) // holla, undefined

在上面的兩種情況下,say()方法的this值都是指向全局對象。而且整個代碼都無法按照預期來運行。為了修復(綁定)對象與方法之間的關(guān)系??梢允褂靡粋€簡單的函數(shù)來實現(xiàn):

function bind(o, m) {
    return function () {
        return m.apply(o, [].slice.call(arguments))
    }

上面的bind()方法接受兩個參數(shù)。一個是對象o,另一個是方法m,并將兩者綁定起來。然后返回一個函數(shù)。

使用bind()來解決問題:

var twosay = bind(two, one.say);
twosay("yo"); // yo another object
  

奢侈的擁有綁定所需要輔助的代價就是額外的閉包的開銷。

ES5 bind()

ECMAScript5中給Function.protoype添加了一個bind()方法,使得bind()call()、apply()一樣簡單易用。

但是在不支持ECMAScript5的運行環(huán)境下,我們可以自己實現(xiàn)一個bind()方法(來自 MDN):

if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5 internal IsCallable function
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var aArgs = Array.prototype.slice.call(arguments, 1), 
        fToBind = this, 
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP && oThis
                                 ? this
                                 : oThis || window,
                               aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}

然后使用自帶的bind()方法來重寫一下上面的栗子:

var twosay = bind(two, one.say);
twosay("Bonjour"); // yo another object
  

最后,如果文章有什么錯誤和疑問的地方,請指出。與sf各位共勉!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/85800.html

相關(guān)文章

  • React學習筆記—組件復用

    摘要:屬性校驗隨著應用的增長,確保你的組件正確使用是有必要的?;烊朐诋斨?,組件復用能夠減少我們的代碼量。官方舉例說明的一種情況一個組件,每隔一段時間更新一次。提供了組件生命周期的方法告訴我們組件什么時候被創(chuàng)建和銷毀。 當我們在設(shè)計接口的時候,將一些常見的設(shè)計元素(如按鈕、表單、布局等)拆分成有著良好接口的可重用的組件。這樣的話,下次你構(gòu)建UI的時候只要寫少量的代碼。 屬性校驗 隨著應用的...

    CastlePeaK 評論0 收藏0
  • angularjs學習筆記——使用requirejs動態(tài)注入控制器

    摘要:最近一段時間在學習,由于覺得直接使用它需要加載很多的文件,因此想使用來實現(xiàn)異步加載,并動態(tài)注入控制器。手動啟動,特別說明此處的不是那個框架,而是的一個手動啟動框架的函數(shù)中完成了各模塊的初始化,并且引入了。 最近一段時間在學習angularjs,由于覺得直接使用它需要加載很多的js文件,因此想使用requirejs來實現(xiàn)異步加載,并動態(tài)注入控制器。簡單搜索了下發(fā)現(xiàn)好多教程寫的都很復雜,所...

    王軍 評論0 收藏0
  • CSS Variables學習筆記

    摘要:注本文首發(fā)于個人博客學習筆記。最近看了下變量,又名自定義屬性,跟大家分享一下我的學習筆記。使用自定義屬性來設(shè)置變量名,并使用特定的來訪問。二學習筆記聲明調(diào)用聲明方式變量聲明的方式非常簡單,如下,聲明了一個名叫的變量。 注:本文首發(fā)于個人博客 《CSS Variables學習筆記》。 最近看了下CSS Variables(CSS變量,又名CSS自定義屬性),跟大家分享一下我的學習筆記。 ...

    mudiyouyou 評論0 收藏0
  • Vue.js 初接觸

    摘要:二還有一點也是思想不容易轉(zhuǎn)過彎的一點,就是我在學習前端時,接觸的思想都是需要我們將者分開,方便維護。但是在學習了接觸了單文件組件之后,世界又變了,又讓我們將同一個組件的放到一個文件中,這樣又便于維護和復用,這一臉的懵那啥。 Vue.js 介紹 官方介紹: Vue.js是一套構(gòu)建用戶界面的漸進式框架。與其他重量級框架不同的是,Vue 采用自底向上增量開發(fā)的設(shè)計。Vue 的核心庫只關(guān)注視圖...

    bladefury 評論0 收藏0
  • vue.js學習和實戰(zhàn)筆記

    摘要:第二個是其值是或,確認是否深入監(jiān)聽。一般監(jiān)聽時是不能監(jiān)聽到對象屬性值的變化的,數(shù)組的值變化可以聽到第三個是其值是或,確認是否以當前的初始值執(zhí)行的函數(shù)?;旌隙x來分發(fā)組件中的可復用功能結(jié)束,撒花文章已同步我的筆記,歡迎大家加,加后人生更加美好 vue.js記錄 文章已同步我的github筆記https://github.com/ymblog/blog,歡迎大家加star~~,加star后...

    Pandaaa 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<