Stories

Detail Return Return

自定義javascript中call、bind、apply方法 - Stories Detail

call、bind、apply都是Function原型上的方法,用於改變this的指向

自定義函數

js中的call、bind、apply是用c++代碼實現的,我們這裏使用js代碼做一個模式,沒有把所有的邊界情況考慮進來,僅做一個簡單的實現,三個函數在使用的時候有一些需要注意的地方,在定義的時候需要把這些情況考慮進去

  • 當傳入的值是基本數據類型時,call、apply、bind方法會將它轉變成引用數據類型,如傳入的字符串變成了 String 類型,通過Object()可以做這一轉換
  • 當沒有傳遞需要改變的this指向時,函數的this指向window(非嚴格模式下)
  • 當傳遞的this指向為null、undefined時, 函數的this指向window(非嚴格模式下)

call的實現

定義call函數需要注意

  • 第一個參數接收改變後的this指向,從第二個參數開始接收函數執行所需要的參數

實現代碼如下

Function.prototype.iCall = function (thisArg, ...args) {
  // 1.獲取執行函數
  var fn = this
  
  // 2.將函數綁定到傳遞的對象上
  thisArg = thisArg || thisArg.toString() ? Object(thisArg) : window
  thisArg.fn = fn
  var result = thisArg.fn(...args)
  
  // 3.刪除傳遞對象的fn函數
  delete thisArg.fn
  
  // 4.返回結果
  return result
}

function foo(...args) {
  console.log('綁定的this為:', this)
  console.log('傳遞的參數為:', args)
}

var user = {
  name: 'alice'
}

// 將foo函數this指向改為user,並傳遞參數1,2,3
foo.iCall(user, 1, 2, 3)

執行結果為

apply的實現

定義apply函數需注意

  • 第一個參數接收改變後的this指向,第二個參數接收函數執行所需要的參數組成的【數組】

實現代碼如下

Function.prototype.iApply = function(thisArg, args){
   // 1.獲取執行函數
   var fn = this
   // 2.將函數綁定到傳遞的對象上
   thisArg = thisArg || thisArg.toString() ? Object(thisArg) : window
   thisArg.fn = fn
   var result = thisArg.fn(...args)
 
   // 3.刪除傳遞對象的fn函數
   delete thisArg.fn
 
   // 4.返回結果
   return result
}

function foo(...args){
  console.log('綁定的this為:', this)
  console.log('傳遞的參數為:', args)
}

var str = "hello js"
var arr = ['a', 'b', 'c']

foo.iApply(str, arr)

執行結果如下

bind的實現

定義bind函數需注意

  • 第一個參數接收改變後的this指向,第二個參數接收函數執行所需要的參數
  • bind函數不會立即調用函數,而是返回一個新的函數,新函數仍然可以繼續傳遞參數
Function.prototype.iBind = function (thisArg, ...args) {
  // 1.獲取執行函數
  var fn = this
  
  // 2.將函數綁定到傳遞的對象上
  thisArg = thisArg || thisArg.toString() ? Object(thisArg) : window
  thisArg.fn = fn
  
  return function (...params) {
    // 3.獲取函數執行的結果
    var result = thisArg.fn(...args, ...params)
    
    // 4.刪除傳遞對象的fn函數
    delete thisArg.fn
    
    // 5.返回結果
    return result
  }
}

function foo(...args) {
  console.log('綁定的this為:', this)
  console.log('傳遞的參數為:', args)
}
var num = 0

var fn = foo.iBind(num, 20, 40)
fn(30, 50)

執行結果如下

以上就是call、bind、apply的實現方法,代碼量不多,但是需要對this的指向比較瞭解,關於this指向也可以看看我其他的博文~

user avatar zxl20070701 Avatar hlinleanring Avatar lovehx_58bc3f5518bf4 Avatar tonyyoung Avatar songxianling1992 Avatar hx19 Avatar chongdongdedaxiongmao_kxfei Avatar yanglinxiao Avatar shijingjing_5ab4aa131e343 Avatar
Favorites 9 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.