1. 程式人生 > >js中call、bind和apply的區別

js中call、bind和apply的區別

相似之處:

  1. 如果你要傳遞的引數不多,則可以使用fn.call(thisObj, arg1, arg2 ...)
  2. 如果你要傳遞的引數很多,則可以用陣列將引數整理好呼叫fn.apply(thisObj, [arg1, arg2 ...])
  3. 如果你想生成一個新的函式長期繫結某個函式給某個物件使用,則可以使用const newFn = fn.bind(thisObj); newFn(arg1, arg2...)

call語法

  • fun.call(thisArg, arg1, arg2, ...)
  • thisArg: 在fun函式執行時指定的this值。需要注意的是,指定的this值並不一定是該函式執行時真正的this值,如果這個函式處於非嚴格模式下,則指定為null和undefined的this值會自動指向全域性物件(瀏覽器中就是window物件),同時值為原始值(數字,字串,布林值)的this會指向該原始值的自動包裝物件。
  • arg1, arg2, ... 指定的引數列表

apply語法

  • fun.apply(thisArg, [argsArray])
  • thisArg 在 fun 函式執行時指定的 this 值。需要注意的是,指定的 this 值並不一定是該函式執行時真正的 this 值,如果這個函式處於非嚴格模式下,則指定為 null 或 undefined 時會自動指向全域性物件(瀏覽器中就是window物件),同時值為原始值(數字,字串,布林值)的 this 會指向該原始值的自動包裝物件。
  • argsArray 一個數組或者類陣列物件,其中的陣列元素將作為單獨的引數傳給 fun 函式。如果該引數的值為null 或 undefined,則表示不需要傳入任何引數。從ECMAScript 5 開始可以使用類陣列物件。

bind語法

  • fun.bind(thisArg[, arg1[, arg2[, ...]]])
  • thisArg 當繫結函式被呼叫時,該引數會作為原函式執行時的 this 指向。當使用new 操作符呼叫繫結函式時,該引數無效。
  • arg1, arg2, ... 當繫結函式被呼叫時,這些引數將置於實參之前傳遞給被繫結的方法。
// 有隻貓叫小黑,小黑會吃魚
const cat = {
    name: '小黑',
    eatFish(...args) {
        console.log('this指向=>', this);
        console.log('...args', args);
        console.log(this.name + '吃魚');
    },
}
// 有隻狗叫大毛,大毛會吃骨頭
const dog = {
    name: '大毛',
    eatBone(...args) {
        console.log('this指向=>', this);
        console.log('...args', args);
        console.log(this.name + '吃骨頭');
    },
}

console.log('=================== call =========================');
// 有一天大毛想吃魚了,可是它不知道怎麼吃。怎麼辦?小黑說我吃的時候餵你吃
cat.eatFish.call(dog, '汪汪汪', 'call')
// 大毛為了表示感謝,決定下次吃骨頭的時候也喂小黑吃
dog.eatBone.call(cat, '喵喵喵', 'call')

console.log('=================== apply =========================');
cat.eatFish.apply(dog, ['汪汪汪', 'apply'])
dog.eatBone.apply(cat, ['喵喵喵', 'apply'])

console.log('=================== bind =========================');
// 有一天他們覺得每次吃的時候再喂太麻煩了。乾脆直接教對方怎麼吃
const test1 = cat.eatFish.bind(dog, '汪汪汪', 'bind')
const test2 = dog.eatBone.bind(cat, '喵喵喵', 'bind')
test1()
test2()

總結

  1. 當我們使用一個函式需要改變this指向的時候才會用到call`apply`bind
  2. 如果你要傳遞的引數不多,則可以使用fn.call(thisObj, arg1, arg2 ...)
  3. 如果你要傳遞的引數很多,則可以用陣列將引數整理好呼叫fn.apply(thisObj, [arg1, arg2 ...])
  4. 如果你想生成一個新的函式長期繫結某個函式給某個物件使用,則可以使用const newFn = fn.bind(thisObj); newFn(arg1, ar