综合开发

JavaScript进阶之实现call、apply

微信扫一扫,分享到朋友圈

JavaScript进阶之实现call、apply

call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

简单的总结一下: call方法就是用来调用函数并且改变函数内部this的指向

举个例子:

var foo = {
value: 1
};
function bar() {
console.log(this.value);
}
bar.call(foo); // 1
复制代码

如何实现call方法

那么实现call需要实现以下四点就行:

  • 如何改变call作用函数的this
  • 考虑context(this)为null的情况
  • 函数有参数的情况
  • 函数有返回值

模拟实现第一版

仔细想想call方法无非就是具有这两个功能: 调用函数,改变函数的this指向 ,那我们自然而然就是从这两方面 做手脚

fn.call(thisArg, arg1, arg2, ...)
复制代码
  • this的指向是如何确定的?是不是谁调用它,它就指向谁,也就是说我们可以将 fn.call(thisArg, arg1, arg2, ...) 转化为 thisArg.fn() 这种形式,进而 改变fn的this指向 ,并且 调用了fn函数
Function.prototype.call2=function(context,...args){
context.fn=this
context.fn(...args)
}
复制代码

来简单实验下吧

var obj = {
value: 1
}
function bar(name, age) {
return {
value: this.value,
name: name,
age: age
}
}
bar.call2(obj, 'kevin', 18)
复制代码

模拟实现第二版

前面虽然实现了call方法的功能,但是我们看到实现这个call2没有解决的 副作用

对象obj添加了fn方法,此时我们应该删除它

Function.prototype.call2=function(context,...args){
context.fn=this
context.fn(...args)
delete context.fn
}
复制代码

模拟实现第三版

如果传入的 context 为null,原来的call方式是指向window的,并且还要考虑fn函数有返回值的情况,代码如下

Function.prototype.call2 = function(context=window,...args) {
content.fn = this;
let result = content.fn(...args);
delete content.fn;
return result;
};
复制代码

至此我们的call方法就实现完了

apply

apply和call方法差不多,只不过参数不同

apply方法 调用一个具有给定this值的函数,以及作为一个 数组(或类似数组对象) 提供的参数。

Function.prototype.apply2 = function(context = window,args) {
context.fn = this;
let result;
//判断是否有第二个参数
result = context.fn(...args);
delete context.fn();
return result;
}
复制代码

实现的不足

以上我们用到es6的 rest 参数以及拓展运算符特性 ,但是如果面试官要求es6之前的方式来实现呢,通常有两种实现方式 evalFunction

这里给出eval方式的实现

Function.prototype.call2 = function (context) {
var context = context || window;
context.fn = this;
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;
}
复制代码

可以es6语法特性给我们带来的便利

JS异步编程有哪些方案?为什么会出现这些方案?

上一篇

金山办公合作伙伴大会:基础软件迎来历史性机遇

下一篇

你也可能喜欢

评论已经被关闭。

插入图片

热门栏目

JavaScript进阶之实现call、apply

长按储存图像,分享给朋友