Javascript擴(kuò)展對象extend實(shí)現(xiàn)

jQuery的$.extend方法是我們在開發(fā)中經(jīng)常用到的方法,用于合并若干個對象,且支持深度拷貝。

最常見的一個使用場景是參數(shù)的合并错负,比如我們要做一個顯示對話框的組件坟瓢,接收一個option對象參數(shù),把它和默認(rèn)參數(shù)defaultOption合并湿颅,得到新的參數(shù)载绿。這樣做的好處就是對option字段的拓展非常方便,并且使用者可以只傳部分參數(shù)油航,其他均為默認(rèn)值,代碼可讀性也比較好怀浆。

var showDialog = (function() {
     var defaultOption = {
        title:'',
        width:500,
        close:function(){}
    }
    return function(option) {
        $.extend({},defaultOption,option);
    }
})()

showDialog({
    title:'',
    close:function() {
      console.log('dialog closed')
    }
})

這種模式在很多地方都用到谊囚,最常見的我們使用$.ajax發(fā)起ajax請求,對于傳遞的option也是這樣處理的执赡。
在現(xiàn)在的項(xiàng)目中镰踏,由于用的是Vue,避免了繁瑣的Dom操作沙合,所以用不到j(luò)Query提供的dom操作奠伪。但是我需要$.extend方法。在查看了他的源碼之后首懈,本來打算直接copy過來使用绊率,可是發(fā)現(xiàn)它有很多依賴項(xiàng),懶得一一去找究履,所以索性自己從頭寫一個滤否。

我們可以考慮首先實(shí)現(xiàn)一個最簡單的extend函數(shù),即用for in遍歷源對象最仑,覆蓋目標(biāo)對象的對應(yīng)屬性即可藐俺。

var extend = function(destination,source) {
    for(var property in source) {
        destination[property] = source[property]
    }
    return destination
}

非常簡潔易懂,這種實(shí)現(xiàn)方式滿足了大部分情況下的需求泥彤,但存在一個問題欲芹,就是這種合并是淺拷貝。
如果合并的屬性中含有對象a吟吝,那么在進(jìn)行合并之后菱父,destination擁有的是對象a的引用,而source對象也有對象a的引用爸黄,那么如果我們修改對象a的屬性滞伟,destinationsource都將被修改——它們引用的是同一個對象,這就是淺拷貝炕贵。我們想實(shí)現(xiàn)深拷貝梆奈,即在destination中的對象a是一份復(fù)制品,而不是引用称开,那么我們需要對對象的賦值做額外的判斷和處理亩钟。

