成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

原生javascript實(shí)現(xiàn)extend

Steve_Wang_ / 3404人閱讀

摘要:使用會(huì)遍歷所有的可枚舉屬性,包括原型。所以需要判斷一下,是否是對(duì)象自身的屬性,而不是繼承于原型的。注意,會(huì)跳過那些值為或的源對(duì)象。

代碼
var obj1 = {"a": "obj2","b":"2"};
var obj2 = {name: "obj3"};
function extend() {
    var length = arguments.length;
    var target = arguments[0] || {};
    if (typeof target!="object" && typeof target != "function") {
        target = {};
    }
    if (length == 1) {
        target = this;
        i--;
    }
    for (var i = 1; i < length; i++) { 
        var source = arguments[i]; 
        for (var key in source) { 
            // 使用for in會(huì)遍歷數(shù)組所有的可枚舉屬性,包括原型。
            if (Object.prototype.hasOwnProperty.call(source, key)) { 
                target[key] = source[key]; 
            } 
        } 
    }
    return target; 
}
console.log(extend(obj1,obj2));

extend 要實(shí)現(xiàn)的是給任意對(duì)象擴(kuò)展
分析一下

在extend()函數(shù)中沒有寫死參數(shù),是為了更好的擴(kuò)展性,永遠(yuǎn)也不知道需要擴(kuò)展的對(duì)象有幾個(gè)。
而是通過arguments來獲取傳進(jìn)來的參數(shù)。

arguments對(duì)象不是一個(gè) Array 。它類似于Array,但除了length屬性和索引元素之外沒有任何Array屬性。
// 可以轉(zhuǎn)換為數(shù)組 ES2015
const args = Array.from(arguments);

console.log(typeof arguments); // "object"
target

target是傳進(jìn)來的第一個(gè)參數(shù),也就是需要擴(kuò)展的對(duì)象。

var target = arguments[0] || {}; // 如果沒有傳參,則設(shè)為一個(gè)空對(duì)象

// 進(jìn)行這一步判斷是為了保證代碼的可執(zhí)行性,如果傳進(jìn)來的是個(gè)數(shù)字、布爾值,則設(shè)為一個(gè)空對(duì)象
if (typeof target!="object" && typeof target != "function") {
    target = {};
}
循環(huán)遍歷賦值
for (var i = 1; i < length; i++) { 
    var source = arguments[i]; 
    for (var key in source) { 
        // 使用for in會(huì)遍歷數(shù)組所有的可枚舉屬性,包括原型。
        if (Object.prototype.hasOwnProperty.call(source, key)) { 
            target[key] = source[key]; 
        } 
    } 
}

這一步就是將擴(kuò)展源里的屬性、方法循環(huán)遍歷賦值到擴(kuò)展項(xiàng)中。

如果擴(kuò)展項(xiàng)和擴(kuò)展源中有相同的屬性、方法,后面的會(huì)覆蓋前面的。 這個(gè)思想也是插件開發(fā)中,實(shí)現(xiàn)用戶配置覆蓋默認(rèn)設(shè)置的實(shí)現(xiàn)思想。
hasOwnProperty

為什么需要使用hasOwnProperty,這跟for in有密切關(guān)系。

使用for in會(huì)遍歷所有的可枚舉屬性,包括原型。

所以需要判斷一下,是否是對(duì)象自身的屬性,而不是繼承于原型的。

那為什么不直接使用source.hasOwnProperty(source[key])呢?

JavaScript 并沒有保護(hù) hasOwnProperty 屬性名,因此某個(gè)對(duì)象是有可能存在使用這個(gè)屬性名的屬性,使用外部的 hasOwnProperty 獲得正確的結(jié)果是需要的:

var foo = {
    hasOwnProperty: function() {
        return false;
    },
    bar: "Here be dragons"
};

foo.hasOwnProperty("bar"); // 始終返回 false

// 如果擔(dān)心這種情況,可以直接使用原型鏈上真正的 hasOwnProperty 方法
({}).hasOwnProperty.call(foo, "bar"); // true

