手写call,apply,bind方法

call

Function.prototype.myCall = function (obj = window) { // 不传参默认为window
  obj.fn = this
  const args = [...arguments].slice(1)
  const res = obj.fn(...args)
  delete obj.fn
  return res
}


var obj = {
  x: 10
}
function foo() {
  console.log(this);  // { x: 10, fn: [Function: foo] }
  console.log(this.x);  // 10
}
foo.myCall(obj);

代码解析:

var obj = {
  x: 10
}

Function.prototype.myCall = function (context = window) {
  context.fn = this // this指向实例,此例为foo
  // console.log(this); // [Function: foo]
  // console.log(context); // { x: 10, fn: [Function: foo] }
  const args = [...arguments].slice(1) // 去掉第一个参数,就是context,这里就是obj
  // console.log(args); // [1,2]
  const result = context.fn(...args)
  delete context.fn // 删除方法属性fn
  return result
}

function foo(a, b) {
  console.log(this) // { x: 10, fn: [Function: foo] }
  console.log(a + b) // 3
}
foo.myCall(obj, 1, 2);

apply和call实现类似,不同的就是参数的处理:

Function.prototype.myApply = function (obj = window) {
  obj.fn = this
  let result
  if (arguments[1]) {
    result = obj.fn(...arguments[1])
  } else {
    result = obj.fn()
  }
  delete obj.fn
  return result
}

var obj = {
  x: 10
}
function foo() {
  console.log(this);  // { x: 10, fn: [Function: foo] }
  console.log(this.x);  // 10
}
foo.myApply(obj);

代码解析:

var obj = {
  x: 1
}

Function.prototype.myApply = function (obj = window) {
  obj.fn = this
  let res
  if (arguments[1]) {
    res = obj.fn(...arguments[1])
  } else {
    res = obj.fn()
  }
  delete obj.fn
  return res
}

function f1(a, b) {
  console.log(this);
  console.log(this.x);
  console.log(a + b);
}

f1.myApply(obj, [1, 2])

bind

Function.prototype.mybind = function (context = window) { // 原型上添加mybind方法
  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
    self.apply(context, args.concat(newArgs)) // 合并两args
  }
}

var obj = {
  x: 10
}
function foo() {
  console.log(this);  // {x: 10}
  console.log(this.x);  // 10
}
foo.mybind(obj)();

代码解析:

var obj = {
  x: 10
}

Function.prototype.myBind = function (obj = window) {
  obj.fn = this // this指向实例,此例为foo
  const res = function () { // 包裹在一个函数里面
    obj.fn(...arguments)
    delete obj.fn // 删除方法属性fn
  }
  return res
}

function foo(a, b) {
  console.log(this) // { x: 10, fn: [Function: foo] }
  console.log(a + b)
}
foo.myBind(obj)(1, 2)

你可能感兴趣的:(javascript,es6)