prototype.js学习(1)
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(); //global 变量
Fun1.apply(window); //global 变量,相当于执行window.Fun1();(把Fun1函数应用在Window对象上,即Window.Fun1())
Fun1.apply($('myText')); //input text,相当于执行 $('myText').Fun1();
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').οnclick=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').οnclick=obj.getName;
$('myChk').οnclick=obj.getName.bind(obj);
//$('myChk').οnclick=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').οnclick=showMessage;
//$('myChk').οnclick=showMessage.bind();
$('myChk').οnclick=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.
}
有时间我想用以上思想实现一个网页浮动框拖拉的代码(其实已经有很多了),待续........
prototype.js学习(1)相关推荐
- ajaxPro /prototype.js 学习笔记
以下均为个人理解,如有不妥,请及时指正. 1. 定义和实现类之间的继承 A. 通过 直接引用和函数调用 function Child(name,age,sex) { this.name = name ...
- prototype.js教程及prototype中文手册
在线API文档: http://www.prototypejs.org/api 1.4网页版: http://thinhunan.cnblogs.com/archive/2006/04/01/De ...
- prototype使用学习手册指南之Position.js
Position是prototype中定义的一个对象,提供了操作DOM中与位置相关的方法,要很好的理解元素在页面中的位置,具体代码如下,按照代码说说,其中英文是作者的注释,中文的才是偶的说明或翻译英文 ...
- prototype.js 1.4版开发者手册
prototype.js是什么? 万一你没有使用过大名鼎鼎的prototype.js,那么让我来告诉你,prototype.js是由Sam Stephenson写的一个javascript类库.这个构 ...
- 转载:Prototype.js的中文使用手册
转载自:http://thinhunan.cnblogs.com/archive/2006/04/01/DeveloperNotesForPrototype.html 转载仅为翻阅学习方便.感谢原文作 ...
- prototype.js开发笔记(转)
prototype.js开发笔记 Table of Contents 1. Programming Guide 1.1. Prototype是什么? 1.2. 关联文章 1.3. 通用性方法 1.3. ...
- prototype.js开发者手册
prototype.js开发者手册 对应版本1.4.0 original article by sp('Sergio Pereira') Sergio Pereira last update: Mar ...
- prototype.js详解
prototype.js是什么? 万一你没有使用过大名鼎鼎的prototype.js,那么让我来告诉你,prototype.js是由Sam Stephenson写的一个javascript类库.这个构 ...
- JS学习笔记(九)深拷贝浅拷贝【Array、Object为例】
JS学习笔记(九) 本系列更多文章,可以查看专栏 JS学习笔记 文章目录 JS学习笔记(九) 一.赋值&复制 二.浅拷贝(shallow copy) 1. 什么是浅拷贝 2. 数组的浅拷贝 ( ...
- 千锋Node.js学习笔记
千锋Node.js学习笔记 文章目录 千锋Node.js学习笔记 写在前面 1. 认识Node.js 2. NVM 3. NPM 4. NRM 5. NPX 6. 模块/包与CommonJS 7. 常 ...
最新文章
- 使用多级分组报表展现分类数据
- python url配置单独放在某个应用目录中
- netflix 模式创新_创新设计模式:工厂模式
- Spring Boot通过@RequestParam接收前端表单传来的数据
- Linux: Apache 安全设定
- Java面试之JVM参数调优
- 传网易、京东6月相继赴港上市:共计筹资50亿美元
- 猜数游戏用Python应该这样写
- 【Spring Boot 实战】数据库千万级分库分表和读写分离实战
- 转行程序员深漂的这三年 #2
- Java学习笔记-Java概述和环境配置
- Linux常用指令指南
- 最新可使用在线音乐网站+多解析源码
- WebGIS开发培训(ArcGIS API for JavaScript方向)
- linux gmac驱动分析,以太网驱动流程浅析(一)-ifconfig主要流程
- 2022-2028年中国粮食物流行业市场发展调研及未来前景规划报告
- amCharts使用方式
- vue vue-quill-editor 富文本 改变图片大小
- html和linux下目录路径中 杠,点杠,点点杠区别
- 如何把标签输出为PDF文件
热门文章
- 【路径规划】基于matlab改进的粒子群算法路径规划【含Matlab源码 491期】
- 【单目标优化求解】基于matlab海洋捕食者算法(MPA)求解单目标问题【含Matlab源码 478期】
- 【跌倒检测】基于matlab中值滤波+二值化跌倒检测【含Matlab源码 344期】
- android自定义sufaceview,Android自定义SurfaceView实现画板功能
- 机器学习 结构化数据_聊天机器人:根据结构化数据创建自然语言
- 集群为什么最少6个_结构化面试答题技巧:多年的经验告诉你,最少要注意这6个方面...
- mysql数据库数据表的指令_mysql数据库和表操作命令
- 让一个.sh文件一直运行_想做AI鉴黄工具?这有一个内含20多万张“不可描述”图片的数据集...
- windows mysql 5.5 升级_windows环境mysql5.0晋级mysql5.5
- java面试jquery问题_20个最常见的jQuery面试问题及答案