在回答你的问题之前,我们想理解一下js中this关键字
在面向对象语言中 this 表示当前对象的一个引用。
但在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变。
在方法中,this 表示该方法所属的对象;
如果单独使用,this 表示全局对象;
在函数中,this 表示全局对象;
在函数中,在严格模式下,this 是未定义的(undefined);
在事件中,this 表示接收事件的元素。
那么call() 和 apply() 方法可以将 this 引用到任何对象。
apply 和 call 允许切换函数执行的上下文环境(context),即 this 绑定的对象,可以将 this 引用到任何对象。
先看看call的写法:<script type="text/javascript">
var person1 = {
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
var person2 = {
firstName: "John",
lastName: "Doe",
}
/*console.log(person1.fullName.apply(person2)); // 返回 "John Doe"*/
console.log(person1.fullName.call(person2)); // 返回 "John Doe"
</script>
使用 person2 作为参数来调用 person1.fullName 方法时, this 将指向 person2, 即便它是 person1 的方法。
在看看call()的另外一种用法:<script type="text/javascript">
function person1(name, age) {
this.name = name;
this.age = age;
}
function person2(name, age, grade) {
person1.call(this, name, age);
this.grade = grade;
}
var person = new person2("xiaoming", 20, "dasan");
console.log(person.name+person.age+person.grade); //xiaoming20dasan
</script>
在person2里面,并没有给name和age赋值,但是存在这两个属性的值,因为call()方法,可以改变this的指向。
person1.call(this,name,age); 中的this代表的是person2,使得person2可以调用person1中的方法,person1中有this.name=name;
this.age=age; 这样就将name和age属性创建到了person2中。
一句话。call()可以让括号里的对象继承括号外函数的属性。同理,再看看apply的写法:
<script type="text/javascript">
function person1(name, age) {
this.name = name;
this.age = age;
}
function person2(name, age, grade) {
person1.apply(this, [name, age]);
/*person1.apply(this,arguments); 等价于上一行*/
this.grade = grade;
}
var person = new person2("xiaoming", 20, "dasan");
console.log(person.name+person.age+person.grade); //xiaoming20dasan
</script>
好了,我们通过上面两个例子知道apply与call的区别了。
call与apply的区别
call()和apply()的区别就是接收参数的方式不同。apply接收两个参数,一个是this,另一个是参数数组,即将其他所有参数放在一个数组里。
call()接收的参数第一个是this,其他参数必须用逗号隔开。其实apply还有其他的玩法。
apply()的其他用法
apply()有个重要特性,是将一个数组默认的转换为一个参数列表。(1)Math.max可以得到数组中最大的一项
因为Math.max不支持Math.max([1,2,3]),但是它支持Math.max(1,2,3),所以,就可以利用apply的特点得到数组中的最大值。
<script type="text/javascript">
var arr = [1, 2, 3];
var max = Math.max.apply(this, arr);
console.log(max); //3
</script>
此处,我们只是需要这个方法帮助我们运算,得到返回结果,所以此处,可以不传this,用null也可以,就是没有对象去调用它。第一个参数为this,就是全局对象去调用Math.max。
<script type="text/javascript">
var arr = [1, 2, 3];
var max = Math.max.apply(null,arr);
console.log(max); //3
</script>
(2)Math.min可以实现得到数组中最小的一项
理由同上,Math.max和Math.min是同一个思路。
<script type="text/javascript">同理,这块也可以不传this,可以直接传null。
var arr = [1, 2, 3];
var min = Math.min.apply(this, arr);
console.log(min); //1
</script>
<script type="text/javascript">
var arr=[1,2,3];
var min=Math.min.apply(null,arr);
console.log(min); //1
</script>
(3)Array.prototype.push 可以实现两个数组合并
push方法没有提供push([param1,param2,…paramN])但是它提供了push(param1,param2,…paramN) 所以同样也可以通过apply转换这个数组,即:
<script type="text/javascript">所以一般在目标函数中只需要n个参数的时候,并且不接收数组的参数形式的时候,可以使用apply。
var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
Array.prototype.push.apply(arr1, arr2);
console.log(arr1); //[ 1, 2, 3, 4, 5, 6 ]
</script>
网友回复