前端高频面试题之call/apply/bind的实现

193 阅读1分钟

call的实现

话不多说直接上代码:

Function.prototype.call1 = function () {
  // this 参数可以传 null,当为 null 的时候,视为指向 window
  var thisObj = arguments[0] || window
  if([...arguments].length > 1){
    var param = Array.prototype.slice.call(arguments,1)
  }
  thisObj.fn = this
    // 函数是可以有返回值的
  var result = thisObj.fn(...param)
  // eval('thisObj.fn(' + param +')')
  delete thisObj.fn
  return result
}
// Function.prototype.call1 = function(thisObj) {
//      var thisObj = thisObj || window
//   thisObj.fn = this;
//   var args = [];
//   for(var i = 1, len = arguments.length; i < len; i++) {
//     args.push('arguments[' + i + ']');
//   }
//   var result = eval('thisObj.fn(' + args +')');
//   delete thisObj.fn;
//   return result
// }

var obj = {
  name: 'siMing',
  sayName: function (age,sex) {
    console.log('你的姓名:', this.name, '你的年龄', age, '你的性别:', sex)
    return {
      name: this.name,
      age: age,
      sex: sex
    }
  }
}
var person = {
  name: '聪明'
}
console.log(obj.sayName.call1(person,18,'girl'))

apply的实现

apply和call的实现原理类似,只是将传递到函数的参数变成了数组,不用我们截取了arguments第1位到最后一位了,直接取参数第1位就可以了。

Function.prototype.apply1 = function () {
  // this 参数可以传 null,当为 null 的时候,视为指向 window
  var thisObj = arguments[0] || window
  if([...arguments].length > 1){
    var param = arguments[1]
  }
  console.log(param)
  thisObj.fn = this
  // 函数是可以有返回值的
  var result = thisObj.fn(...param)
  // eval('thisObj.fn(' + param +')')
  delete thisObj.fn
  return result
}
// Function.prototype.apply1 = function(thisObj,arr) {
//   var thisObj = thisObj || window
//   thisObj.fn = this;
//   var args = [];
//   for(var i = 0, len = arr.length; i < len; i++) {
//     args.push('arr[' + i + ']');
//   }
//   var result = eval('thisObj.fn(' + args +')');
//   delete thisObj.fn;
//   return result
// }

var obj = {
  name: 'siMing',
  sayName: function (age,sex) {
    console.log('你的姓名:', this.name, '你的年龄', age, '你的性别:', sex)
    return {
      name: this.name,
      age: age,
      sex: sex
    }
  }
}
var person = {
  name: '聪明'
}
console.log(obj.sayName.apply1(person,[18,'girl']))

bind实现

bind和call不同的是返回来的是一个函数,而不立即执行。

Function.prototype.bind1 = function () {
    var slice = Array.prototype.slice
    var context = this
    var fnThis = arguments[0]
    var param = slice.call(arguments, 1)
    return function () {
        var args = param.concat(slice.call(arguments))
        return context.apply(fnThis,args)
    }
};