我们都知道apply、call和bind是函数对象的三个方法,但是每次遇到这三个方法时,总是觉得不求甚解。于是去翻了一些好的博客、文章,以求理解的更深入。所以想通过这篇文章对三个方法做一个归纳和总结。
深入浅出妙用 Javascript 中 apply、call、bind 这篇文章是在学习过程中看到的,感觉讲的不错,所以分享在这里,以供借鉴。
一、call和apply
在JavaScript中,call和apply都是为了改变某个函数运行时的上下文而存在的,换句话说,就是为了改变函数体内部this的指向。
下面通过两个例子,让我们分别看下call,apply是如何传参以及如何改变函数体内部的this指向
先来个例子,此例子旨在比较call和apply方法的传参形式
function hello(name, age) {
console.log(name);
console.log(age);
}
// 请注意call和apply的传参形式
hello.call(this, 'Edison', 25); // Edison 25
hello.apply(this, ['Edison', 25]); // Edison 25
再看一个例子,此例只需注意call和apply两方法的第一个参数指定的this值
var x = 1;
var obj = {x: 2};
function foo() {
console.log(this.x);
}
foo(); // 1
// 此时调用foo函数中的this是指向window对象
// 关于this的指向问题可以找相关文章做更深入的了解,这里暂不赘述
// 接下来见证奇迹的时刻到了,让我们看下foo函数是如何通过call和apply改变this的指向
foo.call(obj); // 2
foo.apply(obj); // 2
//感兴趣可以再去深究一下call和apply是如何实现改变this的指向,有知道的也可以指导评论
// 这里穿插一下bind()方法,与call、apply方法做个对比,可以先看一下,暂不深究,接下来会去讨论
var boundFun = foo.bind(obj);
// 与call、apply方法不同的是,bind()方法会创建一个新函数,成为绑定函数。
// 调用绑定函数
boundFun(); // 2;
然后回过头来看下call方法和apply的语法
1、call语法
fun.call(thisArg, arg1, arg2, ...)
thisArg
: 在fun函数运行时指定的this值。需要注意的是,指定的this值并不一定是该函数执行时真正的this值,如果这个函数处于非严格模式下,则指定为null和undefined的this值会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象。arg1, arg2, ...
: 指定的列表参数
2、apply语法
fun.apply(thisArg, [argsArr])
thisArg
: 在 fun 函数运行时指定的 this 值。需要注意的是,指定的 this 值并不一定是该函数执行时真正的 this 值,如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象[argsArr]
: 一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 fun 函数。如果该参数的值为null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。
现在对这两个方法应该有一个基本的认识,但还是得到具体的使用场景去做更多实践,毕竟,实践出真知嘛-
二、bind
其实bind()方法和apply和call很相似,也是可以改变函数体内this的指向。但是,和上边两个方法不同的是,bind()方法会创建一个新函数,成为绑定函数。
下面通过例子来对bind()方法做一个认识
var x = 1;
var bar = function() {
console.log(this.x);
};
var foo = {
x: 2;
}
bar(); // 1
var func = bar.bind(foo);
func(); // 2
然后再来看下bind的语法
1、bind语法
- fun.bind(thisArg[, arg1[, arg2[, ...]]]);
- thisArg 当绑定函数被调用时,该参数会作为原函数运行时的this指向。当使用new操作符调用时绑定函数时,该参数无效
- arg, arg2, ... 当绑定函数被调用时,这些参数将至于实参之前传递给被绑定的方法。