- 浏览: 583817 次
文章分类
- 全部博客 (174)
- Core Java 学习 (6)
- Hibernate 学习 (3)
- Struts 学习 (3)
- Spring 学习 (9)
- EJB 学习 (0)
- 设计模式 (0)
- Oracle 学习 (6)
- JRuby (0)
- PHP (18)
- MySql (7)
- Apache (6)
- Informix (2)
- JSTL (1)
- CSS+HTML (8)
- Ajax (2)
- javaScript (16)
- reverse Ajax (1)
- Discuz (7)
- 网站 (11)
- SEO (5)
- Linux (4)
- ecshop (1)
- 电子商务 (1)
- 文档在线浏览 (18)
- 服务器技术 (10)
- flex (17)
- 用户体验 (1)
- java (1)
- flex+blazeDS (1)
- tomcat (1)
- 开发管理 (1)
最新评论
-
niaoqq1:
真坑爹,全是中文字符,复制全部报错!
<c:forEach 详解 -
jhys7s8jd:
pdf打印机下载http://www.onlinedown.n ...
命令行下转换word文档成PDF -
海豚12315:
flashPaper读取磁盘上的文件路径,
最好是放到某个系统 ...
在线文档阅读实现的解决方案 -
八月约克:
火狐不支持这个东东
Scripting.Dictionary的使用 -
longgol:
有一问:怎么通过flashPaper读取磁盘上的文件路径呢。我 ...
在线文档阅读实现的解决方案
关于javascript的apply和call函数
- 博客分类:
- javaScript
1、关于javascript的apply和call函数
prototype.js中用了大量的apply和call函数,不注意会造成理解偏差。
官方解释:应用某一对象的一个方法,用另一个对象替换当前对象。
apply与call的区别是第二个参数不同。apply是 数组或者arguments 对象。而call是逗号隔开的任何类型。
apply,call方法最让人混淆的地方也是apply,call的特色。但最好不要滥用。
能改变调用函数的对象。如下例,函数中用到this关键字,这时候this代表的是apply,call函数的第一个参数。
<script src="prototype1.3.1.js"></script>
<input type="text" id="myText" value="input text">
<script>
function Obj(){
this.value="对象!";
}
var value="global 变量";
function Fun1(){
alert(this.value);
}
window.Fun1();
Fun1.apply(window);
Fun1.apply($('myText'));
Fun1.apply(new Obj());
</script>
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.bind Function.prototype.bindAsEventListener两个方法。首先我们从概念上解释一个这两个方法。
任何一个函数都可以调用这两个方法;参数的是javascript对象或网页上元素对象;返回类型是个函数对象。
本来我就是个函数,返回还是函数,到这两个函数有什么不同呢。看实现代码,关键还是apply\call函数的代码。其实这里只是转化了一下方法调用的对象。
<script src="prototype1.3.1.js"></script>
<input type=checkbox id=myChk name="asf" value=1> Test
<script>
var CheckboxWatcher = Class.create();
CheckboxWatcher.prototype = {
initialize: function(chkBox, message) {
this.chkBox = $(chkBox);
this.message = message;
this.chkBox.onclick = this.showMessage.bindAsEventListener(this);
},
showMessage: function(evt) {
alert(this.message + ' (' + evt.type + ')');
}
};
new CheckboxWatcher('myChk','message!!!!');
//$('myChk').onclick=function(){};
</script>
这是 https://compdoc2cn.dev.java.net/ 上举的例子,个人感觉没什么意思,反而让我对bind,bindAsEventListener有些反感。(javascript就是这样,明明大家都知道的语法,但写出来的代码差别确很大)
看下面代码:
<script src="prototype1.3.1.js"></script>
<input type=checkbox id=myChk name="chk" value=1> Test
<script>
function Class(){
this.name="class";
}
Class.prototype.getName=function(){
alert(this.name);
}
var obj=new Class();
//$('myChk').onclick=obj.getName;
$('myChk').onclick=obj.getName.bind(obj);
//$('myChk').onclick=obj.getName.bind($('myChk'));
</script>
从上面代码可以看出bind/bindAsEventListener只是包装了一下apply/call方法,改变方法的调用对象。如例子,你可以把obj.getName方法转化成任何对象调用,并且把方法让表单元素触发。(bind和bindAsEventListener之间只是返回函数的参数不同)
这两个方法也可以用在对象之间的方法重用,实现类似继承方法的概念。看以下代码,其实是比较无聊的。
<script src="prototype1.3.1.js"></script>
<script>
function Class1(name){
this.name=name;
}
Class1.prototype.getName=function(){
alert(this.name);
}
function Class2(name){
this.name=name;
this.getName=Class1.prototype.getName.bind(this);
}
var obj1=new Class2("yql");
obj1.getName();
var obj2=new Object();
obj2.name="zkj";
obj2.fun=Class1.prototype.getName.bind(obj2);
obj2.fun();
</script>
我从来没读过prototype.js的扩展项目代码,也不知道bind..的最佳实践,一起挖掘吧。但你绝对不要把bind/bindAsEventListener从绑定的词义上来理解,可能会让你更加迷惑。从apply/call理解本质。应用某一对象的一个方法,用另一个对象替换当前对象。
5、关于事件的注册
<script src="prototype1.3.1.js"></script>
<input type=checkbox id=myChk name="chk" value=1> Test
<script>
Event.observe(myChk, 'click', showMessage, false);
//$('myChk').onclick=showMessage;
//$('myChk').onclick=showMessage.bind();
$('myChk').onclick=showMessage.bind($('myChk'));
function showMessage() {
alert(this.value);
}
</script>
执行上面代码,你就能明白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.
}
有时间我想用以上思想实现一个网页浮动框拖拉的代码(其实已经有很多了),待续........
发表评论
-
JS中对象中的公有方法、私有方法、特权方法
2012-05-26 18:25 4708了解如何创建一个对象的时候,我们就需要给这个对象增加方法 ... -
注意细节:Javascript中的变量作用域
2012-05-21 03:04 887先看一下这段Javascript脚本代码: 1< ... -
JavaScript中对象的构造方法
2012-03-07 13:03 958第一种方式: 工厂方法 能创建并返回特定类型的对象的工厂 ... -
函数中定义 var self = this 的作用
2011-12-21 16:19 3422function Class1(){ ... -
ie6下的js调试工具companion.js
2010-12-03 15:28 1442做web开发的朋友都清楚,js程序的调试是相当郁闷的,因为 ... -
gb2312转换utf-8 utf-8转换gb2312 javascript urlencode解码 Hex Asc Chr
2010-06-23 16:44 3947在我的前一篇文章里面已经实现了用javascript给urle ... -
avascript判断浏览器和操作系统类型
2009-11-07 00:35 812var ua = navigator.userAgent. ... -
JS eval()函数
2009-08-27 23:30 1502eval()函数 Jav ... -
几种js方法调用
2009-08-25 23:35 890// 第一种var i = function() { re ... -
js计算字符个数,包括中文
2009-07-14 09:55 3872<SCRIPT language="JavaS ... -
揭开正则表达式的神秘面纱
2009-03-25 14:16 925引言 正则表达式(regular expres ... -
js判断浏览器版本
2009-02-07 17:19 1301function getIEVersion() { i ... -
JS获取表格单元格
2009-02-04 21:00 2427var ccell = document.getE ... -
javascript---window.location和window.open
2008-11-20 18:57 4360window.open 用来打开新窗口 window.loca ... -
setInterval()、setTimeout()的区别与停止
2008-11-20 18:26 1542区别:setTimeout(表达式,延时时间);//只执行一次 ...
相关推荐
JavaScript中的apply和call函数详解_.docx
JavaScript函数之call、apply以及bind方法案例详解 总结 1、相同点 2、区别 call() 方法 /* 正常模式 */ let obj = { sum(a, b) { console.log(this) return a + b } } // 执行 sum 函数的 apply、bind...
每个JavaScript函数都会有很多附属的(attached)方法,包括toString()、call()以及apply()。听起来,你是否会感到奇怪,一个函数可能会有属于它自己的方法,但是记住,JavaScript中的每个函数都是一个对象。看一下 ...
主要介绍了JavaScript中函数(Function)的apply与call理解,本文讲解了JavaScript函数调用分为4中模式以及通过apply和call实现扩展和继承两方面,需要的朋友可以参考下
一些简单的Javascript操作中较少会用到call和apply函数,在另外一些较大型的操作中,如web应用开发,js框架开发中可能会经常遇到这两个函数。关于这两个函数的解释,网上的资料也很多,但是本人认为很多资料要么...
apply和call,它们的作用都是将函数绑定到另外一个对象上去运行,两者仅在定义参数的方式有所区别: Function.prototype.apply(thisArg,argArray); Function.prototype.call(thisArg[,arg1[,arg2…]]); 从函数原型...
一.call函数 a.call(b); 简单的理解:把a对象的方法应用到b对象上(a里如果有this,会指向b) call()的用法:用在函数上面 var Dog=function(){ this.name="汪星人"; this.shout=function(){ alert(this.name&...
js代码-JavaScript的call/apply/bind函数实现
主要介绍了javascript基于原型链的继承及call和apply函数用法,结合实例形式较为详细的分析了javascript中继承的概念、创建方法以及call和apply函数的功能与使用技巧,需要的朋友可以参考下
在Javascript中,Function是一种对象。Function对象中的this指向决定于函数被调用的方式,使用apply,call 与 bind 均可以改变函数对象中this的指向。
本文实例分析了JavaScript函数apply()和call()用法与异同。分享给大家供大家参考,具体如下: JavaScript的函数是对象,因此有属性和方法。每个函数都包含两个属性:length和prototype,每个函数都包含两个非继承而...
这篇文章主要介绍了JavaScript函数Call、Apply原理实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一、方法重用 使用 call() 方法,您可以编写能够在...
在谈论JavaScript中apply、call和bind这三兄弟之前,我想先说下,函数的调用方式有哪些: •作为函数 •作为方法 •作为构造函数 •通过它们的call()和apply()方法间接调用 前面的三种调用方法,我们都知道且不...
在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,一般来说,this总是指向调用某个方法的对象,但是使用call()和apply()方法时,就会改变this的指向 语法: apply() 接收两...
主要介绍了从JQuery源码分析JavaScript函数的apply方法与call方法,本文结合JQuery源码和js高级程序设计再次探究apply方法与call方法,需要的朋友可以参考下
目录 一、 函数内 this 的指向1、普通函数2、构造函数3、对象方法4、事件绑定方法5、定时器函数6、立即执行函数二、改变函数内部 this 指向1、call 方法2、apply 方法3、bind 方法三、call apply bind 总结1、...
简单的说就是改变函数执行的上下文,... 这两个方法通常被用来类的继承和回调函数: 作用一、类的继承: 先来看这个例子: 代码如下: function Person(name,age){ this.name = name; this.age=age; this.alertName = f