apply、call 有什么作用,什么区别
要说清除apply和call的作用就要从this的指向开始讲起
- this值的指向
this, 是函数内部的属性, 指向的函数据以执行的环境对象, 注意: this的指向只有函数调用的时候才能确定- 在全局调用的时候指向的是window
- 作为对象的方法调用的时候指向的是那个对象
- 构造函数的时候指向的是构造出来的对象
- 在事件的回调函数中指的是注册事件dom节点(this === e.currentTarget)
- 只用apply和call调用的时候指向的是第一个参数指定对象, 如果第一个null就指向window
例子:
var name = 'hello'
var obj = {
name: 'world'
}
function sayName() {
console.log(this.name)
}
//全局调用, 默认指向window
sayName()//输出'hello'
//作为obj的方法调用, 指向obj
obj.sayName = sayName
obj.sayName()//输出'world'
//使用call指定this值
sayName.call(obj)//输出'world'
- apply和call的作用
apply和call的作用是相同的, 都是指定函数的this值和参数调用函数, 其实JavaScript完全可以不支持使用.
调用函数的方法, 例如obj.sayName()
, 这只是一个语法糖, 使得this的指向去不够清晰, 而使用apply和call调用却使this的指向十分清晰
例如:
sayName.call(null)//如果不指定, 函数内部的this指向的就是window
sayName.call(obj)//指定this的指向为obj
- apply和call的区别
区别在于传递给函数的参数, apply接受的是数组形式, call接受的是多个参数, 因为apply接受数组形式的参数, 所以就有一些特别的用法, 例如
var numArr =[1,2,3,4,5,6,7]
Math.min.apply(null, numArr)//就可以获得数组中的最小值
Math.max.apply(null,numArr)//就可以获得数组中的最大值
注意: 虽然apply接受的是数组, 但是传递给函数的参数还是数组的元素, 而不是整个数组
代码练习题
//1. 以下代码输出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi()
//输出"John: hi!"
//2. 下面代码输出什么,为什么
func()
function func() {
alert(this)
}
//输出window, 因为func()是在全局环境下调用的, 全局环境绑定的是window对象
//3. 下面代码输出什么
function fn0(){
function fn(){
console.log(this);
}
fn();
}
fn0();//输出window对象
document.addEventListener('click', function(e){
console.log(this);//输出dom节点document
setTimeout(function(){
console.log(this);//输出window对象
}, 200);
}, false);
//4. 下面代码输出什么,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john)
//"John"
//因为call的第一个参数指定this的值
//5. 代码输出?
var john = {
firstName: "John",
surname: "Smith"
}
function func(a, b) {
alert( this[a] + ' ' + this[b] )
}
func.call(john, 'firstName', 'surname')
//输出"John Smith"
//6. 以下代码有什么问题,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指什么, 当$btn被点击的时候, this指向$btn
this.showMsg();
})
},
showMsg: function(){
console.log('饥人谷');
}
}
//问题: this指向只有当函数调用是才确定, 当$btn点击的时候, this指的是$btn, 而不是module
//修改:
var module= {
bind: function(){
var that = this
$btn.on('click', function(){
console.log(that)
that.showMsg();
})
},
showMsg: function(){
console.log('饥人谷');
}
}
网友评论