今天学习的是apply和call,他们是我们作为前端入门必须掌握的知识点,废话不多说开始我们今天的学习之路
1.apply和call是什么?
apply和call是function对象中的两个方法。
2.什么场景下面我们需要使用到apply和call?
举个例子我们有两个对象A和B,在对象A中有一个方法C,A对象经常使用方法C,B偶尔会使用到方法C,此时为了节约资源,减少冗余代码我们不会在B中在写一个方法C,而是直接使用B调用A中的方法C,在这样的场景下面我们就会使用到apply和call。
3.apply和call的定义?
从我们的第二个问题我们可以大概知道,apply和call就是改变当前对象的作用域,B能够访问A中的方法C,在这里我们称作B改变了A中的this指向,相当于将A对象中函数C的上下文修改为B。
官方的定义:
apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象调用B对象的方法。
call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法。
从官方的定义我们能够看出apply和call的唯一区别在于,他们的参数不同,apply接收两个参数,第一个参数为要改变的原函数的上下文,第二个参数为替换原函数的参数,我们需要注意的是第二个参数必须是数组。call可以接收多个参数,第一个参数是要改变的原函数的上下文,第二个参数和以后的参数为要替换原函数的参数
4.apply和call的实际使用
apply和call的实际使用我将通过举例实战的方式来讲解
var A = { name: "AAA", fn: function(skill) { this.skill = skill; console.log("my name is " + this.name + ", my skills are " + this.skill); } } var B = { name: "BBB" } A.fn("sing"); //my name is AAA, my skills are sing B.fn("dance"); //Uncaught TypeError: B.fn is not a function;
在这段代码我们能够看到B直接调用A中的fn是会报错的,因为B中并没有A中fn方法,接下来我们使用apply和call实现B能调用fn方法
var A = { name: "AAA", fn: function(skill) { this.skill = skill; console.log("my name is " + this.name + ", my skills are " + this.skill); } } var B = { name: "BBB" } A.fn("sing"); //my name is AAA, my skills are sing //B.fn("dance"); //Uncaught TypeError: B.fn is not a function; A.fn.apply(B,["dance"])//my name is BBB, my skills are dance A.fn.call(B,'dance21')//my name is BBB, my skills are dance21
在执行A对象的函数fn时,通过apply将函数fn的执行上下文(this)暂时修改为对象B,此时fn中的this指向对象B,同时修改原函数fn的参数为“dance”(注意“dance”参数必须是数组的形式),call方法自动执行改变之后的原函数