JS手寫bind函數

1、題目

  • 一、已知 ES5 中 func.bind(context, 1, 2)(3, 4) 等價於 func.call(context, 1, 2, 3, 4) 請用 ES3 實現一個 bind 的 polyfill

在前端的面試中,常常會問到call, apply, bind方法的區別?javascript

  • call: fn.call(context, 1, 2, 3, 4)
  • apply: fn.apply(context, [1, 2, 3, 4])
  • bind: fn.bind(context, 1, 2)(3, 4)

context爲this的指向, 以上三種方法執行的結果一致,call、apply二者的區別就是傳參方式的不一樣,而bind方法執行結果返回的是一個未執行的方法,執行時能夠繼續傳入參數,實現了函數的柯里化,提升參數的複用前端

2、實現過程

Function.prototype.myBind = function (context = window) { // 原型上添加mybind方法
   // var args = Array.from(arguments) // 類數組轉數組(es6) console.log(args instanceof Array)
   var argumentsArr = Array.prototype.slice.call(arguments) // 類數組轉數組
   var args = argumentsArr.slice(1) // 後面的參數
   var self = this // 調用的方法自己
   return function () { // 返回一個待執行的方法
       var newArgs = Array.prototype.slice.call(arguments) // 返回函數的arguments,類數組轉數組或者使用es6解構賦值
       self.apply(context, args.concat(newArgs)) // 合併兩args
   }
}

複製代碼

3、測試結果

// 測試
var name = 'window name'
var obj = {
    name: 'obj name',
}
var fn = function () {
    console.log(this.name, [...arguments])
}
fn(1, 2, 3, 4) // 直接執行,this指向window
fn.myBind(obj, 1, 2)(3, 4) // mybind改變this指向
fn.bind(obj, 1, 2)(3, 4) // 原生bind

// 以上執行結果以下:
// window name [1, 2, 3, 4]
// obj name [1, 2, 3, 4]
// obj name [1, 2, 3, 4]
複製代碼
相關文章
相關標籤/搜索