JS系列之call & apply & bind

參考連接:https://juejin.im/post/59bfe8...數組

在JavaScript中,call、apply和bind是Function對象自帶的三個方法,都是爲了改變函數體內部 this 的指向。app

  1. apply 、 call 、bind 三者第一個參數都是 this 要指向的對象,也就是想指定的上下文;
  2. apply 、 call 、bind 三者均可以利用後續參數傳參;
  3. bind 是返回對應 函數,便於稍後調用;apply 、call 則是當即調用。

apply、call 的區別

func.apply(thisArg, [argsArray])
fun.call(thisArg, arg1, arg2, ...)

對於 apply、call 兩者而言,做用徹底同樣,只是接受參數的方式不太同樣。函數

var func = function(arg1, arg2) {
   ...   
};

func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2]);

call 須要把參數按順序傳遞進去,而 apply 則是把參數放在數組裏。post

bind

fun.bind(thisArg[, arg1[, arg2[, ...]]])

bind()方法會建立一個新函數,稱爲綁定函數,當調用這個綁定函數時,綁定函數會以建立它時傳入 bind()方法的第一個參數做爲 this,傳入 bind() 方法的第二個以及之後的參數加上綁定函數運行時自己的參數按照順序做爲原函數的參數來調用原函數。
bind返回值是函數this

var obj = {
    name: 'Dot'
}

function printName() {
    console.log(this.name)
}

var dot = printName.bind(obj)
console.log(dot) // function () { … }
dot()  // Dot

bind 方法不會當即執行,而是返回一個改變了上下文 this 後的函數。而原函數 printName 中的 this 並無被改變,依舊指向全局對象 window。code

有個有趣的問題,若是連續 bind() 兩次,亦或者是連續 bind() 三次那麼輸出的值是什麼呢?像這樣:對象

var bar = function(){
    console.log(this.x);
}
var foo = {
    x:3
}
var sed = {
    x:4
}
var func = bar.bind(foo).bind(sed);
func(); //?
  
var fiv = {
    x:5
}
var func = bar.bind(foo).bind(sed).bind(fiv);
func(); //?

答案是,兩次都仍將輸出 3 ,而非期待中的 4 和 5 。緣由是,在Javascript中,屢次 bind() 是無效的。更深層次的緣由, bind() 的實現,至關於使用函數在內部包了一個 call / apply ,第二次 bind() 至關於再包住第一次 bind() ,故第二次之後的 bind 是沒法生效的。ip

參數

function fn(a, b, c) {
    console.log(a, b, c);
}
var fn1 = fn.bind(null, 'Dot');

fn('A', 'B', 'C');            // A B C
fn1('A', 'B', 'C');           // Dot A B
fn1('B', 'C');                // Dot B C
fn.call(null, 'Dot');      // Dot undefined undefined

call 是把第二個及之後的參數做爲 fn 方法的實參傳進去,而 fn1 方法的實參實則是在 bind 中參數的基礎上再日後排。get

相關文章
相關標籤/搜索