call、apply、bind 的区别及应用
在面向对象的编程中,经常会处理 this 的指向问题,改变 this 的指向就不得不谈谈今天的主角—— call、apply、bind。个人感觉 this 的问题初学者不同容易一下理解透彻,今天再来好好捋一捋加深理解。
作用
call、apply、bind 的作用就是改变函数执行时的上下文,即改变 this 指向。
this 的指向其实也就不外乎这四种情况,其实理解起来还是很容易的,理解不了也没关系,先记住,后面在工作中大量编码应用,写多了就知道为啥要这样用了。先来一个简单的例子。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19// 定义人类构造函数,属性是姓名,方法是输出自己的姓名
function Person(name) {
this.name = name;
}
Person.prototype = {
constructor: Person,
showName: function() {
console.log(this.name);
}
};
var p1 = new Person('ifyour');
p1.showName(); // => ifyour
// 定义一个动物对象,它有个一姓名属性
var animal = {
name: 'cat'
};
人类实例 p1 想要打印自己的姓名,只要调用自身的 showName 方法即可,但是动物呢?我也想要动物实例 animal 打印自己的名字,如何做呢?当然改变 this 咯,把人类的 showName 方法借给动物用。
1 | // 可以直接去原型上借用 |
区别
call、apply 与 bind
call、apply改变this指向后会 立即执行bind并不会执行
在上面的例子我们也看到了,bind 方法改变 this 时,还需要加一个 () 才能执行输出 cat。
call 与 apply
call把参数按顺序传入,即:fn.call(obj, arg1, arg2, arg3...);apply把参数打包成Array后传入,即:fn.apply(obj, [arg1, arg2, arg3...]);
它们俩之间的差别在于 参数,call 和 aplly 的第一个参数都是要改变上下文的对象,而 call 从第二个参数开始以参数列表的形式展现,apply 则是把除了改变上下文对象的参数放在一个数组里面作为它的第二个参数。
应用
知道了怎么使用和它们之间的区别,接下来我们来了解一下使用 call、apply、bind 的常见应用场景。
求数组中的最大、最小值
1 | var arr = [34,5,3,6,54,6,-67,5,7,6,-8,687]; |
将伪数组转化为数组
JavaScript 中的伪数组(例如通过 document.getElementsByTagName 获取的元素)具有 length 属性,并且可以通过 0、1、2……下标来访问其中的元素,但是没有 Array 中的 push、pop 等方法。我们可以利用 call、apply 来将其转化为真正的数组这样便可以方便地使用数组方法了。
1 | // 这是一个伪数组 |
arr 便是一个包含 arrayLike 元素的真正的数组啦( 注意数据结构必须是以数字为下标而且一定要有 length 属性 )数组追加
1 | var arr1 = [1,2,3]; |
变量类型判断
1 | function isArray(obj){ |
继承
1 | // 基础类 |