目录
前言
前端笔试的时候为了考察你js的水平,大概率会考察到手写call、apply函数,在此之前如果你还不了解call、apply函数的作用及区别,请先看这一篇,如果了解了请继续往下看~
一、call函数
1.初体验call函数
我们都知道call函数会改变this的指向,这里,我们先来看一段代码体验一下
var name = "小明";
var obj={
name:"小新",
funny:function () {
console.log(this.name)
}
};
const users={name:"甜甜"};
obj.funny()
根据this指向问题,我们知道对象函数里面的this指向对象~所以输出应该为小新
输出:
接下来,我们使用call函数改变this指向,让他指向users下面的name
var name = "小明";
var obj={
name:"小新",
funny:function () {
console.log(this.name)
}
};
const users={name:"甜甜"};
// obj.funny() //普通调用
obj.funny.call(users) //改变this指向
输出:
ok~到这里我们已经知道啦call的作用了吧!接下来我们来到正题:手写call
2.手写call函数
首先我们要思考,如何才能让所有函数都能使用call函数呢,那必然就是原型啦(不了解原型的请看这一篇:)
所以我们需要把这个方法写在函数原型上,我这里命名为mycall
var name = "小明";
var obj={
name:"小新",
funny:function () {
console.log(this.name)
return this.name
}
};
const users={name:"甜甜"};
// obj.funny()
//添加在原型上
Function.prototype.myCall=function (content) {//这里就会接受到调用的参数users 和1,2,3(这个几个参数在arguments里面)
//1. 因为call是函数方法,所以我们要判断调用的时候是否是函数
if(!typeof this ==="function"){
throw new Error("error")
}
//this指向obj.funny
// console.log(this);
//content是users,改变this的重要值
// console.log(content);
//arguments就是需要传给obj.funny的参数,我们需要后几个参数并传递给obj.funny
// console.log(...arguments);
const arg = [...arguments].splice(1);//不要第一个参数
// console.log(arg,"arg");
//2. 改变this指向:把obj.funny方法挂载到content上,并把参数传过去
content.addFun = this;
var result = content.addFun(...arg);
console.log(result,"结果");
delete content.addFun; //删除
return result
};
//1. 第一个参数为this指向,默认为window,后面都是参数
//2. myCall在obj.funny上面,这是一个函数方法,初始指向为obj.funny上函数
obj.funny.myCall(users,1,2,3)
ok~到这里就完成啦,手写call函数主要注意两个关键点:
1.如何让所有函数都有这个方法?方法加在原型上
2.如何改变this指向?在指定的对象上上添加函数并调用(最后记得删除这个方法)
二、apply函数
理解了call函数,apply函数就更写了。我们知道apply和call的区别在于第二个参数,apply传递数组,call则不是,所以我们只需要改变最后传参问题就可以啦!
1.手写apply
var name = "小明";
var obj={
name:"小新",
funny:function () {
console.log(this.name)
return this.name
}
};
const users={name:"甜甜"};
Function.prototype.myApply =function (content) {//这里就会接受到调用的参数users 和1,2,3(这个几个参数在arguments里面)
//1. 因为apply是函数方法,所以我们要判断调用的时候是否是函数
if(!typeof this ==="function"){
throw new Error("error")
}
//this指向obj.funny
// console.log(this);
//content是users,改变this的重要值
// console.log(content);
//arguments就是需要传给obj.funny的参数,我们需要后几个参数并传递给obj.funny
//2. 改变this指向:把obj.funny方法挂载到content上,并把参数传过去
content.addFun = this;
var result;
console.log(arguments);
//判断是否有参数
if (arguments[1]) {
result = content.addFun(...arguments[1]);
}else{
result = content.addFun()
}
delete content.addFun; //删除
return result
};
//1. 第一个参数为this指向,默认为window,后面都是参数
//2. myApply在obj.funny上面,这是一个函数方法,初始指向为obj.funny上函数
obj.funny.myApply(users,[1,2,3])
输出:
总结
以上就是今天要讲的内容,本文仅仅简单介绍call、apply如何手写,如果你有好的想法记得评论区告诉我哟~