javascript中的apply和call
2014-03-16
javascript中的call 和 apply 都是为了改变某个函数运行时的 context 而存在的,即通过call或者apply用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。两个方法的基本 区别表现在传参不同。
call和apply的语法
call
fun.call(thisObj[, arg1[, arg2[, ...]]])
apply
fun.call(thisObj[, arg1[, arg2[, ...]]])
- call第一个参数传对象,可以是null。参数以逗号分开进行传值,参数可以是任何类型。
- apply第一个参数传对象,参数可以是数组或者arguments 对象。
作用一:类的继承
function student(name,age){
this.name = name;
this.age = age;
this.alertName = function(){
alert(this.name);
}
this.alertAge() = function(){
alert(this.age);
}
}
function girl(name,age,relationship){
student.call(this,name,age);
this.relationship = relationship;
this.alertRelationship = function(){
alert(this.relationship);
}
}
var test = new girl("Helen",17,"single")
test.alertName();//Helen
test.alertAge();//17
test.alertRelationship();//single
作用二:回调函数
很多时候,做开发我们需要回调函数执行上下文,那么这个时候call和apply变得非常重要, 来看一个例子
var socket =
{
connect: function(host, port)
{
alert('Connecting socket server,host:' + host + ',port:' + port);
}
};
function classIm()
{
this.host = '192.168.1.28';
this.port = '8080';
this.connect = function(data)
{
socket.connect(this.host, this.port);
};
}
var IM = new classIm();
$.get('index.html', IM.connect.apply(IM));//弹出Connecting socket server,host:192.168.1.28,port:8080
如果不使用IM.connect.apply(IM),而用IM.connect代替,那么弹出的host与port都是undefined,
那是因为回调函数的this不是指向IM对象,而我们则想要回调函数代码socket.connect(this.host, this.port)中的this指向类
classIm的实例对象IM。使用前者则在这个返回的function中使用apply把调用时对象的this替换为目标对象thisObj。
示例二:
function Album(id, title, owner_id) {
this.id = id;
this.name = title;
this.owner_id = owner_id;
};
Album.prototype.get_owner = function (callback) {
var self = this;
$.get('/owners/' + this.owner_id, function (data) {
callback && callback.call(self, data.name);
});
};
var album = new Album(110, 'jeason', 520);
album.get_owner(function (owner) {
alert('The album' + this.name + ' belongs to ' + owner);
});
这里alert('The album' + this.name + ' belongs to ' + owner)中的this.name就能直接取到album对象中的name属性了
发现
至此总结出函数的三种调用方式
obj.myFunc();
myFunc.call(obj,arg);
myFunc.apply(obj,[arg1,arg2..]);