关于javascript的apply和call函数


======================================================
注:本文源代码点此下载
======================================================

1、关于javascript的apply和call函数

prototype.js中用了大量的apply和call函数,不注意会造成理解偏差。

官方解释:应用某一对象的一个方法,用另一个对象替换当前对象。

apply与call的区别是第二个参数不同。apply是数组或者arguments 对象。而call是逗号隔开的任何类型。

apply,call方法最让人混淆的地方也是apply,call的特色。但最好不要滥用。

能改变调用函数的对象。如下例,函数中用到this关键字,这时候this代表的是apply,call函数的第一个参数。

2、关于闭包

prototype.js在class.create,bind等中用到javascript的闭包特色。但整体上prototype.js对于强大的闭包特性用的不多。大家可以参阅我翻译的篇文章了解闭包。

3、让我比较反感的两个方法

(1)

var class = {

create: function() {

return function() {

this.initialize.apply(this, arguments);

}

}

}

很讨厌用别的语言的风格来写javascript。用这个方法构造自定义类并没有觉得有多方便,减少代码行数,只会让人难理解,多定义一个initialize方法。

其实讨厌这条有些牵强,不过修改object的原型对象就有点过分了。

(2)object.prototype.extend

先不过你取个extend的名字会让熟悉java的人引起的歧义。修改object的prototype就说不过去了。不知道作者是怎么考虑的。当你for in循环对象是,麻烦就来了。可能有人会问你for in干吗。 我一个项目中既用了dwr,也用了prototype.js,dwr返回的javascript对象都多了个exetend属性,还得特殊处理。

以前我比较过dojo和prototype.js中继承的实现,现在我明白个道理。对于javascript这种没有静态类型检查,语法宽松的语言来讲,如果你选择了某个js类库,那你也必须适应作者写javascript的风格。prototype.js的作者对extend的使用炉火纯青,如果我们不当它只是个属性拷贝的函数的话,多读读prototype.js的代码是好的。

4、关于函数的绑定

类库提供了function.prototype.bindfunction.prototype.bindaseventlistener两个方法。首先我们从概念上解释一个这两个方法。

任何一个函数都可以调用这两个方法;参数的是javascript对象或网页上元素对象;返回类型是个函数对象。

本来我就是个函数,返回还是函数,到这两个函数有什么不同呢。看实现代码,关键还是apply\call函数的代码。其实这里只是转化了一下方法调用的对象。

test

这是 https://compdoc2cn.dev.java.net/ 上举的例子,个人感觉没什么意思,反而让我对bind,bindaseventlistener有些反感。(javascript就是这样,明明大家都知道的语法,但写出来的代码差别确很大)

看下面代码:

test

从上面代码可以看出bind/bindaseventlistener只是包装了一下apply/call方法,改变方法的调用对象。如例子,你可以把obj.getname方法转化成任何对象调用,并且把方法让表单元素触发。(bind和bindaseventlistener之间只是返回函数的参数不同)

这两个方法也可以用在对象之间的方法重用,实现类似继承方法的概念。看以下代码,其实是比较无聊的。

我从来没读过prototype.js的扩展项目代码,也不知道bind..的最佳实践,一起挖掘吧。但你绝对不要把bind/bindaseventlistener从绑定的词义上来理解,可能会让你更加迷惑。从apply/call理解本质。应用某一对象的一个方法,用另一个对象替换当前对象。

5、关于事件的注册

test

执行上面代码,你就能明白event.observe与bind/bindaseventlistener之间的区别:

(1) 显然event.observe有限制,只能处理简单的函数,并函数中不能有this之类的东西。

(2)event.observe内部用到addeventlistener/attachevent。能把多个函数加到一个触发事件(window.onload)。bind是覆盖。

6、关于事件监听最佳实践

很显然prototype.js提供的事件注册方法不是很完善。那看看dojo的时间注册吧(中文版),更加复杂,估计很多人像我一样,对于dojo暂时持观望态度。

如果你看过的前篇关于闭包的介绍,可能见过以下代码。

看以下代码前我想表述一个观点,任何网页中元素,浏览器都会为你创建一个对象(见)。(我觉得)这些对象与你建立javascript对象区别是它们有事件监听,会响应鼠标键盘的事件。如果你用了以下代码,那么把事件监听代码很好的转化到你的javascript代码中。

function associateobjwithevent(obj, methodname){

return (function(e){

e = e||window.event;

return obj[methodname](e, this);

});

}

function dhtmlobject(elementid){

var el = getelementwithid(elementid);

if(el){

el.onclick = associateobjwithevent(this, "doonclick");

el.onmouseover = associateobjwithevent(this, "domouseover");

el.onmouseout = associateobjwithevent(this, "domouseout");

}

}

dhtmlobject.prototype.doonclick = function(event, element){

... // doonclick method body.

}

dhtmlobject.prototype.domouseover = function(event, element){

... // domouseover method body.

}

dhtmlobject.prototype.domouseout = function(event, element){

... // domouseout method body.

}

有时间我想用以上思想实现一个网页浮动框拖拉的代码(其实已经有很多了),待续........


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值