javascript高级之手写call、apply、bind

76 阅读1分钟

实现call方法

/**
 * 手写call函数的实现
 */

// 1.给所有的函数原型上添加一个lycall方法
Function.prototype.lycall = function (thisArg, ...args) {
  // 2.获取要被执行的函数
  var fn = this;

  // 3.处理thisArg的边界情况
  thisArg =
    thisArg !== null && thisArg !== undefined ? Object(thisArg) : window;

  // 4.调用需要执行的函数
  thisArg.fn = fn;
  var result = thisArg.fn(...args);
  delete thisArg.fn;

  // 5.将最终的结果返回
  return result;
};

/**
 * 测试函数foo
 */
function foo() {
  console.log(this);
}
foo.lycall(null);

/**
 * 测试函数sum
 */
function sum(num1, num2) {
  console.log()
  console.log("sum==>", num1 + num2);
}
sum.lycall('proxyParam',10, 50);

实现apply

/**
 * 手写实现apply
 */
Function.prototype.lyapply = function (thisArg,argArray) {
  // 获取需要执行的函数对象
  var fn = this
  

  // 处理thisArg参数的边界问题
  thisArg = ![null,undefined].includes(thisArg) ? Object(thisArg) : window

  // 执行函数
  var result 
  thisArg.fn = fn
  argArray = argArray || []
  result = thisArg.fn(...argArray)
  delete thisArg.fn

  return result
}

/**
 * 测试函数foo
 */
function foo () {
  console.log(this)
}
foo.lyapply()


/**
 * 测试函数sum
 */
 function sum (num1,num2) {
  return num1 + num2
}
var count = sum.lyapply('proxyValue',[10,60])
console.log(count)


/**
 * 测试函数bar
 * 场景:传入0
 */
function bar () {
  console.log('执行了bar函数',0)
}
bar.lyapply(0)

实现bind

/**
 * 手写bind实现
 */
Function.prototype.lybind = function (thisArg,argArray) {
  // 获取要执行的函数对象
  var fn = this

  // 处理thisArg边界情况
  thisArg = ![null,undefined].includes(thisArg) ? Object(thisArg) : window

  // 返回新的函数
  function proxyFn (...args) {
    thisArg.fn = fn
    var finalArray = [...argArray,...args]
    var result = thisArg.fn(...finalArray)
    delete thisArg.fn

    return result
  }
  return proxyFn()
}

/**
 * 测试函数foo
 */
function foo () {
  console.log(this)
}
foo.bind()()


/**
 * 测试函数sum
 */
function sum (num1,num2) {
  return num1 + num2
}
var callback = sum.bind('aaa',20,50)
console.log(callback())

测试

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script src="./实现bind.js"></script>
    <!-- <script src="./实现call.js"></script> -->
    <!-- <script src="./实现apply.js"></script> -->
  </body>
</html>
****