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..]);