`
yunhaifeiwu
  • 浏览: 163212 次
  • 性别: Icon_minigender_1
  • 来自: 宁波
社区版块
存档分类
最新评论

用js书写UI组件之js基础知识

阅读更多


本人在用js书写UI组件道路上正不断探索与学习,下面是自已的理解与学习笔记。欢迎各位
网友指正。本贴内容仅供参考。但有一点,所发的源代码,本人是测试过的。如果因此各各位
带来不便,请谅解!






[color=blue] 特别说明:
    1  本人文中所用的词,也许与各位网页见到的词,概念上有不一致的地方。请各位见谅。本文有许多词
是属于理解之物,请各位注意。重点看例子!通过例子 与文字描述试着理解,如果还理解不了,请各位不要浪费时间了! 再次说明,本文是笔记与探索文,阅读时要严重注意!

    2 本文的例子全部调试通过了的。默认的浏览器是 firefox 3,调试工具是firebug.在印象中会在ie 6下验证能否
是同样的效果,但不能保证每个都会在ie6 下验证。如果没有特别说明,意味着其他浏览器全部没测试。




本博文与另一篇博文《javascript函数式编程---解决事件参数传递问题》
构成了用js实现书写UI组件的基础知识,及实现的技术手段。
笔记很多,仅选用了自认为对同样道路上有用的朋友。
关于封装的总的方法论,时机到了再发布。


3.1 javascript 模拟类
[/color]
说明:
1 在javascript中,函数就是一个特简单的类。定义了一个函数,就定义了一个类。可用var关键字与new关键字为该函数生成一个对象。
例:
function Aa(){var dd="ddd"};//类名是Aa
var aa1=new Aa();//aa1 是类Aa的对象。同时Aa()函数就是Aa类的构造函数。


2 函数中,前缀有“this.”的变量,就是刻函数类的公有变量与公有方法。

3 注意 this 关键字的使用,它指向当前对象。


例 :
<html >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<body> 

<script language=Javascript>
  function Pasta(aaa ){  //构造方法,同时也是类名
       this.aaa= aaa;//定义属性, 
         this.ddd="ddd"; //定义属性,
         this.bb=cc;//定义方法
         this.eee=function(){alert("cc")};//另一种方法定义及实现
 }
 
  function cc(){//方法实现
	  document.write(this.aaa);
  }
  // 另一种方法定义与实现
  Pasta.prototype.dd= function(d){
	 alert(d);
  }
 var xx=new Pasta("hello word");//为类Pasta生成一个名叫xx的对象
 xx.bb("sssss");//使用对象
 xx.dd("sssxxxx");
 xx..eee();

</script>

</body>
</html>





3.2 prototype使用----能简单模拟类

说明: (经walkman指出,在这里作了更改)
(1) 所有函数都具有prototype属性。
(2) 函数可当成一个类,可用new为该函数生成一个函数对象。
(3) 可用prototype为函数动态新增函数属性与方法。
(4) 假定有一个函数名为 Afun,则用prototype可为Afun增加属性与方法。此时所有的Afun对象都具有这些属性与方法。
(5) 特别注意:假定有一个对象名为anObj,但无法用prototype为anObj增加属性与方法。
    如:
function Dd(){};//定义一个空的类
var dd=new Dd();//生成一个Dd对象
;//动态为Dd类增加一个xx属性,从此时起所有的Dd对象都具有xx属性。
Dd.prototype.xx="22";
//动态为Dd类增加一个say函数,从此时起所有的Dd对象都具有say函数。
Dd.prototype.say=function(){alert(this.xx)}; 
dd.say(); //执行后,将显示一个信息框,内容为22
var bb=new Dd();//再生成一个Dd对象
bb.say();//执行后,将显示一个信息框,内容为22
//也就是说bb,dd都能调用用prototype定义的属性与函数

结论:
使用prototype能模拟类


3.3 apply与call 使用

appply是所有函数都具有的方法。其作用时,调用该函数,参数通过参数表的形式传入;同时还传递一个对象到该函数的this对象中。
调用形式: functionName.apply(obj,[“zhang”,”34”]);
其义是:调用functionName函数,其参数是”zhang”,”34”,同时在functionName函数执行时,其内部的this对象还具有一个属性obj。注意:这个obj不是functionNam函数固有的,随着apply调用变化而变化。
     这个apply动态传一个对象到被调用函数的this对象中,是为特殊应用而生。
另外:1  arguments是每个函数都固有的对象,存放着该函的参数
2  call与apply类似,仅参数方式不同。
例:
functionName.call(obj,“zhang”,”34”)



例:

<html >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<body><script language=Javascript>

function parent(name,age){
   this.name=name;
   this.age=age;
   this.say=function(){ 
      alert(this.name);
   }
}

function Son(){
   var dd1="ha ha ha";
   this.tel="11";
   //调用parennt函数,且此时的该函数(即parennt)内的this对象具有dd1的属性。注意:
   //仅限于本次执行时才能确定具有dd1的属性。
   parent.apply(dd1,["zhang"]);
   this.calltel=function(){
      alert(this.tel);
   }

}
var s = new Son("ss","aa");
s.calltel();

</script>
</body>
</html>

用途:
    可用在下面的情景中。
当模拟类继承时,子类构造函数,通过apply调用父类的构造函数。这样执行子类构造函数,也能执行父类的函数。


3.4 模拟类继承

使用prototype与apply实现类继承的模拟。用prototype把父类的公有方法与公有变量加入到子类中去。在子类构造方法中,用apply执行父类的构造方法。
例:

<html >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<body>
 

<script language=Javascript>
  function Parent(){  //父类
	     this.pname="parentName";//父类公有变量
	     this.say=function(){alert(this.pname)};//父类公有方法
	     this.tell=function(){alert(this.pname+"tell")};//父类公有方法
 }
  function Son(){ 
          
	    //以下两句要先执行,不然不能完成方法覆盖
    Son.prototype=new Parent();//得到父类的公有变量与公有方法  
	    Parent.apply(this); //调用父类的构造函数           
     
	    this.sname="sonName";//子类公有变量
	    this.say=function(){alert(this.sname)};//子类公有方法,覆盖了父类的say方法
	    this.talk=function(){alert(this.sname+"talk")};//子类公有方法
 }
 
  var son1=new Son();
  son1.say();//显示 sonName,表时成功覆盖父类
  son1.talk();//显示 sonNametalk ,执行子类自已的方法
  son1.tell();//显示 parentNametell ,执父类没被覆盖的方法。
  son1.pname="父亲老张"; //使用父类的变量 
  son1.tell();//显示 父亲老张  表明成功使用了父类的公有方法与属性
  son1.sname="儿子小张"; //用子类自已的变量
  son1.say(); //显示 儿子小张 表明子类的属性与覆盖方法正常
  son1.talk();//显示 儿子小张 表明子类的属性与方法正常

var son2=new Son();//生成另一个子类,研究子类是否是对父类的方法与变量的拷贝
  son2.pname="母亲李夫人";
  son2.tell();//显示  母亲李夫人; 表明成功使用父类的方法
  son1.tell();//显示 父亲老张;  表明多个子类使用的同名的父类的变量,各有自已的值。 

</script>

</body>
</html>



3.5 用js实现自已定义的类体系

3.5.1 说明:
(1) 本节实例多半摘自悟透javascript一书。
(2) 本节中的类是用javascript语法,实现了自已设定的类体系结构。
(3) Javascript原本是没有类的,只有函数。其他一些章节中提到的类,仅仅是模拟类体系罢了。而这里是要用javascript自已实现一套类体系

3.5.2 语法规定
Create函数-----类的构造函数;
Class 函数------类定义函数
New 函数-----产生类的实例。
object---所有自定义类的基类。
说明:javascript区分大小写,自身的关键字为:new Object
自定义的类,如下形式表式:
var Person ={ //定义名为Person的类
	  Create: function(name, age) {//Create指明构造函数
		  this.name = name;//定义类公有变量
		  this.age = age; //定义类公有变量
	  },
	  SayHello: function(){//定义公有方法
		  alert("Hello, I'm " + this.name);
	  },
	  HowOld: function(){//定义公有方法
	      alert(this.name + " is " + this.age + " years old.");
	  }
};

说明:
(1)上例是自已定义的类体系使用例子。例子中定义了一个名为Person的类,其构造方法,由Create指明。
(2)本例中可直接用Person.SayHello()的形式,调用方法。但是无法得到公有变量值,即name与age.解决方法。
    (3)在调用了Create函数后,Person类就有了name变量与age变量。 为了说明方便见下例:

<html >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<body>

<script language=Javascript>

var Person ={ //定义名为Person的类
	  Create: function(name, age) {//Create指明构造函数
		  this.name = name;//定义类公有变量
		  this.age = age; //定义类公有变量
	  },
	  SayHello: function(){//定义公有方法
		  alert("Hello, I'm " + this.name);
	  },
	  HowOld: function(){//定义公有方法
	      alert(this.name + " is " + this.age + " years old.");
	  }
};

//  //该语句执行后,Penson类就有了name与age变量。
//  Person.Create("dd1","ss1");

function Fun(){Person.Create("dd","ss");};//定义了一个名为Fun的函数,
Fun.prototype=Person;//让Fun拥有Person类的成员

//一旦执行了Fun函数,就执行了Person.Create方法,
//Person.Create方法一执行,Person就有了公有变量name与age
//当Person有了公有变量时,由于Fun中有Person类成员,因此Fun也就有了name变量
//与age变量。
var p =new Fun();
p.SayHello();// 显示“Hello, I'm dd ”, 这表明了p具有了变量name与age.

</script>



3.5.3 New实现
为了生成自定义类的对象,定义了New方法,该方法原型为:
New(aClass, aParams)
其中:aClass 类,该类定义中要有Create方法。aParams类构造函数的参数表.
实现时:
(1)生成一个临时函数,该函数要执行类定义中的Create方法。
(2) 这个临时函数具有aClass对象;
(3) 生成临时函数的对象,并返回给调用者。
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>18-1.html</title>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
</head>
<body>
<script language="javascript">
    //aClass 类,该类定义中有名为Create的函数;aParams 类构造函数的参数表。
    function New(aClass, aParams) { 
        function new_() { //定义临时函数
            aClass.Create.apply(this, aParams); //调用类的构造函数,并执行
        }; 
        
		//让临时函数具有aClass类
        new_.prototype = aClass;  
		//生成临时函数的对象。生成时要执行该临时函数,该临时函数会执行类的
		//构造函数。类构造函数一旦执行,类就有了公有变量,从而拥有该类的临时
		//函数也就具有了类的公有变量。
        var a=new new_();
        return a;          //返回aClass的实例
    }; 
    
    //*******************下面是具自定义类的使用*******************]
	//定义Person类
    var Person = { 
        Create: function(name, age){ //定义构造函数
            this.name = name; //定义公有变量
            this.age = age; //定义公有变量
        }, 
        SayHello: function() { //定义公有方法
            alert("Hello, I'm " + this.name); 
        }, 
        HowOld: function() { //定义公有方法
            alert(this.name + " is " + this.age + " years old."); 
        } 
    }; 
     
    var BillGates = New(Person, ["Bill Gates", 53]);  //生成Person类的实例
	 //使用Person的实例
    BillGates.SayHello();
    BillGates.HowOld(); 
  
</script>
</body>
</html>


3.6 自定义类体系实现及使用
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>20-1.html</title>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
</head>
<body>
<script language="javascript">
    // 根类 实现,注意object不是的关键字。Object才是固有的。
    var object = {  
	     // 判断本实例是否属于指定的类。 
        isA: function(aType)  { 
            var self = this; 
            while(self) 

            { 
                if (self == aType) 
                  return true; 
                self = self.Type; //由于类的继承原故,因此要循环。
            }; 
            return false; 
        } 
    }; 
    
	// 类定义函数 实现。该函数实现了一个类的定义
	//aBaseClass----父类;aClassDefine子类
    function Class(aBaseClass, aClassDefine) { 
	    //临时函数
        function class_()  { 
            this.Type = aBaseClass;  //保存类的父类类型,注:不是祖先类
		    //复制类定义
            for(var member in aClassDefine) 
                this[member] = aClassDefine[member];    
        }; 
		//让临时函数拥有父类
        class_.prototype = aBaseClass; 
		//生成临时函数的对象,并返回。该临时函数不仅有父类成员,也有子类成员,
		//另外还通过type保存了类的父类的类型。
        return new class_(); 
    }; 
    
	//实例生成函数实现
	//aClass---类;aParams---类构造函数的参数表
    function New(aClass, aParams)  { 
	    //临时函数
        function new_()  { 
            this.Type = aClass;//保存该实例的类型   
			//如果类定义中有名为Create的函数,则执行。
			//这个Create是我们约定的构造函数
            if (aClass.Create) 
              aClass.Create.apply(this, aParams); //执行构造函数   
        }; 
		//让临时函数拥有aClass类
        new_.prototype = aClass; 
		//生成临时函数的实例,并返回给调用者。该实例有类中的所有公有
		//变量与方法,还有一个公有变量Type保存着该实例的类型。
        return new new_(); 
    }; 
    
     //*********************自定义类体系使用*************************
	 //定义一个Person类,父类是object
     var Person = Class(object,
	    //下面是Person类定义的描述
	    { 
          Create: function(name, age) { //定义构造函数
             this.name = name; //定义公有变量
             this.age = age; //定义公有量
         }, 
         SayHello: function() { //定义公有方法
             alert("Hello, I'm " + this.name + ", " + this.age + " years old."); 
         } 
     }); 
     
	 //定义一个Employee类,继承于Person类
     var Employee = Class(Person,    
	    //个Employee类的定义描述
       { 
         Create: function(name, age, salary) { 
             Person.Create.call(this, name, age);  //调用基类的构造函数 
             this.salary = salary; 
         }, 
         ShowMeTheMoney: function() { 
             alert(this.name + " $" + this.salary); 
         } 
     }); 
     
	 //生成Person类的实例
     var BillGates = New(Person, ["Bill Gates", 53]); 
	 //生成Employee类的实例
     var SteveJobs = New(Employee, ["Steve Jobs", 53, 1234]); 
     BillGates.SayHello(); 
     SteveJobs.SayHello(); 
     SteveJobs.ShowMeTheMoney(); 
     
	 //根据 BillGate的类型创建 LittleBill 
     var LittleBill = New(BillGates.Type, ["Little Bill", 6]);   
     LittleBill.SayHello(); 
      
     alert(BillGates.isA(Person));       //true 
     alert(BillGates.isA(Employee));     //false 
     alert(SteveJobs.isA(Person));       //true 
     alert(Person.isA(Employee));        //false 
     alert(Employee.isA(Person));        //true 
</script>
</body>
</html>


分享到:
评论
38 楼 fins 2008-12-02  
"这种代码作用,初步估计是为了减少内存泄露之类的吧。 "

不是的, 目的如下:
1 限定变量作用域
2 提高安全性(这里的安全性指的是 代码的稳定可靠性)
3 省内存

发现你一个问题: 喜欢肆无忌惮的使用 eval. 这样不好.
在你的那个 tab组件里 有这样一段
    this.ShowTabs=function(thisObj,e){   
       
        var ID=e.getAttribute("idno");   
        if(ID!=thisObj.tID){       
        eval ("document.getElementById(this.targName+'FSimpleTabTitle"+[thisObj.tID]+"').className='';");   
        eval ("document.getElementById(this.targName+'FSimpleTabTitle"+[ID]+"').className='selectedtab';");   
        eval("document.getElementById(this.targName+'FSimpleTabs"+[thisObj.tID]+"').style.display='none';");   
        eval("document.getElementById(this.targName+'FSimpleTabs"+[ID]+"').style.display='';");   
        thisObj.tID=ID;   
        }   
  
    }   


我实在没看明白 为啥非要用eval
37 楼 yunhaifeiwu 2008-12-02  
下面是从ymPrompt 3.0版源码中剥离整理出来的。目的是揣磨别人代码中的
div等标签拖动的处理方式。由于是为了便于阅读,与原来的代码有一定的差别。
如:原来有这样的语句:
   var d=document,db=d.body,y=ymPrompt;

在下面的代码中,为了便于阅读取消了这种方式,但是如果要在实际使用中,
建议不要取消。因为,这缩代了js代码(如果有第三方js压缩软件,不取消
也未偿不可)。

在下面的代码中,注意 如下的代码:
  (function(){})();

其中花括号中有许多语句。这种方式,基本上可这样看待:定义了一个函数,并立即
调用它。 这种代码作用,初步估计是为了减少内存泄露之类的吧。

说明:
      1 代码中其事件处理方式中,没有搞得很明白,暂时会用自已的方式处理事件.

      2 如果组件复杂时,个人认为有必要把组件拖动、浏览器类型判断等,事件注册单独
封装在一个对象中。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
	<title>ymPrompt </title>
	<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
	<script type="text/javascript">
	</script>
 </head>
 <body>
    <div id="dd" style="background:#FC6; width:80px; position:absolute">ssss</div>
    <script type="text/javascript">


    //用json的形式定义了对象
    var fc={
        d:"d1111",
        targDiv:null,
        ds:function( ){
            alert("sss");//无啥意义的函数
        },
        copy:function(o,c){//这是一个把c中定义的函数与变量,拷贝到对象o中。
            o=(o&&typeof o=='object')?o:{};
            if (o && c && typeof c == 'object')
                for(var p in c)o[p] = c[p];
            return o;
        }
    }
    //*****************上面这个对象使用例子程序**************
    //使用fc的copy函数,把用json形式定义的对象与函数拷贝到fc对象中
    //fc.copy(fc,{
    //    b:"b111",
    //    tel:function(){
    //        alert("fc.copy");
    //    }
    //});
    //fc.tel(); //由于有上面一个语句,这里可以调用tel函了。
    //***********************************************


    fc.targDiv=document.getElementById("dd");//设定一个目标对象,本例就是要拖动它
    //这里有一个奇怪形式的函数,为了描述方便,姑且叫临时函数吧。
    (function(){
        //浏览器类型判断
        var browser=function(s){
            return navigator.userAgent.toLowerCase().indexOf(s)!=-1
        };
        var isOpera=browser('opera');
        var isIE=browser('msie')!=-1&&(document.all&&!isOpera);
        
        //统一定义一个事件绑定函数,以兼容主流浏览器的事件注册
        var addEvent=(function(){
            return eval(['1,function(env,fn,obj){obj=obj||document;',
                isIE?"obj.attachEvent('on'+env,fn)":
                    'obj.addEventListener(env,fn,false)',
                '}'].join(''))
        })();
        

        //鼠标左键按下响应函数
        var dragVar,setDrag=function(e){
            e=e||window.event;
            dragVar=fc.copy(dragVar,
                {startDrag:true,
                    startX:e.x||e.pageX,
                    startY:e.y||e.pageY,
                    containX:fc.targDiv.offsetLeft,
                    containY:fc.targDiv.offsetTop
                }
            );
        };
        //关联鼠标左键按下事件 到setDrag函数
        addEvent('mousedown',setDrag,fc.targDiv);

        //鼠标移动响应事件及其响应函数
        addEvent("mousemove",function(e){
            if(dragVar&&dragVar.startDrag){
                e=e||window.event;
                fc.targDiv.style.left=(dragVar.containX+(e.x||e.pageX)-dragVar.startX)+"px";
                fc.targDiv.style.top=(dragVar.containY+(e.y||e.pageY)-dragVar.startY)+"px";
            }
        });

        //鼠标左键释放及其响应函数
        addEvent("mouseup",function(){dragVar=null});
		  
    })();

   </script>
 </body>
</html>
36 楼 yunhaifeiwu 2008-12-02  
walkman 写道
似乎楼主说的就是 这种东西?
如果是的话那 Array-Like 就只是“表面现象”,Objects 才是实质啊


谢谢walkman! 我说的正是这个东东!但一直不知怎么叫,现在明白了它与Array-Like的概念雷同
各位大虾都一致认为这个东东实质是Objects,那么我想一定不会错了。

不过,不管它的本质是什么,我想把他映射成数据结构中的东东(故以前用了相关概念一词:关联数组),
目的也不外乎整合自已的认知体系。在以后的设计中,在自已的认知体系中会把关联数组、
Array-Like,、js中用花括号定义的动象,划成一个类别,便于自已跨越式思维。既能
读懂其他语言的相关概念,又能联系到数据结构、js。这对知识的贯通有相当大的好处,
不足是与别人交流容易产生沟通上的问题,自已有时也会短暂的迷糊。事实上,自已迷糊时
会查找相关资料、调试等多种手段消除的。

在经过与fins网兄的探讨中,我收获很多,但 fins花了许多时间,在此特别感谢fins!

对walkman对本人多个贴子,不惜指正建议,深表感谢!


=============
简单查了了一下Array-Like ,中文意思少有描述,也没看见什么知名网站进行特别定义。
不过看了一些相关中文描述,知道walkman所提到的Array-Like,正是我眼中的东西。

至于英文,本人较烂。看英文资料,也仅仅是看例子,对英文说明基本上无视!
35 楼 walkman 2008-12-02  
似乎楼主说的就是 Array-Like Objects 这种东西?
如果是的话那 Array-Like 就只是“表面现象”,Objects 才是实质啊
34 楼 yunhaifeiwu 2008-12-02  
achun 写道
to:yunhaifeiwu
我也认为不应该用其他语言的词汇来映射js的对象。
这种学习方法不对头。至于什么权威的书写了什么,不重要。
在学习阶段你可以拿其他语言的词汇、概念来和js做参照以便加快学习,但是和大家交流的时候就不要用这些词汇了。
因为如果你注意的话会发现一个现象就是:
技术论坛上讨论问题的时候在很小心的情况下都会造成别人的理解偏差。
而如果你还采用这样让人迷惑的词汇的话,更不利于讨论了。
另外就是关联数组这个词真的太不是适合js了。
因为在js里至少:Object,Array,Function都能模仿关联数组的功能。
那是否也可以称Array,Function也是关联数组呢!
明显不能这样理解,所以关联数组这种概念根本不适合js.
别管那些权威教材了。



既然大家都反对,以后与大家交流时,把这个词灭掉!
33 楼 yunhaifeiwu 2008-12-02  
fins 写道
yunhaifeiwu :

你怎么看这个问题我已经不关心了 我不打算再就这个无聊问题和你争论.

但是 我觉得你不应该把你的理解强加在 犀牛书上

犀牛书 的"唠叨解说中,全部提到的是数组" 这个结论你时怎么得出的?
在你没有认真看过这本书的情况下?
事实上 该书中 关联数组一词 出现的次数非常少, 而且如我前面所说 作者引入这个概念 只是为了让读者更好的理解 js中object的一些特性.
犀牛书没有 说过 object就是"关联数组".

犀牛书 中 介绍相关知识的章节叫做 "Objects as Associative Arrays"
而不是 "Associative Arrays"
也就是说 其本意是 "用object来充当关联数组" 或者是"像操作关联数组一样来操作对象" .  核心词汇是"object" 而不是"array".

=================================
你拿perl的定义 放到js里毫无疑义. 因为perl中 确实有一种东西叫做 关联数组.

而js中没有这种东西.
js中有的只是对象 但是 这个对象很特殊, 你可以用类似操作关联数组的方式来操作它.

=================================


其实 你怎么叫这个东西都无所谓
但是 我还是建议你 站在 对象的角度去看待  o["p"] 这种形势的代码.
否则 你在看其他示例的代码时 你会在"这是数组还是一个对象"的问题上 纠缠不清.




原来你也没睡啊?  睡不着,整理了一下,总算搞清楚了,我为什么要把那个用json定义的对象叫关联数组了。

1 我的出发点,是想把数据结构与设计模式引到js中来,这可对写复杂的组件有帮助。

2  寻找一种数据结构。 发现了关联数组一词,一查概念,大致意思下标索引是字符串的数组。

3  接着搜寻javascript 关联数组,发现 犀牛也提到这个概念。此外,发现了javasript也类似的支持。

4  接着,寻找数据结构 基本上要用到的存储操作-----新增、修改、读值、删除。然后试着看javascript能否完成。
  反复查找、调试:ok,完全支持!说白了,就是一个map,就是一个hashTable

5 后来我为什么要用关联数组,是因为犀牛给我留下较深的印象。感觉叫关联数组,大家能接受。

6 在例子中,我为什么要在注释中 把用json形式定义的对象,叫作关联数组,这个对象明显不符合关联数组定义啊?

  但是,我的目的是要寻找一种数据结构。而这个东西,就能实现。可当作关联数组来使用。


即,我在那里叫关联数组的深刻原因是:
[/size]

[size=medium]   
      站在数据结构的视点上,强制性加深印象,这个东西就可当关联数组用。当在js软件设计中一遇到复杂的问题

,自然就会想到用数据结构的方法去思考;接着,在实现方案时,自然就会想到用用json形式定义对象了。
  
     也就是说,这个东东让我对数据结构的认知与js融在一起了。
   
     同理,设计模式,当然要与类联系在一起,因此在我的贴文中开头,就直接把function 注释成了类。说实在的,这哪里是什么类哟,仅是可当作类用罢了。




感谢fins兄! 让我又明白了一些东东。




  
32 楼 fins 2008-12-02  
yunhaifeiwu :

你怎么看这个问题我已经不关心了 我不打算再就这个无聊问题和你争论.

但是 我觉得你不应该把你的理解强加在 犀牛书上

犀牛书 的"唠叨解说中,全部提到的是数组" 这个结论你时怎么得出的?
在你没有认真看过这本书的情况下?
事实上 该书中 关联数组一词 出现的次数非常少, 而且如我前面所说 作者引入这个概念 只是为了让读者更好的理解 js中object的一些特性.
犀牛书没有 说过 object就是"关联数组".

犀牛书 中 介绍相关知识的章节叫做 "Objects as Associative Arrays"
而不是 "Associative Arrays"
也就是说 其本意是 "用object来充当关联数组" 或者是"像操作关联数组一样来操作对象" .  核心词汇是"object" 而不是"array".

=================================
你拿perl的定义 放到js里毫无疑义. 因为perl中 确实有一种东西叫做 关联数组.

而js中没有这种东西.
js中有的只是对象 但是 这个对象很特殊, 你可以用类似操作关联数组的方式来操作它.

=================================


其实 你怎么叫这个东西都无所谓
但是 我还是建议你 站在 对象的角度去看待  o["p"] 这种形势的代码.
否则 你在看其他示例的代码时 你会在"这是数组还是一个对象"的问题上 纠缠不清.


31 楼 achun 2008-12-02  
to:yunhaifeiwu
我也认为不应该用其他语言的词汇来映射js的对象。
这种学习方法不对头。至于什么权威的书写了什么,不重要。
在学习阶段你可以拿其他语言的词汇、概念来和js做参照以便加快学习,但是和大家交流的时候就不要用这些词汇了。
因为如果你注意的话会发现一个现象就是:
技术论坛上讨论问题的时候在很小心的情况下都会造成别人的理解偏差。
而如果你还采用这样让人迷惑的词汇的话,更不利于讨论了。
另外就是关联数组这个词真的太不是适合js了。
因为在js里至少:Object,Array,Function都能模仿关联数组的功能。
那是否也可以称Array,Function也是关联数组呢!
明显不能这样理解,所以关联数组这种概念根本不适合js.
别管那些权威教材了。
30 楼 yunhaifeiwu 2008-12-01  
fins 写道
"常常称" 本身就意味着 只是一种习惯.

而且 如我前面所说  我不认同这个书中的这种观点.

你能说: 代码  window["document"] 表示的是 操作一个关联数组 吗?

我觉得 书的作者这么写 只是为了更好的让大家理解 js-object的一些性质.
而不是为了 告诉大家"这就是关联数组".

总之 js中对象随处可见, 还是从对象的视角来考虑问题比较好.

好了 不在这个问题上和你纠结了.
你要是觉得我说的不对 那你选择你自己喜欢的方式去理解吧.




---------------------------------------
     这一点我还真不认同。

     这本书中,唠叨解说中,全部提到的是数组。强调下标与普通数组有差别。其他语言也把这种数组称为关联数组。

附,有的网页也把关联数组,称为hash数组。

     既然这犀牛这本书使用了这个叫法,其他语言,也称这种数组为关联数组,我也跟着叫吧。

本来词就是大家创造出来的。

    为了方便,现把天极网中在perl教材中提到的关联数组的定义,摘抄与下:
http://www.yesky.com/268/26768.shtml
     关联数组和前面说的数组类似,它包含标量数据,可用索引值来单独选择这些数据,和数组不同的是, 关联数组的索引值不是非负的整数而是任意的标量。这些标量称为Keys,可以在以后用于检索数组中的数值。


   


 
29 楼 fins 2008-12-01  
"常常称" 本身就意味着 只是一种习惯.

而且 如我前面所说  我不认同这个书中的这种观点.

你能说: 代码  window["document"] 表示的是 操作一个关联数组 吗?

我觉得 书的作者这么写 只是为了更好的让大家理解 js-object的一些性质.
而不是为了 告诉大家"这就是关联数组".

总之 js中对象随处可见, 还是从对象的视角来考虑问题比较好.

好了 不在这个问题上和你纠结了.
你要是觉得我说的不对 那你选择你自己喜欢的方式去理解吧.



28 楼 yunhaifeiwu 2008-12-01  
fins 写道
不知道你到底看没看过 犀牛书.
js中根本就没有"下标是字符的这种数组"
object["property"] 这种格式 是访问object属性的一种方式
根本就不是 "下标是字符的这种数组" .

我觉得你有点走入歧途了.

P.S.: 我不搞java好多年, 我主要是做ajax开发的.


首先申明本人没有认真看这本书。

但<<javascript权威指南>>的154页,标题是《8.6 作为关联数组的对象>>

在155页,倒数第四行,有这样一句话:“如果使用一个对象时采取的是这一种形式,我们常常
称他为关联数组(associativearry),它是一个数据结构,允许动态地将任意数值与字符串联系在一
起”。前面是它的例子与唠唠叨哪叨的解说。


27 楼 fins 2008-12-01  
在 js 中
new Object() 和 {} 是等价的
new Array() 和 [] 是等价的
(注意 不是"类似"也不是"相当于", 而是等价)


{ a : 1, b: 2  } 定义的是一个对象.
只是使用的是 json格式的定义方式而已.


你原帖中说 "json描述了一个树状结构的对象。"

不对 你应该说 "json可以描述一个树状结构的对象。"
json也可以表述  线性的数组.

更多的你自己看吧
http://www.json.org/json-zh.html



26 楼 yunhaifeiwu 2008-12-01  
fins 写道
yunhaifeiwu 写道

......
可用作map,用作树,用作一维数组,多维数组等。

json描述了一个树状结构的对象。各个节点,要么是一个普通对象,要么是函数,要么是一个由前两者组成的复合对象。
   当一个对象,由json定义时,该对象本质是一个关联数组(即索引为字符串的数组
可动态的增加、删除、修改元素。每个元素要么是一个普通对象、要么是一个函数、要么是由这两者组成的复合对象。

......   


建议去 www.json.org 网站看一下 究竟什么是json.

另外 在 关联数组的问题上我再和你纠结一下:
你可以说, "js中,一个object有时可以相当于一个关联数组,但是其本质仍然是一个object"
你那个 "本质是一个关联数组"的说法 大错特错.


这个本质,真的没有去考证。马上修改。json是自已头脑中大体的意识。马上修改,谢谢fins指出。
25 楼 fins 2008-12-01  
不知道你到底看没看过 犀牛书.
js中根本就没有"下标是字符的这种数组"
object["property"] 这种格式 是访问object属性的一种方式
根本就不是 "下标是字符的这种数组" .

我觉得你有点走入歧途了.

P.S.: 我不搞java好多年, 我主要是做ajax开发的.
24 楼 yunhaifeiwu 2008-12-01  
fins 写道
yunhaifeiwu 写道
fins 写道
我不认同这本书中的说法
js的对象 可以充当 关联数组
但是 如果 把 {} 理解为关联数组 我觉得是不对的

关联数组是一种特殊的对象 但是两者不能画全等号



我狂晕! 在初中数学中,我们经常这样做题:假设a=2 ,b=3 则a+b=5

在这里,已经定义了a与b的概念,你不会说,我不认同这个概念, a 与b不是数字,它是英文字母,

不,它不是英文字母,它是拼音字母。

在那本书的描述中,已经对关联数组的概念作了描述了。你认不认可,是你的事了。

我在我的文中,也作了些限定性的描述,为了怕描述不准确,还用例子,进行说明。如果有人
还要理解偏,如果理解有模糊感觉了,还不调试例子,还不查资料,对于这种人,我只能叫无语了,
无可奈何了!

   


犀牛书中 说的 是 "Objects in JavaScript can serve as associative arrays"
js中没有关联数组这种东西.
信不信由你了.

如果以后你在和别人交流的时候 总是说 定义一个关联数组 {a:1 ,b:2}...
这样是很难让人理解的.



与别人尝试交流时,我尽可能的用大家都知道的词。在我选用关联数组这个词时,也是在网上查了资料的。
权威指南这本书也在用这个词,没想到还是。。。。。

不过,感谢兄台的建议!如:读别人的优秀的源代码,尽可能用大众化的词,是笔记尽可能说明是个人观点,

提醒读者,以免误读!


对了,你老兄的大名,我是经常看见,老兄在java方面造诣很深! 如果有什么不得体的地方,请谅解!
不过,关于花括号中的这种对象,与下标是字符的这种数组有种很强的共性,我不知道如何描述,前面的贴文用到的
关联数组一词暂不作修改。等一下,对其含义描述一下。与人方便,就是给自已方便。

感谢fins!



23 楼 fins 2008-12-01  
yunhaifeiwu 写道

......
可用作map,用作树,用作一维数组,多维数组等。

json描述了一个树状结构的对象。各个节点,要么是一个普通对象,要么是函数,要么是一个由前两者组成的复合对象。
   当一个对象,由json定义时,该对象本质是一个关联数组(即索引为字符串的数组
可动态的增加、删除、修改元素。每个元素要么是一个普通对象、要么是一个函数、要么是由这两者组成的复合对象。

......   


建议去 www.json.org 网站看一下 究竟什么是json.

另外 在 关联数组的问题上我再和你纠结一下:
你可以说, "js中,一个object有时可以相当于一个关联数组,但是其本质仍然是一个object"
你那个 "本质是一个关联数组"的说法 大错特错.
22 楼 fins 2008-12-01  
yunhaifeiwu 写道
fins 写道
我不认同这本书中的说法
js的对象 可以充当 关联数组
但是 如果 把 {} 理解为关联数组 我觉得是不对的

关联数组是一种特殊的对象 但是两者不能画全等号



我狂晕! 在初中数学中,我们经常这样做题:假设a=2 ,b=3 则a+b=5

在这里,已经定义了a与b的概念,你不会说,我不认同这个概念, a 与b不是数字,它是英文字母,

不,它不是英文字母,它是拼音字母。

在那本书的描述中,已经对关联数组的概念作了描述了。你认不认可,是你的事了。

我在我的文中,也作了些限定性的描述,为了怕描述不准确,还用例子,进行说明。如果有人
还要理解偏,如果理解有模糊感觉了,还不调试例子,还不查资料,对于这种人,我只能叫无语了,
无可奈何了!

   


犀牛书中 说的 是 "Objects in JavaScript can serve as associative arrays"
js中没有关联数组这种东西.
信不信由你了.

如果以后你在和别人交流的时候 总是说 定义一个关联数组 {a:1 ,b:2}...
这样是很难让人理解的.

21 楼 yunhaifeiwu 2008-12-01  
fins 写道
我不认同这本书中的说法
js的对象 可以充当 关联数组
但是 如果 把 {} 理解为关联数组 我觉得是不对的

关联数组是一种特殊的对象 但是两者不能画全等号



我狂晕! 在初中数学中,我们经常这样做题:假设a=2 ,b=3 则a+b=5

在这里,已经定义了a与b的概念,你不会说,我不认同这个概念, a 与b不是数字,它是英文字母,

不,它不是英文字母,它是拼音字母。

在那本书的描述中,已经对关联数组的概念作了描述了。你认不认可,是你的事了。

我在我的文中,也作了些限定性的描述,为了怕描述不准确,还用例子,进行说明。如果有人
还要理解偏,如果理解有模糊感觉了,还不调试例子,还不查资料,对于这种人,我只能叫无语了,
无可奈何了!

   
20 楼 yunhaifeiwu 2008-12-01  
fins 写道
建议你多看看其他js组件/框架的代码 应该能学到很多吧
例如你说的 向事件响应函数传递自定义参数之类的.

另外 你的一些概念有错误
虽然死抠概念 没什么意义
不过 有些概念和术语还是统一一下比较好.

不应该总是自创概念.
例如你说的那个 关联数组, 在php perl中或许有种叫法
但是在js 中, 没见过谁这么叫的.

而且严格来说 关联数组和对象 完全不同.
你用 关联数组来指代 js的对象 是错误的.




感谢你的这个建议:“看看其他js组件/框架的代码 ”。

不过眼目前没那个劲去看!

我的目标就是寻找js中书写组件的方法!代码优不优雅,效率高不高,现在没劲去理它!当我寻找到了
方法后,在实际中再去优化它。

js非常的灵活, 别人的框架是为实际使用而写,不是为了便于阅读而写! 他们不可能浅显的告诉我,
在写复杂的UI组件时,如何进行!举个例子:我今天正在看一个写消息提示组件的那个源码!从实际效率与性能上说,
这个源代码非常优秀,如果要从易读性来说,唉,真差!我跟踪事件流程,都好了好长功夫!然后,看它的
一个简单的通过id名称得对象,它的代码在哪里转了半天。 不过凭心而论,代码质量的确让我赞叹!
但是,这个无法告诉我,复杂组件如何封装啊?不会告诉我,如何把数据结构,设计模式,javascript结合在一起啊?

我会按我的方式,去寻找复杂设计方法的,当找到后,有必要,再去看别人的源码,优化代码!








19 楼 fins 2008-12-01  
我不认同这本书中的说法
js的对象 可以充当 关联数组
但是 如果 把 {} 理解为关联数组 我觉得是不对的

关联数组是一种特殊的对象 但是两者不能画全等号

相关推荐

    js 书写较复杂的UI日记

    【标题】"JS 书写较复杂的UI日记"主要探讨的是如何使用JavaScript来构建一个功能丰富的用户界面,尤其可能涉及到自定义布局和交互设计。在Web开发中,JavaScript是一种不可或缺的脚本语言,它使得网页具有动态性和...

    ui-components:React UI组件

    JavaScript是React的基础,它是一种广泛使用的、动态的、基于原型的编程语言,尤其在Web开发中占据重要地位。React的JSX语法扩展了JavaScript,使得在JavaScript中书写HTML元素变得更为直观。在"ui-components"项目...

    JavaScript_学习Reactjs的基础知识,使测试通过.zip

    本压缩包“JavaScript_学习Reactjs的基础知识,使测试通过.zip”显然旨在帮助初学者掌握React的基础,并学习如何编写通过测试的React应用。 React.js的核心概念: 1. **虚拟DOM(Virtual DOM)**:React使用虚拟DOM...

    React组件合集,附视频教程_JavaScript_CSS_下载.zip

    1. React基础知识:JSX、组件、props和state、事件处理。 2. React Hooks:useState、useEffect、useContext、useReducer等,它们如何简化类组件的逻辑。 3. React Router:用于应用程序的路由管理,创建可导航的...

    Garden React组件.zip

    1. **JSX**:React引入了一种类似HTML的语法扩展,称为JSX,它允许在JavaScript中书写UI结构。JSX使得组件定义更加直观。 2. **Props**:组件可以通过props(属性)接收外部数据,props是组件之间通信的基础。 3. **...

    18.1 01_react_basics_javascript_

    以上就是React基础知识的概览,它结合了JavaScript的强大功能和组件化的思想,为构建动态、高效的Web应用提供了强大的工具。通过深入学习和实践,你可以更好地理解和运用React,创建出高质量的前端应用。

    React小书(完整版)1

    本书不仅仅提供了React.js的基础知识,还深入探讨了React.js的高级特性,使得读者能够在掌握基础知识的基础上进一步深入学习,应对更为复杂的开发场景。 React.js作为前端组件化的重要实践,自诞生之日起就迅速受到...

    此为本人学习node.js中书写的Demo,特此保存一下。采用AppCan MEAP移动应用开发平台开发,数据库采用.zip

    4. **移动应用开发**:掌握移动应用开发的基础知识,包括UI设计原则、响应式布局、手势识别等,理解原生与混合应用的区别。 5. **前后端交互**:理解RESTful API设计,用JSON格式交换数据,学习如何通过Ajax或者...

    react-basico:在 React.js 中编写组件的基础

    在这个"react-basico"项目中,我们将深入探讨在React中创建组件的基础知识。 一、React组件的概念 React组件是构建UI的基本单元,可以想象为独立的、自包含的代码块,它们负责渲染特定部分的视图。组件可以是简单的...

    JavaScript_初学者文件,最终项目和FAQ为我的终极React课程.zip

    总的来说,这个压缩包提供了一条从JavaScript基础知识过渡到React实战的完整学习路径,对初学者来说是一份宝贵的资源。通过系统学习和实践,不仅能掌握JavaScript语言,还能深入理解React框架,为成为专业的前端...

    movie_app:React JS基础知识!

    电影应用2021是基于React JS开发的一个项目,它展示了React的基础知识和在实际开发中的应用。React作为JavaScript库,主要用于构建用户界面,尤其适用于单页应用(SPA)。在这个项目中,我们可以深入理解React的核心...

    Lay-UI前端模板

    2. **HTML/CSS/JS书写与组织形式**:LayUI遵循原生的HTML、CSS和JavaScript编写方式,使得对前端基础有了解的开发者能够快速上手。同时,它提供了一套规范,使得代码结构清晰,有利于团队协作和代码一致性。 3. **...

    react+ant design admin

    - JSX语法:React使用JSX,一种JavaScript的扩展语法,允许在JavaScript中书写HTML样式的代码,方便地创建和组合UI组件。 - State与Props:State是组件内部的数据,可变;Props是组件接收的外部数据,不可变。组件...

    我的react练习,第一节

    在本节React练习中,我们将深入探讨React.js的基础知识,这是一种流行的JavaScript库,用于构建用户界面,特别是单页应用程序(SPA)。React以其组件化、声明式编程风格和高效的虚拟DOM著称,是现代前端开发的重要...

    【JavaScript源代码】如何创建自己的第一个React 页面.docx

    【JavaScript源代码】如何创建自己的第一个React页面 ...了解并掌握这些基础知识,你就踏上了React开发之旅。随着进一步的学习,你将能够利用React的组件系统、状态管理和生命周期方法来构建功能丰富的Web应用程序。

    react学习1

    总之,React是通过函数组件和JSX语法来构建可复用的UI组件。通过合理的环境配置和基本的HTML容器设置,开发者可以轻松地开始React项目,并在JavaScript文件中创建和渲染React组件。了解这些基础知识对于掌握React...

    资源前后端分离式分布式微服务架构项目搜索前端Nuxt.js讲义+源码+视频

    例如,`pages`目录用于存放路由相关的组件,`components`目录存放可复用的UI组件等。 - **理解目录别名**:通过配置`alias`字段可以在项目中定义别名,方便引用各个文件夹下的文件,简化路径书写。 - **能够测试页面...

    danpung2-movie_app_21:React JS基础知识

    在这个“danpung2-movie_app_21”项目中,我们将深入探讨React的基础知识,这将帮助你理解和掌握这个强大的库。 1. **React组件**:React的核心概念是组件化,它允许我们将UI分解为独立、可重用的部件。在项目中,...

    react基础与进阶部分笔记

    React.js 是一个由Facebook开发并维护的开源JavaScript库,用于构建用户界面,特别是单页应用程序。这个库专注于视图层,让开发者能够高效地管理组件的状态和渲染过程。本笔记将涵盖React的基础概念以及进阶特性,...

    前端开发简历模板-web前端开发工程师-3年.docx

    前端开发简历模板-web...本资源摘要信息总结了前端开发工程师的基础知识、JavaScript 程序设计、前端开发框架和工具、Node.js 和 GraphQL、项目经验等多个方面的知识点,为前端开发工程师提供了详细的知识 reference。

Global site tag (gtag.js) - Google Analytics