var isObjFunc = function(name) {
    var toString = Object.prototype.toString
    return function() {
        return toString.call(arguments[0]) === '[object ' + name + ']'
    } 
}
var isObject = isObjFunc('Object'),
var extend = function(destination,source,isDeep) {
    var obj,copy
    for(var property in source) {
        obj = source[property]
        if(isDeep && isObject(obj) { // 判斷是深拷貝且這個屬性是純對象
            var copy = {}
            destination[property] = extend(copy,obj,isDeep) // 遞歸調(diào)用乓梨,創(chuàng)建一份obj的拷貝,賦值給destination
        } else {
            destination[property] = obj
        }
    }
    return destination
}

上面的代碼就實(shí)現(xiàn)了一個簡單深拷貝清酥。但這里還有一個漏洞扶镀,如果是數(shù)組的話,創(chuàng)建copy的時候應(yīng)該設(shè)置為一個新的空數(shù)組焰轻,這樣for in操作擴(kuò)展才能正常執(zhí)行臭觉。再參考jQuery.extend的實(shí)現(xiàn)方式,利用arguments處理多個對象合并的情況辱志,最終的代碼如下蝠筑,較為完整的實(shí)現(xiàn)了extend,供參考揩懒。如果有bug歡迎留言指正什乙。

var extend = (function() {
    var isObjFunc = function(name) {
        var toString = Object.prototype.toString
        return function() {
            return toString.call(arguments[0]) === '[object ' + name + ']'
        } 
    }
    var   isObject = isObjFunc('Object'),
        isArray = isObjFunc('Array'),
        isBoolean = isObjFunc('Boolean')
    return function extend() {
        var index = 0,isDeep = false,obj,copy,destination,source,i
        if(isBoolean(arguments[0])) {
            index = 1
            isDeep = arguments[0]
        }
        for(i = arguments.length - 1;i>index;i--) {
            destination = arguments[i - 1]
            source = arguments[i]
            if(isObject(source) || isArray(source)) {
                console.log(source)
                for(var property in source) {
                    obj = source[property]
                    if(isDeep && ( isObject(obj) || isArray(obj) ) ) {
                        copy = isObject(obj) ? {} : []
                        var extended = extend(isDeep,copy,obj)
                        destination[property] = extended 
                    }else {
                        destination[property] = source[property]
                    }
                }
            } else {
                destination = source
            }
        }
        return destination
    }
})()

測試代碼如下

var a = {name:1}
var b = {name:2}
var c = {name:3}
extend(true,a,b,{name:[a,b,c],value:a})
console.log(a)
console.log(a.name[0] === a) // false
console.log(a.value === a) // false
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市已球,隨后出現(xiàn)的幾起案子臣镣,更是在濱河造成了極大的恐慌,老刑警劉巖智亮,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忆某,死亡現(xiàn)場離奇詭異,居然都是意外死亡鸽素,警方通過查閱死者的電腦和手機(jī)褒繁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來馍忽,“玉大人棒坏,你說我怎么就攤上這事≡馑瘢” “怎么了坝冕?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長瓦呼。 經(jīng)常有香客問我喂窟,道長,這世上最難降的妖魔是什么央串? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任磨澡,我火速辦了婚禮,結(jié)果婚禮上质和,老公的妹妹穿的比我還像新娘稳摄。我一直安慰自己,他們只是感情好饲宿,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布厦酬。 她就那樣靜靜地躺著胆描,像睡著了一般。 火紅的嫁衣襯著肌膚如雪仗阅。 梳的紋絲不亂的頭發(fā)上昌讲,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機(jī)與錄音减噪,去河邊找鬼短绸。 笑死,一個胖子當(dāng)著我的面吹牛旋廷,可吹牛的內(nèi)容都是我干的鸠按。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼饶碘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了馒吴?” 一聲冷哼從身側(cè)響起扎运,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎饮戳,沒想到半個月后豪治,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡扯罐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年负拟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歹河。...
    茶點(diǎn)故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡掩浙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出秸歧,到底是詐尸還是另有隱情厨姚,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布键菱,位于F島的核電站谬墙,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏经备。R本人自食惡果不足惜拭抬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望侵蒙。 院中可真熱鬧造虎,春花似錦、人聲如沸蘑志。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至澎媒,卻和暖如春搞乏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背戒努。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工请敦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人储玫。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓侍筛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親撒穷。 傳聞我的和親對象是個殘疾皇子匣椰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 在線閱讀 http://interview.poetries.top[http://interview.poetr...
    程序員poetry閱讀 114,359評論 24 450
  • 函數(shù)和對象 1、函數(shù) 1.1 函數(shù)概述 函數(shù)對于任何一門語言來說都是核心的概念端礼。通過函數(shù)可以封裝任意多條語句禽笑,而且...
    道無虛閱讀 4,556評論 0 5
  • ALTRun Windows快速啟動工具,靈活自主配置快捷鍵快速啟動電腦上各類軟件的小工具蛤奥。簡單易用佳镜,智能匹配,你...
    cd2016閱讀 790評論 0 0
  • 靜態(tài)庫 VS 動態(tài)庫 靜態(tài)庫:靜態(tài)庫在Objective-C里面以.a或者.framework作為后綴凡桥,目前開發(fā)者...
    王君爵閱讀 1,288評論 0 0
  • 女人的江山之十七 文|綠茉兒 看見蘭茉進(jìn)來了蟀伸,他們都收起了笑聲。 蘭陵過來招呼說:“茉茉缅刽,你終于來了啊掏,我們正念叨你...
    陜北一姐閱讀 168評論 0 0