欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解JavaScript中的this硬綁定

 更新時間:2022年10月08日 15:34:26   作者:墨戈  
這篇文章主要為大家詳細介紹了JavaScript中的this顯示綁定和硬綁定,文中的示例代碼講解詳細,具有一定的借鑒價值,感興趣的可以了解一下

一、this顯示綁定

this顯示綁定,顧名思義,它有別于this的隱式綁定,而隱式綁定必須要求一個對象內部包含一個指向某個函數的屬性(或者某個對象或者上下文包含一個函數調用位置),并通過這個屬性間接調用這個函數,從而把this簡介/隱式綁定到這個對象上。但是this的隱式綁定存在一個綁定對象丟失問題,如下面代碼所示:

function afun() {
    console.log(this.a);
}

var obj = {
    a: 1,
    afun: afun
};

var a = "hello";

setTimeout(obj.afun, 100);//"hello"

出人意料的是,控制臺打印出來的結果是全局變量a的結果,而不是擁有指向函數屬性的對象的a的值,這就是隱式綁定的對象丟失,回調函數丟失綁定對象是非常常見的。

但是,顯示綁定仍然不能解決綁定對象丟失的問題,但是顯示綁定的一個變種,即硬綁定可以解決綁定對象丟失。

在此之前,我們先來看看什么是顯示綁定。

我們可以通過使用函數的call()和apply()方法實現this顯示綁定,絕大多數內置函數和自定義函數都可以調用這兩種方法。他們均接收兩個參數

參數:

thisArg: 要綁定到調用者this的對象。

arg1, arg2, ...(call):指定的參數列表,即要傳給調用者的參數。比如a.call(obj, args)/a.apply(obj, args),args為參數傳給調用者函數a作為該函數的實參。

argsArray(apply):一個數組或者類數組對象,如果該參數的值為 null 或 undefined,則表示不需要傳入任何參數。

返回值:調用者函數若有返回值則返回該值,沒有返回值則返回undefined。

來看下面的代碼:

function bfun() {
    return this.a;
}

var obj1 = {
    a: "hello"
};

console.log(bfun.apply(obj1), bfun.call(obj1));//"hello" "hello"

若傳入的第一個參數時一個原始值呢?來看下面的代碼:

function bfun() {
    return this;
}


console.log(bfun.apply(3));//[Number: 2]

沒錯,原始值被轉換成了它的對象形式,也就是new Number(),這被成為"裝箱"。

但是,我們前面提到過,this顯示綁定雖然強大,但是仍然不能解決this綁定丟失問題。下面我們來解釋硬綁定,即顯示綁定的一個變種,它能完美解決this綁定丟失問題。

二、硬綁定

先來看看下面的代碼:

function cfun() {
    console.log(this.a)//"hello"
    return this.a;
}

var obj2 = {
    a: "hello"
};

var fn = function() {
    return cfun.apply(obj2);
};
console.log(fn());//"hello"

setTimeout(fn, 100);//"hello"

可以看到,硬綁定確實解決了this綁定丟失,但值得注意的是,通過apply()綁定的this對象,無法二次更改綁定對象:

function f() {
console.log( this.a );
}
var obj = {
a:2
};
var b = function() {
f.call( obj );
};
b(); // 2

b.call( window ); // 2

硬綁定的一個典型應用場景是創(chuàng)建一個包裹函數,傳入所有的參數給調用者函數并返回接收到的所有值。

function dfun(v) {
    return (v[0] + this.a);
}

var obj3 = {
    a: 10
};

var fn1 = function() {
    return dfun.call(obj3, arguments);
}

var result = fn1(6);
console.log(result);//16

對于arguments而言,call()和apply()的不同之處在于他們的參數類型不同:

function efun(v) {
    console.log(..v)//6 10 11
    return (v);
}

var obj4 = {
    a: 10
};

var fn1 = function() {
    return efun.apply(obj3, arguments);
}

var result = fn1([6, 10, 11]);
console.log(result);//[6, 10, 11]

也就是說call()的參數類型是Object,它傳入的參數列表會被轉換為鍵為'0'(隨傳入參數數量遞增),值為傳入參數的對象;而apply()的參數類型則是數組或者類數組。

function dfun(v) {
    return (v);
}

var obj3 = {
    a: 10
};

var fn1 = function() {
    return dfun.call(obj3, arguments);
}

var result = fn1(6, 19, 1, 1);
console.log(result);//[Arguments]{'0':6,'1':19,2':1,3':1}
console.log(typeof result);//'object'

最強大的一種方法是將包裹函數創(chuàng)建為可以重復使用的輔助函數,封裝可重復使用的硬綁定。