// 也可以使用 Object 原型上的 hasOwnProperty 屬性
Object.prototype.hasOwnProperty.call(foo, "bar"); // true
call apply

上面用到的call和apply,就在這里記錄一下。

1.每個(gè)函數(shù)都包含兩個(gè)非繼承而來的方法:call()方法和apply()方法。
2.相同點(diǎn):這兩個(gè)方法的作用是一樣的。
都是在特定的作用域中調(diào)用函數(shù),等于設(shè)置函數(shù)體內(nèi)this對(duì)象的值,以擴(kuò)充函數(shù)賴以運(yùn)行的作用域。
一般來說,this總是指向調(diào)用某個(gè)方法的對(duì)象,但是使用call()和apply()方法時(shí),就會(huì)改變this的指向。
3.不同點(diǎn):接收參數(shù)的方式不同。

apply()方法 接收兩個(gè)參數(shù),一個(gè)是函數(shù)運(yùn)行的作用域(this),另一個(gè)是參數(shù)數(shù)組。

語法:apply([thisObj [,argArray] ]);,調(diào)用一個(gè)對(duì)象的一個(gè)方法,2另一個(gè)對(duì)象替換當(dāng)前對(duì)象。
說明:如果argArray不是一個(gè)有效數(shù)組或不是arguments對(duì)象,那么將導(dǎo)致一個(gè)TypeError,如果沒有提供argArray和thisObj任何一個(gè)參數(shù),那么Global對(duì)象將用作thisObj。

call()方法 第一個(gè)參數(shù)和apply()方法的一樣,但是傳遞給函數(shù)的參數(shù)必須列舉出來。

語法:call([thisObject[,arg1 [,arg2 [,...,argn]]]]);,應(yīng)用某一對(duì)象的一個(gè)方法,用另一個(gè)對(duì)象替換當(dāng)前對(duì)象。
說明: call方法可以用來代替另一個(gè)對(duì)象調(diào)用一個(gè)方法,call方法可以將一個(gè)函數(shù)的對(duì)象上下文從初始的上下文改變?yōu)閠hisObj指定的新對(duì)象,如果沒有提供thisObj參數(shù),那么Global對(duì)象被用于thisObj。

// call
    window.name = "FinGet";
    document.name = "FinGet1";

    var boy = {name: "FinGet2" };
    function showName(){
        console.log(this.name);
    }

    showName.call();         //FinGet (默認(rèn)傳遞參數(shù))  this 是指向window
    showName.call(window);   //FinGet
    showName.call(document); //FinGet1
    showName.call(this);     //FinGet
    showName.call(boy);       //FinGet2

    var Pet = {
        words : "hello",
        speak : function (say) {
            console.log(say + ""+ this.words)
        }
    }
    Pet.speak("Speak"); // 結(jié)果:Speakhello

    var Dog = {
        words:"Wang"
    }

    //將this的指向改變成了Dog
    Pet.speak.call(Dog, "Speak"); //結(jié)果: SpeakWang

可以將上面代碼中的call換成apply,也是可以執(zhí)行的。

Object.assign
Object.assign(target, ...sources)

target 目標(biāo)對(duì)象

sources 源對(duì)象

如果目標(biāo)對(duì)象中的屬性具有相同的鍵,則屬性將被源中的屬性覆蓋。后來的源的屬性將類似地覆蓋早先的屬性。
注意,Object.assign 會(huì)跳過那些值為 null 或 undefined 的源對(duì)象。
var obj1 = {a:"1",b:"2"};
var obj2 = {c:"3",d:"4"};
Object.assign(obj1,obj2); // Object {a: "1", b: "2", c: "3", d: "4"}

obj1 也改變
Object {a: "1", b: "2", c: "3", d: "4"}

obj2
Object {c: "3", d: "4"}

更多相關(guān)Object.assign可以查看官網(wǎng)。

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

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

