网站导航免费论文 原创论文 论文搜索 原创论文 网学软件 学术大家 资料中心 会员中心 问题解答 原创论文 论文素材 设计下载 最新论文 下载排行 论文上传 在线投稿 联系我们
返回网学首页
最新论文 推荐专题 热门论文 素材专题
当前位置: 网学 > 网页素材 > AJAX代码 > 正文
ExtJS 2.2type和eval
来源:Http://myeducs.cn 联系QQ:点击这里给我发消息 作者: 用户投稿 来源: 网络 发布时间: 11/01/18

返回深入学习ExtJS 2.2开发系列连载教程目录
对于变量或对象的类型判断是经常用到的功能,也是每门语言都提供的功能。在C中就提供typeof要判断类型。但是在面向对象中这种判断是不准的。如我通过private Animal cat=new Cat();Cat类是继承Animal类的。如果采用typeof来判断的话,cat的类型是Animal。这样的类型当然是没有错的。但是我们需要的是返回Cat类型。于是面向对象语言大部分都提供了instanceof来判断其运行实例的真正的类型。

typeof分析
Js语言的中typeof也是出现这样的问题。它可以返回六种类型:number、string、boolean、object、function、undefined。对于这六种类型,我们做了下面的测试

var a = [3, 4, 5];
var b = function() {};
var c;

alert("undefined \''s type=" + typeof(undefined));// undefined
alert("null \''s type=" + typeof(null));// object
alert("NaN \''s type=" + typeof(NaN));// number
alert("c \''s type=" + typeof(c));// undefined
alert("d \''s type=" + typeof(d));// undefined

alert("true \''s type=" + typeof(true));// boolean
alert("false \''s type=" + typeof(false));// boolean

alert(" \''s type=" + typeof());// object
alert("Array \''s type=" + typeof(Array));// functtion
alert("[3,4,5] \''s type=" + typeof(a));// object

alert("{} \''s type="));// object

alert("Date \''s type=" + typeof(Date)); // functtion
alert("new Date() \''s type=" + typeof(new Date()));// object

alert("Function \''s type=" + typeof(Function)); // functtion
alert("new Function()\''s type=" + typeof(new Function()));// functtion
alert("function(){} \''s type=" + typeof(b));// functtion

alert("empty char \''s type=" + typeof(""));// string
alert("space \''s type=" + typeof(" "));// string
alert("string sss\''s type=" + typeof(" sss"));// string + typeof( {}

从上面的代码可以看不管是空字符,还是空格,它都当作是string的类型。对于boolean的类型,就是true和false两种。对于 Number类型而言,NaN也就是属于这个类型。undefined的本身或变量没有定义或变量没有初始化(仅仅是定义了)都返回undefined。

上面string,boolean,undefined,number这四种是我们可以接受的类型判断。但是对null的返回值为object,对于通过new原生对象(如Array,Date,String等)的返回值都是object。这个就是不是我们所需要的。对于原生对象本身,它们返回的类型是function。我们也不太满意。

从上面的例子可以看出。原生对象本质其实都是函数类型。Function是构建函数的函数,而new Function()则是构建之后的函数。

为了更好地满足目前的要求。我们应该把对数组等的类型的返回值再精准一步,让其返回Array的类型。而对于null的返回类型应该和undefined一样,返回false。

Ext.type函数
Ext.type则改进了上面的所提出的问题,同时还提供了一些关于元素常用节点的判断。在上一部分,我们可以看出通过new的方式构建的(除Function)都是对象(还有一些直接量,如,{})。那么我们如果把其实质为object的类型更精准一点呢。Array,Date这样原生对象其实都函数。也就是说明原生对象的实例都会有有一个constructor的属性。我们可以通过这个constructor来区分。对于dom元素的节点的类型来讲,我们要先要判断是不是节点,再判断其nodeType是什么类型。Mootools做了很多开创性的工作,它的$type也成为别的类库借鉴的东西。Ext.type就是来自mootools的$type。

type : function(o){
    if(o === undefined || o === null){   return false;        }
    if(o.htmlElement){    return ''element'';  }
    var t = typeof o;
    if(t == ''object'' && o.nodeName) {
       switch(o.nodeType) {
        case 1: return ''element'';
        case 3:return (/\S/).test(o.nodeValue)? ''textnode'':''whitespace'';
             }

        }

   if(t == ''object'' || t == ''function'') {
     switch(o.constructor) {
        case Array: return ''array'';
        case RegExp: return ''regexp'';
         }

   if(typeof o.length == ''number'' && typeof o.item == ''function'') {
        return ''nodelist'';
           }

        }

  return t;
},

通过Ext.type,我们可以判断regexp,array,nodelist等类型。这个只是提供了一个简单的代码,并没有从根本上解决面对对象中instanceof的问题。在mootools1.2中提供了一个更为完美的解决方案。但是那是建立在整个框架的重新架构之上。其实Ext.type已经足够用了,不需要完全的面向对象化。

3.1.3 命名空间的分析
对于命名空间,它实际上就是一个变量,在window的定义的是全局变量,在变量对象或函数中定义的就是局部变量。但是我们不是把这个变量当作存储值来看待或使用。我们把它当作一组或一类东西(函数,类)的空间或领域的归类来看待,同一类或同一组的函数(类)都在同一个命名空间(变量)中。这样变量就成了C#的命名空间或Java中包的概念。

