
prototype(JS对象)
在JavaScript中,prototype对象是实现面向对象的一个重要机制。
每个函式就是一个对象(Function),函式对象都有一个子对象 prototype对象,类是以函式的形式来定义的。prototype表示该函式的原型,也表示一个类的成员的集合。
基本介绍
- 中文名:prototype
- 性质:JS对象
- 套用:JavaScript
- 人物:Sam Stephenson
简介
在通过new创建一个类的实例对象的时候,prototype对象的成员都成为实例化对象的成员。
1、该对象被类所引用,只有函式对象才可引用;
2、在new实例化后,其成员被实例化,实例对象方可调用。
同时,函式是一个对象,函式对象若直接声明成员,不用被实例化即可调用。
prototype.js优点
prototype.js是由Sam Stephenson写的一个javascript类库。该框架的设计思路巧妙,而且兼容标準的类库,能够帮助开发人员轻鬆建立有互动性良好的web2.0特性富客户端页面。
使用$()方法
$() 方法是在DOM中使用过于频繁的 document.getElementById() 方法的一个便利的简写,就像这个DOM方法一样,这个方法返回参数传入的id的那个元素。
比起DOM中的方法,这个更胜一筹。你可以传入多个id作为参数然后 $() 返回一个带有所有要求的元素的一个 Array 对象。
<html><head> <meta charset="UTF-8"> <title>Test Page</title> <script src="prototype-1.3.1.js"></script> <script> function test1() { var d = $('#myDiv'); alert(d.innerHTML); } function test2() { var divs = $('#myDiv, #myOtherDiv'); for (i = 0; i < divs.length; i++) { alert(divs[i].innerHTML); } } </script></head><body> <div id="myDiv"> <p>This is a paragraph</p> </div> <div id="myOtherDiv"> <p>This is another paragraph</p> </div> <input type="button" value=Test1 onclick="test1();"> <br> <input type="button" value=Test2 onclick="test2();"></body></html>
另外一个好处是,这个函式能传入用string表示的对象ID,也可以传入对象本身,这样,在建立其它能传两种类型的参数的函式时非常有用。
使用$F()函式
$F()函式是另一个大受欢迎的“快捷键”,它能用于返回任何表单输入控制项的值,比如text box,drop-down list。这个方法也能用元素id或元素本身做为参数。
<script>function test3(){alert( $F('#userName') );}</script><input type="text" id="userName" value="Joe Doe"><br><input type="button" value=Test3 onclick="test3();"><br>
使用$A()函式
$A()函式能把它接收到的单个的参数转换成一个Array对象。
这个方法,结合被本类库扩展了的Array类,能方便的把任何的可枚举列錶转换成或拷贝到一个Array对象。一个推荐的用法就是把DOM Node Lists转换成一个普通的Array对象,从而更有效率的进行遍历,请看下面的例子。
<script>function showOptions(){var someNodeList = $('#lstEmployees').getElementsByTagName('option');var nodes = $A(someNodeList);nodes.each(function(node){alert(node.nodeName + ': ' + node.innerHTML);});}</script><select id="lstEmployees" size="10" ><option value="5">Buchanan, Steven</option><option value="8">Callahan, Laura</option><option value="1">Davolio, Nancy</option></select><input type="button" value="Show the options" onclick="showOptions();" >
使用$H() 函式
$H()函式把一些对象转换成一个可枚举的和联合数组类似的Hash对象。
<script>function testHash(){//let's create the objectvar a = {first: 10,second: 20,third: 30};//now transform it into a hashvar h = $H(a);alert(h.toQueryString()); //displays: first=10&second=20&third=30}</script>
使用$R()函式
$R()是new ObjectRange(lowBound,upperBound,excludeBounds)的缩写。
跳到ObjectRange 类文档可以看到一个关于此类的完整描述. 此时,我们还是先来看一个例子以展示这个缩写能代替哪些方法吧。其它相关的一些知识可以在Enumerable 对象文档中找到。
<script>function demoDollar_R() { var range = $R(10, 20, false); range.each(function(value, index) { alert(value); });}</script><input type="button" value="Sample Count" onclick="demoDollar_R();" >
使用Try.these()函式
Try.these() 方法使得实现当你想调用不同的方法直到其中的一个成功正常的这种需求变得非常容易, 他把一系列的方法作为参数并且按顺序的一个一个的执行这些方法直到其中的一个成功执行,返回成功执行的那个方法的返回值。
在下面的例子中, xmlNode.text在一些浏览器中好用,但是xmlNode.textContent在另一些浏览器中正常工作。 使用Try.these()方法我们可以得到正常工作的那个方法的返回值。
<script>function getXmlNodeValue(xmlNode){ return Try.these( function() {return xmlNode.text;}, function() {return xmlNode.textContent;} );}</script>
Ajax对象
上面提到的共通方法非常好,但是面对它吧,它们不是最高级的那类东西。它们是吗?你很可能自己编写了这些甚至在你的脚本里面有类似功能的方法。但是这些方法只是冰山一角。
我很肯定你对prototype.js感兴趣的原因很可能是由于它的AJAX能力。所以让我们解释当你需要完成AJAX逻辑的时候,这个包如何让它更容易。
Ajax 对象是一个预定义对象,由这个包创建,为了封装和简化编写AJAX 功能涉及的狡猾的代码。 这个对象包含一系列的封装AJAX逻辑的类。我们来看看其中几个类。
使用Ajax.Request类
如果你不使用任何的帮助程式包,你很可能编写了整个大量的代码来创建XMLHttpRequest对象并且异步地跟蹤它的进程, 然后解析出回响并处理它。当你不需要支持多于一种类型的浏览器时你会感到非常的幸运。
为了支持 AJAX 功能。这个包定义了 Ajax.Request 类。
假如你有一个应用程式可以通过url http://yoursever/app/get_sales?empID=1234&year=1998与伺服器通信。它返回下面这样的XML 回响。
<?xml version="1.0" encoding="utf-8" ?><ajax-response><response type="object" id="productDetails"><monthly-sales><employee-sales><employee-id>1234</employee-id><year-month>1998-01</year-month><sales>$8,115.36</sales></employee-sales><employee-sales><employee-id>1234</employee-id><year-month>1998-02</year-month><sales>$11,147.51</sales></employee-sales></monthly-sales></response></ajax-response>
用 Ajax.Request对象和伺服器通信并且得到这段XML是非常简单的。下面的例子演示了它是如何完成的。
<script>function searchSales() { var empID = $F('#lstEmployees'); var y = $F('#lstYears'); var url = 'http://yoursever/app/get_sales'; var pars = 'empID=' + empID + '&year=' + y; var myAjax = new Ajax.Request(url, { method: 'get', parameters: pars, onComplete: showResponse });}function showResponse(originalRequest) { //put returned XML in the textarea $('result').value = originalRequest.responseText;}</script><select id="lstEmployees" size="10" onchange="searchSales()"><option value="5">Buchanan, Steven</option><option value="8">Callahan, Laura</option><option value="1">Davolio, Nancy</option></select><select id="lstYears" size="3" onchange="searchSales()"><option selected="selected" value="1996">1996</option><option value="1997">1997</option><option value="1998">1998</option></select><br><textarea id=result cols=60 rows=10 ></textarea>
你注意到传入 Ajax.Request构造方法的第二个对象了吗? 参数{method: 'get', parameters: pars, onComplete: showResponse} 表示一个匿名对象的真实写法。他表示你传入的这个对象有一个名为 method 值为 'get'的属性,另一个属性名为 parameters 包含HTTP请求的查询字元串,和一个onComplete 属性/方法包含函式showResponse。
还有一些其它的属性可以在这个对象里面定义和设定,如 asynchronous,可以为true 或 false 来决定AJAX对伺服器的调用是否是异步的(默认值是 true)。
这个参数定义AJAX调用的选项。在我们的例子中,在第一个参数通过HTTP GET命令请求那个url,传入了变数 pars包含的查询字元串, Ajax.Request 对象在它完成接收回响的时候将调用showResponse 方法。
也许你知道, XMLHttpRequest在HTTP请求期间将报告进度情况。这个进度被描述为四个不同阶段:Loading, Loaded, Interactive, 或 Complete。你可以使 Ajax.Request 对象在任何阶段调用自定义方法 ,Complete 是最常用的一个。想调用自定义的方法只需要简单的在请求的选项参数中的名为 onXXXXX 属性/方法中提供自定义的方法对象。 就像我们例子中的 onComplete 。你传入的方法将会被用一个参数调用,这个参数是 XMLHttpRequest 对象自己。你将会用这个对象去得到返回的数据并且或许检查包含有在这次调用中的HTTP结果代码的 status 属性。
还有另外两个有用的选项用来处理结果。我们可以在onSuccess 选项处传入一个方法,当AJAX无误的执行完后调用, 相反的,也可以在onFailure选项处传入一个方法,当伺服器端出现错误时调用。正如onXXXXX 选项传入的方法一样,这两个在被调用的时候也传入一个带有AJAX请求的XMLHttpRequest对象。
我们的例子没有用任何有趣的方式处理这个 XML回响, 我们只是把这段XML放进了一个文本域里面。对这个回响的一个典型的套用很可能就是找到其中的想要的信息,然后更新页面中的某些元素, 或者甚至可能做某些XSLT转换而在页面中产生一些HTML。
在1.4.0版本中,一种新的事件回传外理被引入。如果你有一段代码总是要为一个特殊的事件执行,而不管是哪个AJAX调用引发它,那幺你可以使用新的Ajax.Responders对象。
假设你想要在一个AJAX调用正在运行时,显示一些提示效果,像一个不断转动的图示之类的,你可以使用两个全局事件Handler来做到,其中一个在第一个调用开始时显示图示,另一个在最后一个调用完成时隐藏图示。看下面的例子。
<script>var myGlobalHandlers = { onCreate: function() { Element.show('systemWorking'); }, onComplete: function() { if(Ajax.activeRequestCount == 0) { Element.hide('systemWorking'); } }};Ajax.Responders.register(myGlobalHandlers);</script><div id='systemWorking'><img src='spinner.gif'>Loading...</div>
更完全的解释,请参照 Ajax.Request 参考 和 Ajax选项参考。
使用Ajax.Updater类
如果你的伺服器的另一端返回的信息已经是HTML了,那幺使用这个程式包中 Ajax.Updater 类将使你的生活变得更加得容易。用它你只需提供哪一个元素需要被AJAX请求返回的HTML填充就可以了,例子比我写说明的更清楚。
<script>function getHTML() { var url = 'http://yourserver/app/getSomeHTML'; var pars = 'someParameter=ABC'; var myAjax = new Ajax.Updater('placeholder', url, { method: 'get', parameters: pars });}</script><input type=button value=GetHtml onclick="getHTML()"><div id="placeholder"></div>
你可以看到,这段代码比前面的例子更加简洁,不包括 onComplete 方法,但是在构造方法中传入了一个元素id。 我们来稍稍修改一下代码来描述如何在客户端处理伺服器段错误成为可能。
我们将加入更多的选项, 指定处理错误的一个方法。这个是用 onFailure 选项来完成的。我们也指定了一个 placeholder 只有在成功请求之后才会被填充。为了完成这个目的我们修改了第一个参数从一个简单的元素id到一个带有两个属性的对象, success (一切OK的时候被用到) 和 failure (有地方出问题的时候被用到) 在下面的例子中没有用到failure属性,而仅仅在 onFailure 处使用了 reportError 方法。
<script>function getHTML() { var url = 'http://yourserver/app/getSomeHTML'; var pars = 'someParameter=ABC'; var myAjax = new Ajax.Updater({success: 'placeholder'}, url, { method: 'get', parameters: pars, onFailure: reportError });}function reportError(request) { alert('Sorry. There was an error.');}</script><input type=button value=GetHtml onclick="getHTML()"><div id="placeholder"></div>
如果你的伺服器逻辑是连同HTML 标记返回JavaScript 代码, Ajax.Updater对象可以执行那段JavaScript代码。为了使这个对象对待回响为JavaScript,你只需在最后参数的对象构造方法中简单加入evalScripts: true属性。但是值得提醒的是,像这个选项名evalScripts暗示的,这些脚本会被执行,但是它们不会被加入到Page的脚本中。“有什幺区别?”,可能你会这样问。我们假定请求地址返回的东东像这样:
<script language="javascript" type="text/javascript">function sayHi(){ alert('Hi');}</script><input type=button value="Click Me" onclick="sayHi()">
如果你以前这样尝试过,你知道这些脚本不会如你所期望的那样工作,原因是这段脚本会被执行,但像上面这样的脚本执行并不会创建一个名叫sayHi的函式,它什幺也不做。如果要创建一个函式,我们应当把代码改成下面这个样子:
<script language="javascript" type="text/javascript">sayHi = function(){ alert('Hi');};</script><input type=button value="Click Me" onclick="sayHi()">
为什幺我们在上面的代码中不使用var关键字来声明这个变数呢(指sayHi ),因为那样做创建出来的函式将只是当前脚本块的一个局部变数(至少在IE中是这样)。不写var关键字,创建出来的对象的作用域就是我们所期望的window。
建立循环
你知道,我们都是这样来做循环的,建一个Array,用elements组织它们,再建一个循环结构(例如for,foreach,while)通过index数字来访问每一个element,再用这个element做一些动作。
当你想到这时,你会发现几乎每次写循环代码你都会迟早用到一个Array。那幺,如果Array对象能够提供更多的功能给它们的叠代器使用不是很爽吗?确实是这样,事实上很多的程式语言都在它们的Array或其它类似的结构中(如Collections,Lists)提供一些这样的功能。
现在好了,prototype.js了给我们一个 Enumerable对象,它实现了很多和可叠代数据进行互动的窍门。和原有的JS对象相比prototype.js更上一层楼,它对Array 类s扩展了所有枚举要用的函式。
循环, Ruby样式的
在标準的javascript中,如果你想把一个array中的所有elements显示出来,你可以像下面代码这样写得很好:
<script>function showList(){ var simpsons = ['Homer', 'Marge', 'Lisa', 'Bart', 'Meg']; for(i=0;i<simpsons.length;i++){ alert(simpsons); }}</script><input type="button" value="Show List" onclick="showList();" >
使用我们新的最好的朋友,prototype.js,我们可以把它生写成这样
function showList(){ var simpsons = ['Homer', 'Marge', 'Lisa', 'Bart', 'Meg']; simpsons.each( function(familyMember){ alert(familyMember); });}
在继续下面内容之前,你注意到那个被做为一个参数传递给each函式的函式?我们把它理解成叠代器函式。
Your arrays on steroids
就如我们上面提到的,把你的Array中的elements当成相同的类型使用相同的属性和函式是很通用(Common,不知该翻译成通用还是庸俗)的。让我们看看怎幺样利用我们新的马力强劲的Arrays的叠代功能吧。
依照标準找到一个element。
<script>function findEmployeeById(emp_id){ var listBox = $('lstEmployees') var options = listBox.getElementsByTagName('option'); options = $A(options); var opt = options.find( function(employee){ return (employee.value == emp_id);});alert(opt.innerHTML); //displays the employee name}</script><select id="lstEmployees" size="10" ><option value="5">Buchanan, Steven</option><option value="8">Callahan, Laura</option><option value="1">Davolio, Nancy</option></select><input type="button" value="Find Laura" onclick="findEmployeeById(8);" >
现在我们再下一城,看看如何过滤一个Array中的元素,从每个元素中得到我们想要的成员。
<script>function showLocalLinks(paragraph) { paragraph = $(paragraph); var links = $A(paragraph.getElementsByTagName('a')); //find links that do not start with 'http' var localLinks = links.findAll( function(link){ var start = link.href.substring(0,4); return start !='http'; }); //now the link texts var texts = localLinks.pluck('innerHTML'); //get them in a single string var result = texts.inspect(); alert(result);}</script><p id="someText"> This <a href="http://othersite.com/page.html">text</a> has a <a href="#localAnchor">lot</a> of<a href="#otherAnchor">links</a>. Some are <a href="http://wherever.com/page.html">external</a>and some are <a href="#someAnchor">local</a></p><input type=button value="Find Local Links" onclick="showLocalLinks('someText')">
上面的代码仅仅是一点小小的实践让人爱上这种语法。
prototype例子
例子1:给String类封装一个“日期验证”的新的方法
String.prototype.isDate = function(){ var regex = new RegExp("^[\d]([-|/])[\d]{1,2}([-|/])[\d]{1,2}$"); console.log(this); return regex.exec(this);}var strValue = "12512412";alert(strValue.isDate());
Prototype定期执行
很多时候,它需要后一定时间内多次执行一个函式。例如,您可能要刷新一个给定的时间后你的萤幕。原型提供了一个简单的机制来实现它使用周期性的PeriodicalExecuter 对象.
通过PeriodicalExecuter提供的优势是,它禁止对多个并行执行的回调函式.
创建一个定期执行
构造函式有两个参数:
callback 函式。
interval (in seconds) 函式。
一旦启动,PeriodicalExecuter触发下去,直到页面卸载或执行者停止使用stop()方法。
以下是例子,它会弹出一个对话框,每5秒后,直到你按“取消”按钮将停止。
<html><head> <title>Prototype教程 examples - by yiibai </title> <script type="text/javascript" src="/javascript/prototype.js"></script> <script> function startExec(){ new PeriodicalExecuter(function(pe) { if (!confirm('Want me to annoy you again later?')) pe.stop(); }, 5); } </script></head><body> <p>Click start button to start periodic executer:</p> <br /> <input type="button" value="start" onclick="startExec();"/></body></html>
转载请注明出处海之美文 » prototype(JS对象)