国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

原生javascript實現(xiàn)extend

Steve_Wang_ / 3400人閱讀

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

代碼
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會遍歷數(shù)組所有的可枚舉屬性,包括原型。
            if (Object.prototype.hasOwnProperty.call(source, key)) { 
                target[key] = source[key]; 
            } 
        } 
    }
    return target; 
}
console.log(extend(obj1,obj2));

extend 要實現(xiàn)的是給任意對象擴展
分析一下

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

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

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

target是傳進來的第一個參數(shù),也就是需要擴展的對象。

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

// 進行這一步判斷是為了保證代碼的可執(zhí)行性,如果傳進來的是個數(shù)字、布爾值,則設(shè)為一個空對象
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會遍歷數(shù)組所有的可枚舉屬性,包括原型。
        if (Object.prototype.hasOwnProperty.call(source, key)) { 
            target[key] = source[key]; 
        } 
    } 
}

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

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

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

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

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

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

JavaScript 并沒有保護 hasOwnProperty 屬性名,因此某個對象是有可能存在使用這個屬性名的屬性,使用外部的 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.每個函數(shù)都包含兩個非繼承而來的方法:call()方法和apply()方法。
2.相同點:這兩個方法的作用是一樣的。
都是在特定的作用域中調(diào)用函數(shù),等于設(shè)置函數(shù)體內(nèi)this對象的值,以擴充函數(shù)賴以運行的作用域。
一般來說,this總是指向調(diào)用某個方法的對象,但是使用call()和apply()方法時,就會改變this的指向。
3.不同點:接收參數(shù)的方式不同。

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

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

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

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

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

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

    showName.call();         //FinGet (默認傳遞參數(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)對象

sources 源對象

如果目標(biāo)對象中的屬性具有相同的鍵,則屬性將被源中的屬性覆蓋。后來的源的屬性將類似地覆蓋早先的屬性。
注意,Object.assign 會跳過那些值為 null 或 undefined 的源對象。
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://specialneedsforspecialkids.com/yun/94139.html

相關(guān)文章

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

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

    liuchengxu 評論0 收藏0
  • 淺談React事件機制

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

    moven_j 評論0 收藏0
  • 淺談React事件機制

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

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

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

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

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

    GeekGhc 評論0 收藏0

發(fā)表評論

0條評論

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