function ffun(v) {
    return this.a * v;
}

var obj5 = {
    a: 5,
};

var fn2 = function(fn, obj) {
    return function() {
        return fn.apply(obj, arguments);
    }
}

var bind = fn2(ffun, obj5);
console.log(bind(10));//50

由于硬綁定十分常用,但通過包裹函數創(chuàng)建可重復使用的硬綁定比較麻煩,所以ES5提供了一個實現相同功能的方法bind()。用法如下:

function hfun(v) {
    return this.a * v;
}

var obj6 = {
    a: 6
};

var bind = hfun.bind(obj6);
console.log(bind(4));//24

可以看到,我們再無需構建一個包裹函數來手動調用call或apply方法,只需要提供調用者和綁定到調用者this的對象即可。

我們可能發(fā)現了一個奇怪的現象,通過apply()和call()方法綁定的對象在傳參給調用者時,需要設置一個參數占位,但bind()方法則不用,這是因為他們的返回值不同,bind()方法會返回一個經過硬編碼的新函數,它會把傳入參數設置為this的上下文并調用原始函數??梢岳斫鈈ind使用方法為bind(obj)(args)。而對于call()和apply()方法而言,一旦調用此方法,就會立刻返回調用者函數的返回值,所以此時就需要同時傳入參數給方法的參數占用符,然后被函數參數讀取。值得注意的是,bind方法的參數和call方法類似。

到此這篇關于詳解JavaScript中的this硬綁定 的文章就介紹到這了,更多相關JavaScript this硬綁定 內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 簡單聊聊JavaScript中作用域與自執(zhí)行函數的使用

    簡單聊聊JavaScript中作用域與自執(zhí)行函數的使用

    作用域指的是一個變量的作用范圍,自執(zhí)行函數是指定義后立即執(zhí)行的函數,它可以被用來創(chuàng)建一個私有作用域,本文主要來和大家聊聊二者的具體定義與使用,感興趣的可以了解下
    2024-03-03
  • js實現敏感詞過濾算法及實現邏輯

    js實現敏感詞過濾算法及實現邏輯

    這篇文章主要介紹了js實現敏感詞過濾算法及實現邏輯,文中介紹了dfa算法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-07-07
  • JavaScript地圖拖動功能SpryMap的簡單實現

    JavaScript地圖拖動功能SpryMap的簡單實現

    SpryMap是一個獨立的并且是輕量級的JavaScript類庫,它不依賴于任何其他的JS框架
    2013-07-07
  • Webpack的Loader和Plugin的區(qū)別

    Webpack的Loader和Plugin的區(qū)別

    這篇文章主要介紹了Webpack的Loader和Plugin的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • 跨域表單提交狀態(tài)的變相判斷代碼

    跨域表單提交狀態(tài)的變相判斷代碼

    通過表單在iframe內向一個跨域的url提交的時候,如何判斷提交成功了呢?這個,基本上,很難,因為瀏覽器安全沙箱的限制,我們沒有辦法通過獲得iframe內部不同域頁面的信息。
    2009-11-11
  • Web表單提交之disabled問題js解決方法

    Web表單提交之disabled問題js解決方法

    這篇文章主要介紹了Web表單提交之disabled問題js解決方法,分析了通過js解決保存值也能保留用戶不能輸入的功能,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-01-01
  • JavaScript原型鏈及常見的繼承方法

    JavaScript原型鏈及常見的繼承方法

    這篇文章主要介紹了JavaScript原型鏈及常見的繼承方法,文章圍繞主題展開詳細的內容介紹,具有一定的的參考價值,需要的朋友可以參考一下
    2022-07-07
  • 用js來解決ajax讀取頁面亂碼

    用js來解決ajax讀取頁面亂碼

    前兩天寫過服務端的,可以解決所有的瀏覽器讀取中文亂碼的問題,總是有點不爽,憋了一天,想出這個東東來,能解決firefox和ie讀中文亂碼的問題,opera不行,chome也沒測試,暫且放著吧。
    2010-11-11
  • JavaScript talbe表中指定位置插入一行的實現代碼 腳本之家修正版

    JavaScript talbe表中指定位置插入一行的實現代碼 腳本之家修正版

    用js實現的在table中指定的位置插入一行,先點一下表中你想插入的位置,點擊即可。
    2009-06-06
  • 微信小程序自定義波浪組件使用方法詳解

    微信小程序自定義波浪組件使用方法詳解

    這篇文章主要為大家詳細介紹了微信小程序自定義波浪組件的使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09

最新評論