this 在不同的地方有不同的含义:
1. 在事件处理函数中,this指向触发函数的对象;
2. 在普通函数中,this指向window;
3. 当作函数作为某个对象的方法调用时,this指向那个对象;
4. 在构造函数中this指向当前实例化对象;
当在一些情况中我们想要更改this的指向,这里就可以使用 call 与 apply 来改变 this 的指向,让 this 指向特定的对象。
call 与 apply 的作用都是改变 this 的指向,基本的操作都是一样的。其使用方法如下:
call(this指向,参数1,参数2...)
apply(this指向,[参数1,参数2...])
可以看到他们的传参方式是不一样的。想要修改this 的指向,那么必然有一个this修改后的指向,而函数必然后关系到传参问题:call方法可以传给该函数的参数分别作为自己的多个参数,而apply方法必须将传给该函数的参数合并成一个数组作为自己的一个参数。
- function sum(a,b){
- console.log(a+b); // 30
- console.log(this); // 原本指向window,现在指向sum了
- }
- sum.call(sum,10,20)
通过使用call方法,使得sum函数中原本指向window的this现在指向了sum自身,当然this的指向自己想指向哪里都可以。
另外还可以改变对象的this
- var obj1 = {
- "name":"韩梅梅",
- "getName":function(){
- console.log(this.name);
- }
- }
- obj2 = {
- "name":"李雷"
- }
- obj1.getName(); // 韩梅梅
- obj1.getName.call(obj2);// 李雷
可以看到在obj1第一次调用getName方法时,结果为韩梅梅,因为调用getName时this指向obj1自身。在第二次调用getName方法时,使用了call方法改变了this的指向,让this指向了obj2,故打印时this.name成了obj2.name,为李雷。
改变this一般用于借用别的对象的方法,当想使用某个自己没有而别的对象有的方法时,就可以通过改变this的指向来借用别对象的方法。如:
- var n = {};
- console.log(n.toString()); // [object Object]
- // 对象的toString方法可以获取数据的具体类型,若是也想获取数组的具体数据类型可以借用对象的该方法。
- console.log(Object.prototype.toString.call([])); // [object Array]
apply的使用和call的使用方式是一样的,只是在于向函数传参时是以一个数组的形式,就如上面例子中使用call改变函数sum的指向时,若是使用apply则为:sum.apply(sum,[10,20]),第一个为改变后的this指向,第二个参数为数组,若在进行传参时第二个参数的格式不对,会报错。
apply的巧妙用法:
使用Math.max可以得到数组中最大的一项
因为Math.max不支持Math.max([参数1,参数2...])也就是数组,但是它支持Math.max (参数1,参数2...)的形式,所以可以根据apply的特点来解决这个问题,因为刚好apply的第二个参数为一个数组,可以将这个数组作为apply的第二个参数传入,这样apply会将一个数组转换为一个参数接一个参数的方式传递给方法。
- var arr = [6,3,8,9,12,5]
- console.log(Math.max.apply(1,arr)); // 12
这样就轻易的可以得到一个数组中的最大项。
这块在调用的时候第一个参数给了1,这是因为没有对象去调用这个方法,我只需要用这个方法帮我运算,得到返回的结果就行,所以直接传递了一个1过去。用这种方法也可以实现得到数组中的最小项:Math.min.apply(1,array)