bind和apply以及call函数使用

这三个函数都是定义在函数原型对象上的方法,其主要的用途是改变this的指向,并且调用函数,但是bind会返回一个改变bind后的函数。下面我们将详细聊一下三个函数的作用,以及其内部实现。
一、call和apply
(1)、传入参数不同
call函数可以传入的参数没有限制,第一个参数为this指向的值,第二个参数一直到最后一个参数都是传入原函数的参数。apply需要传入两个参数,第一个参数为this指向的对象,第二个参数是需要传入原函数的参数,是一个数组或者伪数组。
(2)、当第一个参数为null
对于call和apply函数,如果第一个参数为null,那么该函数指向默认宿主对象,在浏览器中会指向window对象。

//在node环境下
function foo(a, b) {
  console.log(this)
}
foo.call(null, 10, 20)  //global
//在浏览器环境中
foo.call(null, 10, 20) //window

在严格模式下,其中的this都指向null。

function foo(a, b) {
	"use strict"
	console.log(this)
}
foo.call(null)  //null

(3)、
有时候我们使用call,apply其目的不只是改变this,而是调用对象上面的方法,此时我们传入null,就可以表示一个具体的对象。

let nums = Math.max.apply(null, [12,34,56,2,11])
console.log(nums) //56

二、手动实现call函数

//手动实现call
Function.prototype.myCall = function (obj, ...array) {
  let fn = this
  let thisArg = (obj === undefined || obj === null) ? window : Object(obj)
  array = Array.isArray(array) ? array : []
  thisArg.fn = fn
  let result = thisArg.fn(...array)
  delete thisArg.fn
  return result
}

三、手动实现apply函数

//手动实现apply
Function.prototype.myApply = function (obj, array) {
  let fn = this
  let thisArg = (obj === undefined || obj === null) ? window : Object(obj)
  thisArg.fn = fn
  array = Array.isArray(array) ? array : []
  let result = thisArg.fn(...array)
  delete thisArg.fn
  return result
}

四、手动实现bind函数
bind返回得是一个函数,就是将this改变后的函数。

Function.prototype.myBind = function (obj, ...arg1) {
  let fn = this
  let thisArg = (obj === undefined || obj === null) ? window : Object(obj)

  function proxyFn(...arg2) {
    thisArg.fn = fn
    let arg3 = [...arg1, ...arg2]
    let result = thisArg.fn(...arg3)
    delete thisArg.fn
    return result
  }
  return proxyFn
}

五、arguments的应用
arguments是一个伪数组,但是有时候我们需要使用数组的方法,在ES6之前我们可以使用call方法来调用,但是在ES6之后我们可以使用Array.from来将其转换为数组。

上一篇:如何自己实现bind方法


下一篇:Linux的bind服务