call、apply、bind 的用法分別是什么?

call、apply、bind這三個方法,用來切換/固定this的指向。

1 .call() 方法
函數(shù)實(shí)例的call方法,可以指定函數(shù)內(nèi)部this的指向(即函數(shù)執(zhí)行時(shí)所在的作用域),然后在所指定的作用域中,調(diào)用該函數(shù)。

var obj = {};
var f = function () {
  return this;
};
f() === window // true
f.call(obj) === obj // true

上面代碼中,全局環(huán)境運(yùn)行函數(shù)f時(shí),this指向全局環(huán)境(瀏覽器為window對象);call方法可以改變this的指向,指定this指向?qū)ο髈bj,然后在對象obj的作用域中運(yùn)行函數(shù)f。

call方法的參數(shù),應(yīng)該是一個對象。如果參數(shù)為空、null和undefined,則默認(rèn)傳入全局對象。

var n = 123;
var obj = { n: 456 };
function a() {
  console.log(this.n);
}
a.call() // 123
a.call(null) // 123
a.call(undefined) // 123
a.call(window) // 123
a.call(obj) // 456

上面代碼中,a函數(shù)中的this關(guān)鍵字,如果指向全局對象,返回結(jié)果為123。如果使用call方法將this關(guān)鍵字指向obj對象,返回結(jié)果為456??梢钥吹剑绻鹀all方法沒有參數(shù),或者參數(shù)為null或undefined,則等同于指向全局對象。

2.apply()方法
apply方法的作用與call方法類似,也是改變this指向,然后再調(diào)用該函數(shù)。唯一的區(qū)別就是,它接收一個數(shù)組作為函數(shù)執(zhí)行時(shí)的參數(shù),使用格式如下。

func.apply(thisValue, [arg1, arg2, ...])

apply方法的第一個參數(shù)也是this所要指向的那個對象,如果設(shè)為null或undefined,則等同于指定全局對象。第二個參數(shù)則是一個數(shù)組,該數(shù)組的所有成員依次作為參數(shù),傳入原函數(shù)。原函數(shù)的參數(shù),在call方法中必須一個個添加,但是在apply方法中,必須以數(shù)組形式添加。

function f(x, y){
  console.log(x + y);
}
f.call(null, 1, 1) // 2
f.apply(null, [1, 1]) // 2

上面代碼中,f函數(shù)本來接受兩個參數(shù),使用apply方法以后,就變成可以接受一個數(shù)組作為參數(shù)。

3.bind()方法
bind方法用于將函數(shù)體內(nèi)的this綁定到某個對象,然后返回一個新函數(shù)。

bind方法的參數(shù)就是所要綁定this的對象
舉例:

var counter = {
  count: 0,
  inc: function () {
    this.count++;
  }
};

var func = counter.inc.bind(counter);
func();
counter.count // 1

上面代碼中,counter.inc方法被賦值給變量func。這時(shí)必須用bind方法將inc內(nèi)部的this,綁定到counter,否則就會出錯。

this綁定到其他對象也是可以的。

var counter = {
  count: 0,
  inc: function () {
    this.count++;
  }
};

var obj = {
  count: 100
};
var func = counter.inc.bind(obj);
func();
obj.count // 101

上面代碼中,bind方法將inc方法內(nèi)部的this,綁定到obj對象。結(jié)果調(diào)用func函數(shù)以后,遞增的就是obj內(nèi)部的count屬性。

bind還可以接受更多的參數(shù),將這些參數(shù)綁定原函數(shù)的參數(shù)。

var add = function (x, y) {
  return x * this.m + y * this.n;
}

var obj = {
  m: 2,
  n: 2
};

var newAdd = add.bind(obj, 5);
newAdd(5) // 20

上面代碼中,bind方法除了綁定this對象,還將add函數(shù)的第一個參數(shù)x綁定成5,然后返回一個新函數(shù)newAdd,這個函數(shù)只要再接受一個參數(shù)y就能運(yùn)行了。

如果bind方法的第一個參數(shù)是null或undefined,等于將this綁定到全局對象,函數(shù)運(yùn)行時(shí)this指向頂層對象(瀏覽器為window)。

function add(x, y) {
  return x + y;
}

var plus5 = add.bind(null, 5);
plus5(10) // 15

上面代碼中,函數(shù)add內(nèi)部并沒有this,使用bind方法的主要目的是綁定參數(shù)x,以后每次運(yùn)行新函數(shù)plus5,就只需要提供另一個參數(shù)y就夠了。而且因?yàn)閍dd內(nèi)部沒有this,所以bind的第一個參數(shù)是null,不過這里如果是其他對象,也沒有影響。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容