原文:参考链接
原文作者: chokcoco
读高中的时候,老师说有哪些知识点不明白的,就多抄几遍,抄着抄着就明白了。这种做法效率很低,不过对于理清思路还是有一定帮助的。
读了上面的博客,觉得写的特别好,为了更好的整理思路和学习,所以引用过来,自己从一个纯粹听的人变成一个讲的人,似乎对于细节有更好的把握。
apply 和 call
apply 和 call 可以改变函数中this的指向。
例子1
function fruits() {}
fruits.prototype = {
color: "red",
say: function() {
console.log("My color is " + this.color);
}
}
var apple = new fruits;
apple.say(); //My color is red
banana = {
color: "yellow"
}
apple.say.call(banana); //My color is yellow
apple.say.apply(banana); //My color is yellow
我们可以看到,在调用this.color 的时候,之后了call 和 apply 后,apple的say方法的时候,调用的是banana种的color。
例子2
let apple={
color:"red",
say:function(){
console.log(this.color);
this.color="orange";
}
}
let banana={
color:"yellow",
say:function(){
console.log("--------");
console.log(this.color);
console.log("--------");
}
}
apple.say.apply(banana);//yellow
banana.say();//------- orange -------------
console.log(apple.color);//red
可以看出来,执行还是执行的apple的方法,但是this被变成了banana。banana的color被改变了,而apple的color没有改变.
apply、call 的区别
在调用有参数的方法时,两者的调用法式不太一样。
call是吧参数按顺序传递进去,而apply则是在数组里。
例子3
var func = function(arg1, arg2) {
................
};
func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2])
这样的特性使得apply在使用中比call更常见写,下面列举一些常用的使用方法以加强理解。
例子4 数组合并
let x = [];
let array1 = [12 , "foo" , -2458];
let array2 = ["Doe" , 555 , 100];
x.push.apply(array1,array2);
console.log(array1);
//这些写虽然简便一些,但是会多一个多余的变量x,造成可读性下降。也可以写成如下:
var array1 = [12 , "foo" , {name "Joe"} , -2458];
var array2 = ["Doe" , 555 , 100];
Array.prototype.push.apply(array1, array2);
console.log(array1);
//这样代码长一些,不过意思却很很明显。
例子5 就数组中最大值和最小值
JavaScript
var numbers = [5, 458 , 120 , -215 ];
var maxInNumbers = Math.max.apply(Math, numbers), //458
maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458
number 本身没有 max 方法,但是 Math 有,我们就可以借助 call 或者 apply 使用其方法。
例子6 验证对象是否是数组
functionisArray(obj){
return Object.prototype.toString.call(obj) === '[object Array]' ;
}
bind
bind是现在非常常见的一个函数。bind跟apply和call一样可以改变函数的上下文this的指向。只是参数使用方式不太相同。
MDN的解释是:bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
例子7
var foo = {
bar : 1,
eventBind: function(){
var _this = this;
$('.someClass').on('click',function(event) {
/* Act on the event */
console.log(_this.bar); //1
});
}
}
由于 Javascript 特有的机制,上下文环境在 eventBind:function(){ } 过渡到 $(‘.someClass’).on(‘click’,function(event) { }) 发生了改变,上述使用变量保存 this 这些方式都是有用的,也没有什么问题。当然使用 bind() 可以更加优雅的解决这个问题:
var foo = {
bar : 1,
eventBind: function(){
$('.someClass').on('click',function(event) {
/* Act on the event */
console.log(this.bar); //1
}.bind(this));
}
}
再总结一下:
- apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
- apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
- apply 、 call 、bind 三者都可以利用后续参数传参;
- bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。
网友评论