prototype.js学习(1)

prototype.js学习(1) 1、关于javascript的apply和call函数prototype.js中用了大量的apply和call函数,不注意会造成理解偏差。官方解释:应用某一对象的一个方法,用另一个对象替换当前对象。apply与call的区别是第二个参数不同。apply是 数组或者arguments对象。而call是逗号隔开的任何类型。apply,call方法最让人混淆的地方也是apply,call的

大家好,又见面了,我是你们的朋友全栈君。 
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.
}

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/163408.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 。net 页面跳转大全

    。net 页面跳转大全①response.redirect这个跳转页面的方法跳转的速度不快,因为它要走2个来回(2次postback),但他可以跳转到任何页面,没有站点页面限制(即可以由雅虎跳到新浪),同时不能跳过登录保护。但速度慢是其最大缺陷!redirect跳转机制:首先是发送一个http请求到客户端,通知需要跳转到新页面,然后客户端在发送跳转请求到服务器端。需要注意的是跳转后内部空间保存的所有数据信息将会丢失…

  • mt4数据api接口_外汇api

    mt4数据api接口_外汇api1、MT4API交易接口是什么?MT4Api接口是跨平台多账号交易接口,是将MT4交易通道以API的方式聚合在一起,帮助开发商在各经纪商不提供manager后台账号、无须EA插件的情况下,也能轻松接入不同的MT4交易平台,完成登录、交易和订单查询的功能,真正实现跨平台交易,减少巨额的人工成本和硬件成本。适合开发行情展示或者订单管理,交易策略等,如果开发实力可以,你甚至可以用他开发一个MT4客户端!此MT4API比使用MT4终端进行报价和交易要快得多;提供实时开仓、平仓等多种功能。2、MT4API的协

  • DB9 公头母头引脚定义及连接

    DB9 公头母头引脚定义及连接

  • RUST开服教程、常用指令及心得[通俗易懂]

    RUST开服教程、常用指令及心得[通俗易懂]【前言】【开始前你需要了解的事情】①常用网址②更新与删档日期③目前国服环境【服务器硬件的选择】【标准服务器】①下载和更新服务器②制作服务器的启动脚本③选择你的服务器地图④运行服务器【模组服务器】①完成标准服务器的下载和设置②安装Oxide插件平台③下载插件④安装插件⑤调试插件⑥模组服的更新⑦在标准服中使用插件功能【在自己的电脑上运行服务端】①…

  • Okhttp 之 okio

    Okhttp 之 okio本文是的前一篇文章OkhttpIO之Segment&amp;SegmentPool的基础上写的,如果你没看懂前面的文章,那么看本文会相当的吃力,因为很多关键的代码都是在前面这篇文章中剖析的。ByteStringokio中添加一个类ByteString,顾名思义就是字节串,这里做一个概要的讲解,具体的实现大家可以去看源码。既然是字节串,它内部就是用一个字节数组支持的。…

  • Windows配置Java环境变量(下载、安装、配置环境)[通俗易懂]

    Windows配置Java环境变量(下载、安装、配置环境)[通俗易懂]本人以博客专家担保,本篇文章可以解决你的问题,若未解决,将为你远程操作,但希望你为我点一个关注!!!推荐文章MySql5.7安装教程(超详细)https://myhub.blog.csdn.net/article/details/103532734(JavaSE)目录下载、安装配置环境变量下载、安装进入官网下载https://www.oracle.com/…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号