相關(guān)文章

  • JavaScript基礎(chǔ): 類與繼承

    摘要:類的方法相當(dāng)于之前我們定義在構(gòu)造函數(shù)的原型上。的構(gòu)造函數(shù)中調(diào)用其目的就是調(diào)用父類的構(gòu)造函數(shù)。是先創(chuàng)建子類的實(shí)例,然后在子類實(shí)例的基礎(chǔ)上創(chuàng)建父類的屬性。 前言   首先歡迎大家關(guān)注我的Github博客,也算是對(duì)我的一點(diǎn)鼓勵(lì),畢竟寫東西沒法獲得變現(xiàn),能堅(jiān)持下去也是靠的是自己的熱情和大家的鼓勵(lì)?!   ≡S久已經(jīng)沒有寫東西了,因?yàn)殡s七雜八的原因最近一直沒有抽出時(shí)間來把寫作堅(jiān)持下來,感覺和跑步一...

    liuchengxu 評(píng)論0 收藏0
  • 淺談React事件機(jī)制

    摘要:事件簡介事件是合成事件,所有事件都自動(dòng)綁定到最外層上。支持事件的冒泡機(jī)制,我們可以使用和來中斷它。這樣做簡化了事件處理和回收機(jī)制,效率也有很大提升。事件類型合成事件的事件類型是原生事件類型的一個(gè)子集。 React事件簡介 React事件是合成事件,所有事件都自動(dòng)綁定到最外層上。因?yàn)閂irtual DOM 在內(nèi)存中是以對(duì)象的形式存在的,所以React 基于 Virtual DOM 實(shí)現(xiàn)了...

    moven_j 評(píng)論0 收藏0
  • 淺談React事件機(jī)制

    摘要:事件簡介事件是合成事件,所有事件都自動(dòng)綁定到最外層上。支持事件的冒泡機(jī)制,我們可以使用和來中斷它。這樣做簡化了事件處理和回收機(jī)制,效率也有很大提升。事件類型合成事件的事件類型是原生事件類型的一個(gè)子集。 React事件簡介 React事件是合成事件,所有事件都自動(dòng)綁定到最外層上。因?yàn)閂irtual DOM 在內(nèi)存中是以對(duì)象的形式存在的,所以React 基于 Virtual DOM 實(shí)現(xiàn)了...

    MyFaith 評(píng)論0 收藏0
  • 從Vue數(shù)組響應(yīng)化所引發(fā)的思考

    摘要:因?yàn)闊o法通過借用構(gòu)造函數(shù)的方式創(chuàng)建響應(yīng)式屬性雖然屬性可以被創(chuàng)建,但不具備響應(yīng)式功能,因此在我們是沒法繼承數(shù)組的。上面整個(gè)的文章都是基于監(jiān)聽數(shù)組響應(yīng)的一個(gè)點(diǎn)想到的。 前言   首先歡迎大家關(guān)注我的Github博客,也算是對(duì)我的一點(diǎn)鼓勵(lì),畢竟寫東西沒法獲得變現(xiàn),能堅(jiān)持下去也是靠的是自己的熱情和大家的鼓勵(lì)。   從上一篇文章響應(yīng)式數(shù)據(jù)與數(shù)據(jù)依賴基本原理開始,我就萌發(fā)了想要研究Vue源碼的想法...

    hikui 評(píng)論0 收藏0
  • JavaScript 工作原理之十五-類和繼承及 Babel 和 TypeScript 代碼轉(zhuǎn)換探秘

    摘要:使用新的易用的類定義,歸根結(jié)底也是要?jiǎng)?chuàng)建構(gòu)造函數(shù)和修改原型。首先,它把構(gòu)造函數(shù)當(dāng)成單獨(dú)的函數(shù)且包含類屬性集。該節(jié)點(diǎn)還儲(chǔ)存了指向父類的指針引用,該父類也并儲(chǔ)存了構(gòu)造函數(shù),屬性集和及父類引用,依次類推。 原文請查閱這里,略有刪減,本文采用知識(shí)共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第...

    GeekGhc 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<