学习记录 JS call、apply、bind 实现

47 阅读2分钟

call&apply&bind

1、call, apply 都属于Function.prototype的方法,因为属于Function.prototype,所以每个Function对象实例,也就是每个方法都有call, apply属性。call、apply它们的作用都是一样的都是也是改变执行上下文的对象,只是使用方式不同而已。

2、bind 也是改变执行上下文的对象。

在Javascript中,代码总有一个执行上下文对象,那么当我手动改变它时,就可以改变这个执行上下文,也就可以将非自己的方法成为自己的方法。

3、call或apply是将执行上下文对象换了后,立即执行;而bind是将执行上下文对象换了后,创建一个新函数。

方法执行上下文this 指向问题

最精简的解释:this 指向调用函数时用的引用

JS 规定,当存在一个对象调用函数时,那么该函数的 this 指向的就是该对象 如果一个函数不存在对象调用它,那么该函数的 this 指向的就是全局的 window

call、 apply、bind用法

call

fn.call(obj, arg1, arg2, arg3)

定义:应用某一个对象的一个方法,用另一个对象替换当前对象。

apply

fn.apply(thisObj, [arg1, arg2, arg3])

定义:应用某一个对象的一个方法,用另一个对象替换当前对象。

说明:如果参数不是数组类型的,则会报一个TypeError错误。

apply与call的唯一区别就是接收参数的格式不同。

var name = 'windowName';
//方法a的作用,是输出对象的名字
function a(x, y) {
	console.log(this.name)
    console.log(x + y)
}

function b(){
   this.name = 'bName';
}

a(2, 8)  // windowName 10
a.call(new b(), 2, 8)  // bName 10
a.apply(new b(), [2, 8]) //bName 10
bind

fn.bind(thisObj, arg1, arg2, arg3) bind方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。

var name = 'windowName';
//方法a的作用,是输出对象的名字
function a(x, y) {
	console.log(this.name)
    console.log(x + y)
}

function b(){
   this.name = 'bName';
}

a(2, 8)  // windowName 10
var c = a.bind(new b(), 2)
c(8) //bName 10
call 实现
Function.prototype.myCall = function(context, ...args) {
  // 判断是否是undefined和null
  if (typeof context === 'undefined' || context === null) {
    context = window
  }
  let fnSymbol = Symbol()
  context[fnSymbol] = this
  let fn = context[fnSymbol] (...args)
  delete context[fnSymbol] 
  return fn
}
apply 实现
Function.prototype.myApply = function(context, args) {
  // 判断是否是undefined和null
  if (typeof context === 'undefined' || context === null) {
    context = window
  }
  let fnSymbol = Symbol()
  context[fnSymbol] = this
  let fn = context[fnSymbol] (...args)
  return fn
}
bind 实现
Function.prototype.myBind = function(context) {
// 判断是否是undefined和null
    if (typeof context === "undefined" || context === null) {
    	context = window;
    }
    self = this;
    return function(...args) {
    	return self.apply(context, args);
    }
}