对于Ex.namespace函数,相信基本上是没有人会用到的。因为它的适用的场合也不多。但是其作用却是蛮大的。通过它,我们不需要为每个子命名空间来定义。如Ext.Event.MM空间,我们得通过Var Ext={}, Ext.Event={},Ext.Event.MM来定义。而现在只要通过Ex.namespace(” Ext.Event.MM”)直接定义就可以了。

Ex.namespace的实现也是值得分析的,它通过eval来动态生成命名空间。分析它之前,我们先看一下eval函数。命名空间采用函数来指定的话,也许很多读者觉得没有必要或思虑其的实现机制。

Eval函数的分析
Eval函数能把字符串当作JavaScript表达式或语句一样执行,也就是说我们能通过string的形式来动态地组建来执行的JavaScript语句或其表达式。可以看出Eval函数的功能强大且灵活。

我们可以通过它来计算如”3+5”字符串的数字表达式。我们可以执行如”if(!xx) var xx={}”这样动态字符串的语句。我们还可以通过eval(”({xx:YY})”)来把json字符串转换Json对象。

其格式:Eval(codeString,[override])。

参数 :codeString 必选。JavaScript表达式或语句的字符串。

override 可选项。指执行代码的安全权一般采用默认。
我们可以把Eval支持的codeString分成两种类型:表达式和JavaScript语句。对于表达式而言,Eval能执行或计算它并返回它的结果值。对于Json字符串,把其加上()中间,就是把其转换表达式来处理。不加的话,它就会当作语句来执行,这时的{}就解释成域的范围,计算其第一个属性值并返回。对于JavaScript语句,运行时所在上下文和和eval方法的上下文一样。即其中出现的变量或函数调用必须在eval的上下文环境中是可用的。在第二章中对于默认生成类名的处理就可以用到eval。

加强 增加性能的比较,采用function等自己构建一个eval

Ext.namespace分析
Ext.namespace能一次分配多个命名空间。命名空间可以采用点串(如Ext.Event)的形式来分配。对于和已经存在的命名空间相同的话,就直接采用存在的空间。如Ext自己就采用了它来为自己的类库分配了命名空间:

Ext.ns("Ext", "Ext.util", "Ext.grid", "Ext.dd", "Ext.tree", "Ext.data",
"Ext.form", "Ext.menu", "Ext.state", "Ext.lib", "Ext.layout");

Ext. namespace:

namespace : function(){
   var a=arguments, o=null, i, j, d, rt;
   for (i=0; i<a.length; ++i) {//支持无数多个参数
      d=a[i].split(".");//把点串的命名空间以点来分隔成几部分,对每部分都分配空间                     rt = d[0];
      eval(''if (typeof''+ rt +''=="undefined"){'' + rt +''= {};}o =''+ rt + '';'');
       for (j=1; j<d.length; ++j) {//分配子命名空间
             o[d[j]]=o[d[j]] || {};   o=o[d[j]]; }
            }

        }
,

我们来通过Ext.util这个命名变量来分析一下Ext. namespace内的eval的操作。首先把Ext.util分成两部分,存在d=[Ext, util]的数组中。对于Ext字符,它生成如下的语句:

if (typeof Ext =="undefined"){ Ext = {};} o = Ext;

这一句的上下文是namespace这个函数的内部。这里的Ext在函数内部没有定义,再看看是全局变量。在全局已经定义了。如果没有定义,就在全局生成一个Ext变量空间,其为{}的空对象。接下的o = Ext把Ext这个变量或命名赋值给o这个函数内部的变量。

在接下来的for循环中,先通过o[d[j]]看看Ext的变量空间是否有util这个变量命名,没有或其为空值(undefined)的话,就给Ext的变量空间增加一个util:{}的变量命名。接下把o这个变量指向这个uitl变量命名。进行点串中的下一个子命名空间的分配。这里就没有了。

在上面的代码中,可以看出其实现还是蛮巧妙的。Ext还提供了Ext.ns为Ext.namespace的缩写。我们在开发应用系统时,也是会对于Ext.ns的应用的,因为对于一个采用JavaScript的开发的富客户端。不采用一定的命名规则,其结果是很乱的。比如在本书的例子办公系统就采用了Ext.ns("Morik","Morik.Office", "Morik.Util");这样的方式要给应用系统分层次地命名。



这一节中,我们就Ext类中的extend,type,namespace进行了分析。因为这几个函数有一定的难度且对于整个类库都是很重要的。通过这一节,我们能把握Ext类的设计与实现。

  • 下一篇资讯: ExtJS 2.2Function的扩展
  • 网学推荐

    免费论文

    原创论文

    浏览:
    设为首页 | 加入收藏 | 论文首页 | 论文专题 | 设计下载 | 网学软件 | 论文模板 | 论文资源 | 程序设计 | 关于网学 | 站内搜索 | 网学留言 | 友情链接 | 资料中心
    版权所有 电话:013574892963 QQ:3710167 邮箱:Educs@163.com 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
    Copyright 2008-2015 Www.myeducs.Cn All Rights Reserved
    湘ICP备09003080号