Please enable Javascript to view the contents

从头学习js-10-模拟实现call和apply

 ·  ☕ 1 分钟

这个系列是我读冴羽老师博客的感悟,
加入了个人的解读和练习题的解答

call使用的例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
var foo = {
    value: 1
};

function bar(name, age) {
    console.log(name)
    console.log(age)
    console.log(this.value);
}

bar.call(foo, 'kevin', 18);
// kevin
// 18
// 1

用js模拟call:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Function.prototype.myCall = function (newContext) {
  var context = Object(newContext) || window; //如果传的对象是null,默认指向window
  context.fn = this; //将当前方法作为对象的一个属性
  
  //梳理一下参数,从第二个参数开始(下标为1)
  var args = [];
  for(var i = 1, len = arguments.length; i < len; i++) {
    args.push('arguments[' + i + ']');
  }

  //执行方法
  var result = eval('context.fn(' + args + ')');
  delete context.fn; //删除临时属性方法
  return result;
}

apply和call非常类似,两者的区别只是接受的参数形式不同:
bar.call(foo, ‘kevin’, 18)
bar.apply(foo, [‘kevin’, 18])

用js模拟apply:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
Function.prototype.myApply = function (newContext, arr) {
  var context = Object(newContext) || window; //如果传的对象是null,默认指向window
  context.fn = this; //将当前方法作为对象的一个属性

  //梳理参数,这次从下标0开始,并执行方法
  var result;
  if (!arr) {
    result = context.fn()
  } else {
    var args = [];
    for(var i = 0, len = arr.length; i < len; i++) {
      args.push('arr[' + i + ']')
    }
    result = eval('context.fn(' + args + ')');
  }

  delete context.fn; //删除临时属性方法
  return result;
}
分享

Llane00
作者
Llane00
Web Developer