平时在写js代码中,当需要调用某一个函数或者方法时,我们只需要在函数名称后面加个()并在括号中传入函数的参数就可以。
let a = { add: function (a, b) {console.log(this); console.log(a + b); }}a.add(1, 2);
但是当另外一个对象b想调用上面的add方法时,该如何做呢?这时我们就可以使用call和apply方法。
let a = { add: function (a, b) {console.log(this); console.log(a + b); }}a.add(1, 2);let b = { x:5, y:7}a.add.call(b,b.x,b.y)
我们在a.add方法后面调用call方法,并且传入了3个参数,其中第一个参数为函数执行的上下文this,也就是函数执行的上下文由a变成了b,后面的第2个和第三个参数是方法add的2个参数。事实上我们也经常使用call来调用一个对象上不存在的方法,通过函数或者方法的调用改变函数的执行上下文。apply方法和call类似,只是传入的参数为数组类型。
那我们看看call和apply的出处。我们创建函数其实可以使用构造函数。
var fn = new Function('console.log("a")');fn();
但是这个方法相对函数表达式写法很复杂,而且还需要把字符串转换成js代码,所以执行效率也不高,所以很少这样写。但是这样写我们更容易理解call和apply的来源,其实Function作为一个函数也是有原型的,这个原型上也绑定了可供函数实例调用的方法函数,其中就包含call和apply方法。