`
yunhaifeiwu
  • 浏览: 162337 次
  • 性别: 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>


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

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

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

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





弱弱的红着脸说,我不敢抢别人的专利。因为《javascript权威指南》第四版 第154页使用了这个叫法。
(http://cache.baidu.com/c?m=9d78d513d99b12eb0bacc53e565491711925971337c0a61f68a5905fe0174c40377192c830566613a5c06b100ab8492dfd813c65440937c6eddffc3dc9fcd27620d26172320b87320fce5cea8e5125b6279012feaf6eb6e7af2fe5f3978fc25756cb53076d8087d11c5f4a&p=82769a4581d81ef808e297285a&user=baidu)
这本书的电子教材可到www.gougou.com输入名字中搜,可下载。说明:本人没闲劲看这种教材。


在这本书里,明确指出了,关联数组,是下标索引是字符串的。

还有,javascript 中 当如下定义一个变量 var dd={};
这个对象,本质上就是一个关联数组!!!!!!!!!!!!这个是我的推断。

如果 这样定义 var dd="aa" 这个就不是关联数组了。这个在前面已经作了批注了!





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

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

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

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


16 楼 yunhaifeiwu 2008-12-01  
fins 写道
楼主啊 你这是知识分享呢 还是学习笔记呢?
如果是知识分享 那么 很遗憾的告诉你 你分享了很多错误的知识.
这样的结果就是"容易误导其他新手"

如果是学习笔记呢 那么你要说明下: 本文的内容为个人观点,不保证其正确性.

===============
看了你的其他文>章 觉得你是一个很爱专研和学习的人 但是我觉得你似乎选错了教材.


谢谢大虾!

在文中开头,就指出了属于学习笔记与理解!正在不断的探索! (看你楼上的楼上的兄弟的的全文引用吧,
这位兄台是想纠我小辫子呢,还是想帮我作证,^_^,开个玩笑)

我很不喜欢跟着教材走,不管是什么样的教材!当一个知识无法与自身的认知相融合,
再优秀的教材都变得不优秀了!

就拿apply 与call来说,微软的msdn够准确到位吧?可惜太难理解,看中文与看外文一个样!
再说prototype,我看了许多到位的解说,可惜我领悟能力太低了,只好自已调试总结!

正如在前面的回贴中所说:我的目标是寻找到一个能封装组件的方法,为了这个目标,先想先思,
再实践,遇着问题再寻找或尝试解决。有许多概念性的东西都属于自已理解。

我发贴一是希望得到别人的指正,二是有供他人参考 。

说实在的,有许多东西不是教材中就有的,也不是网上就有的。就拿js中事件响应函数来说,如何
向这个函数传递自定义参数,在网上没找到答案!在许多教村中也没找到答案。这可是我无意中搜
到函数式编程,发现了一个简单的例子,可惜这个简单例子,又把事件源对象弄丢了。又调试,才
发现现arguments有。又说js中如何找一个像java中的map吧,在网上就没搜到答案。问的人倒有一大
群。就是看到一个关联数组,也与自已要找的相差较远。但是一个数据结构,在软件设计中是多
么的重要!我的学习过程与笔记,也许现在这些东东在各位眼中是错误的,严重影响性能,有的还会
出现内存泄露!可是,我至少在寻找一种设计方法,在努力整合自已的知识体系。

本人所发的博文凡是标有原创的,都是本人的学习笔记,是自已寻找、调试、理解、综合的产
物,仅供参考。但有一点,本人所发的源代码,经过调试过的。没有经过调试过的,都会特别注明。

再次申明,本人的博文是自已的学习笔记,不保证内容全部正确,仅供参考!因此给各位网页带来的不便,再次说声
抱歉!还有这个组件的封装,也正在探索之中。如果有结果了。会抽空全部整理成文的。尽可能减少错误,理解尽可不
出偏差,尽可能的表达准确!谢谢!
15 楼 fins 2008-12-01  
楼主啊 你这是知识分享呢 还是学习笔记呢?
如果是知识分享 那么 很遗憾的告诉你 你分享了很多错误的知识.
这样的结果就是"容易误导其他新手"

如果是学习笔记呢 那么你要说明下: 本文的内容为个人观点,不保证其正确性.

===============
看了你的其他文章 觉得你是一个很爱专研和学习的人 但是我觉得你似乎选错了教材.
14 楼 yunhaifeiwu 2008-12-01  

经fins与achun网友的建议,不用关联数组一词。在这里,重新改一下。注意:这里还是站在数据结构的视点上看问题


   在js中,有些对象 可方便模拟java中所说的map,或者模拟有些数据结构教材中的哈希表。(注意:
仅仅是模拟,倒底等不等同需要考证)
  
   理解性的归纳,暂不作说明,仅给出例子。如果要参考理解性归纳总结,看分界线后的内容。
(注意理解性归纳总结,不等于事实是这样,仅仅方便于理解罢了)


   例1:用花括符定义的对象,模拟map相关操作
    
  
       
        //用花括符定义了一个对象root,模拟java中的map对象
        var root= {a1:'a1',a2:'a2',a3:function(){alert("hello");} };
        root.aa="aaa";//向root动态增加一个属性;模拟 map的put操作,即新增数据
        root.aa="aaa1";//修改root中属性aa的数据,模拟map的get 操作与put操作。即完成数据的修改
        root.bb="bbb"; //向root动态增加一个属性;模拟 map的put操作,即新增数据
        delete root.aa;//删除root中的属性;模拟map的remover操作,即完成数据删除

        for(var k in root) {
           alert(root[k]);  };//root[k] ,是读取root中属性为k的数据;模拟map的get操作,即完成数据读取
       root.a3();//调用root中定义的a3函数.这个没有对应的模拟了。


例 2: 用两个类似json的形式分别定义几个函数,并 合并到一个对象中。
说明:1 来源于ymPrompt组件的源码,但作了修改.
       2 这里用了类似json的形式,仅是为了描述的准确性。倒底是不是json,没有考证。有可能本身就是json,
有可能不是(可以肯定与json的形式高度相同)。
 
//用类似json的形式定义了函数  (倒底是不是,不想去考证了,太累了) 
var c={ 
    d:"d1111",
    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;
     }
}

// 用类似json的形式定义了函数tel,也定义了一个变量b.并把它们全部复制到对象c中
c.copy(c,{b:"b111",
        tel:function(){
            alert("c.copy");
        }
});

c.tel();        //由于两处定义的函数被拷贝y到一处了,故这里可直接调用tel函数了。 


 



如果要跨越式思维,快速把数据结构引到js中,还是看下面的吧。在这里,让你非常
强烈的感受到js中用花括号定义的对象之强悍!
但这里容易引起误理解,要特别注意.

这是以前的记录
========================================================================

说明

  1   经fins网兄建义,对于有些不恰当的词句,现作适当修改。而对于“关联数组”一词,fins感觉不恰当,但本人现暂没想到其他词汇,暂不作修改。(这里仅是站在数据结构的视角上描述)

  2  在这里,为了减少给他人造成的误解,特强制义定义本文中的关联数组的含义:

     关联数组--------下标索引是字符串的数组。

  3 以后,本人与大家在js方面交流时,不再用关联数组这个词。如果要用到类似的东东仅列举例子,然后跳过。

   
 
JSON强大的数据结构


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

json可以描述一个树状结构的对象。各个节点,要么是一个普通对象,要么是函数,要么是一个由前两者组成的复合对象。
   当一个对象,由json定义时,该对象可当作一个关联数组使用。可动态的增加、删除、修改元素。每个元素要么是一个普通对象、要么是一个函数、要么是由这两者组成的复合对象。(注意:本文中的概念,仅是理解并不严密与准确,重点看例子,进行总结与印证)

   例1 ,展示了一个对象元素新增、修改、删除操作
       
        var root= {a1:'a1',a2:'a2',a3:function(){alert("hello");} };
        root.aa="aaa";//插入新元素
        root.aa="aaa1";//修改元素值
        root.bb="bbb"; //插入新元素
        delete root.aa;//册除元素

        for(var k in root) {
           alert(root[k]);  };//遍历元素值。当遍历到a3时,把函数定义体当字符串输出。
       root.a3();//调用root中定义的a3函数


例 2: 用两个json分别定义几个函数,并 合并到一个对象中。
说明:1 来源于ymPrompt组件的源码,但作了修改.
       2 注释中多处关于关联数组的地方,是指可当作下标索引是字符串的数组使用。
//定义了一个关联数组。该数组中有普通对象,及函数
//定义形式是用json. 
var c={ 
    d:"d1111",
    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;
     }
}

// 把用json定义的关联数组追加到对象c中。c本身也是一个关联数组。
c.copy(c,{b:"b111",
        tel:function(){
            alert("c.copy");
        }
});

c.tel();        //由于两处定义的函数被copy到一处了,故这里可直接调用tel函数了。 

13 楼 3Seefans 2008-12-01  
yunhaifeiwu 写道
本人在用js书写UI组件道路上正不断探索与学习,下面是自已的理解与学习笔记。
本博文与另一篇博文《javascript函数式编程---解决事件参数传递问题》
构成了用js实现书写UI组件的基础知识,及实现的技术手段。
笔记很多,仅选用了自认为对同样道路上有用的朋友。
关于封装的总的方法论,时机到了再发布。


3.1 javascript 模拟类

说明:
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>



12 楼 yunhaifeiwu 2008-12-01  
achun 写道
yunhaifeiwu 写道
谢谢哥们,让我大开眼界了!

javasript 太灵活强大了!

如果要作为一种数据结构,不可少的是数据元素的插入,修更,访问,删除操作!

关联数组能胜任!

我个人感觉,js的数组是最适宜完成这个工作的,关联数组在js里其实就是普通对象Object,但是没有
js数组的切片,链接等方法.这些方法组合起来就是插入,修更,访问,删除

谢谢兄台了! 是的,本质一样。切片大致看了一眼!
11 楼 achun 2008-12-01  
yunhaifeiwu 写道
谢谢哥们,让我大开眼界了!

javasript 太灵活强大了!

如果要作为一种数据结构,不可少的是数据元素的插入,修更,访问,删除操作!

关联数组能胜任!

我个人感觉,js的数组是最适宜完成这个工作的,关联数组在js里其实就是普通对象Object,但是没有
js数组的切片,链接等方法.这些方法组合起来就是插入,修更,访问,删除
10 楼 yunhaifeiwu 2008-12-01  
谢谢哥们,让我大开眼界了!

javasript 太灵活强大了!

如果要作为一种数据结构,不可少的是数据元素的插入,修更,访问,删除操作!

关联数组能胜任! 经验证,空函数也能胜任!不过函数多了一个prototype!还是用关联数组。

歌们中除了函数哪个,其他的两个实质就是关联数组

所有这几个的共性是:
1  插入新元素,与修改元素使用形式一致。如果该元素不存在就新增一个,如果存在了就修改。
2 删除元素用 delete

下面是经过测试的,把函数当map使用的简单例子
        var fun=function(){};
        fun.aa="aaa";//插入新元素
        fun.aa="aaa1";//修改元素值
        fun.bb="bbb"; //插入新元素
        delete fun.aa;//册除元素
        for(var k in fun){alert(fun[k])};//遍历元素值


附: 我前面出现多个同名key是:运行网页,打开firefox的调试器(firebug),在监控器中
输入 fun.aa="ssss"; fun.aa="dddd"
fun中就有多个key值为aa的元素了!
9 楼 achun 2008-12-01  
<div class='quote_div'>yunhaifeiwu 写道<br/><br/>对于javascript知识,我比较薄弱。现在还处于造轮子阶段。今天利用空闲时间,先研究一下yemoo 的消息提示组件。汗,昨天才粗步弄清大体的工作过程。对了,在javascript中,昨天总算找到了一个可以模仿java中的map的东东--------关联数组。但这个还不能直接当map用,对key他允许重复(这个有疑问了,在脚本中暂时不会重复),需要对之处理。  <br/>
<pre name='code' class='java'> var dd =new Array();//定义数组
       dd["aa"]="aaa";//新增一个key为"aa"的元素
       dd["ss"]="sss";//新增一个key为"aa"的元素
       dd["aa"]="bbb";//修改key为"aa"的元素。奇怪,在用firebug的监控器里输入该语句会再新加入一个元素
       delete dd["aa"];//删降key为"aa"的元素
       for(var t in dd){ //循环遍历数组
         alert(dd[t]);//读出数组中的数据,其中key值为t中的值
       }
}
24
</pre>
<br/>   <br/>   <br/></div>
<p> </p>
<p>不能呀!哥们.你把java的习惯完全带到javascript了呀!</p>
<pre name='code' class='js'>var obj={aa:'aaa',ss:'sss'};//这就是一个普通的js对象,也是js中2等的对象,这就是一个超级大map呀
var fun=function (){}//一等的是函数,定义一个函数对象
fun.aa='aaa';//扩展fun,
fun.ss='sss';//相比前面的obj,fun多了可执行,当然细节上是有差异的,比如说不能定义
fun.length=4;//错误因为length是每个function都有的属性,表示定义的时候参数的个数
var array=[1,2,3,'aaa','bbb','ccc',444,55,6,8];//定义数组对象
array.aaa='aaa';//扩展它,注意上面的aaa是数组array索引为3的元素值,现在的是扩展了,也就是说js里的对象是这么的随便,这也是一个超级大map

for(var k in array){alert(k);}//就是遍历对象array的成员了,可以遍历到array.aaa,当然对于数组来说预定义的方法和属性是不会被遍历到的,比如length,split,slice等
for(var i=0;i&lt;array.length;i++){alert(array[i])}//这是普通的遍历数组的方法了,和上面的相比当不能访问到,array.aaa了
for(var k in obj){alert(k);}//就是遍历对象obj的成员了,当然对于Object来说,也是遍历不到预定义的方法和属性
for(var k in fun){alert(k);}//就是遍历对象fun的成员了,当然对于Function来说,也是遍历不到预定义的方法和属性</pre>
 
<p>另外对象的key是不会重复的,不知道你是怎么测试的.但是这肯定是不会发生的事情.</p>
 
8 楼 yunhaifeiwu 2008-12-01  
achun 写道

好。就拿lightBox开头。
我们先分析一下lightBox的特性:

  1. 内容:是针对图片覆盖式显示的
  2. 关闭:有关闭按钮,可以主动关闭,或者点击lightBox之外的页面关闭。
  3. 内容更换:关键是触发条件,这个可能和第2点有冲突,比如说触发来自页面上的其他标签点击行为。也就是说lightBox可能有多种显示和关闭模式
  4. 显示特效:图片显示可以变花样
  5. 图片预加载和尺寸问题:目的是为了计算lighBox的尺寸,以正确居中放置
  6. 事件(Event):这个看了是不可缺少了。


由上面的基本分析来说,如果我们按照由简单到复杂的模式开发这个的话,也不可避免的要处理几个关键问题

  1. 图片预加载
  2. 居中算法
  3. 事件的监听和撤销


开发策略。我首选的是用jQuery来做这个(完成之后再用其他方法实现一个,比较一下),貌似这个用不上jCT。这3个基本需求jQuery都有支持(扩展)。

而且前几天我正好改造了一个center的扩展可以用到这上面

jQuery 插件 center
今天太晚了,明天做吧。





对于javascript知识,我比较薄弱。现在还处于造轮子阶段。今天利用空闲时间,先研究一下yemoo 的消息提示组件。汗,昨天才粗步弄清大体的工作过程。对了,在javascript中,昨天总算找到了一个可以模仿java中的map的东东--------关联数组。但这个还不能直接当map用,对key他允许重复(这个有疑问了,在脚本中暂时不会重复),需要对之处理。 
 var dd =new Array();//定义数组
       dd["aa"]="aaa";//新增一个key为"aa"的元素
       dd["ss"]="sss";//新增一个key为"aa"的元素
       dd["aa"]="bbb";//修改key为"aa"的元素。奇怪,在用firebug的监控器里输入该语句会再新加入一个元素
       delete dd["aa"];//删降key为"aa"的元素
       for(var t in dd){ //循环遍历数组
         alert(dd[t]);//读出数组中的数据,其中key值为t中的值
       }	 
 }
24 

  
  
7 楼 achun 2008-11-30  
<p>好。就拿lightBox开头。<br/>我们先分析一下lightBox的特性:</p>
<ol>
<li>内容:是针对图片覆盖式显示的</li>
<li>关闭:有关闭按钮,可以主动关闭,或者点击lightBox之外的页面关闭。</li>
<li>内容更换:关键是触发条件,这个可能和第2点有冲突,比如说触发来自页面上的其他标签点击行为。也就是说lightBox可能有多种显示和关闭模式</li>
<li>显示特效:图片显示可以变花样</li>
<li>图片预加载和尺寸问题:目的是为了计算lighBox的尺寸,以正确居中放置</li>
<li>事件(Event):这个看了是不可缺少了。</li>
</ol>
<p>由上面的基本分析来说,如果我们按照由简单到复杂的模式开发这个的话,也不可避免的要处理几个关键问题</p>
<ol>
<li>图片预加载</li>
<li>居中算法</li>
<li>事件的监听和撤销</li>
</ol>
<p>开发策略。我首选的是用jQuery来做这个(完成之后再用其他方法实现一个,比较一下),貌似这个用不上jCT。这3个基本需求jQuery都有支持(扩展)。</p>
<p>而且前几天我正好改造了一个center的扩展可以用到这上面</p>
<h3><a href='http://achun.iteye.com/blog/280364'>jQuery 插件 center</a></h3>
<h3 class='type_original' title='原创'>今天太晚了,明天做吧。</h3>
<h3 class='type_original' title='原创'><br/></h3>
<p> </p>
6 楼 yunhaifeiwu 2008-11-30  
achun 写道
to:yunhaifeiwu
我们这样做,你看如何.
你先提一个简单的UI组件,我们分别用不同的方法来实现他
我用我写的jct模板工具做.
我一直认为jCT有这个能力,不过没有实际去做成组件.(当然可能要配合其他工具)
通过实战,找到一种比较好的开发模式.

好啊!我接下来先打算做一个简单的lightBox。然后,在这个基础上,允许多次向lightBox装入lightBox。到这里,现阶段就不在深入了,然后考虑基本网页如何用这个简单的lightBox进行表达。javascript封装现阶段就到此为止。(我将按计划做其他东东)

重点是找到书写自已UI组件方法,当看到一个网页局部版面较好时,通过foxBug查出其div布局样式,快速封装出来;或在平面设计软件上,作出布局与构图,然后用div,css去表现,再封装出来。这种方法与直接用第三方组件相比,有点笨,但自我感觉自已设计的自由度大点。如果兼容性不容易满足,会考虑用jquery之类的轻量级框架,进行封装。

5 楼 achun 2008-11-30  
to:yunhaifeiwu
我们这样做,你看如何.
你先提一个简单的UI组件,我们分别用不同的方法来实现他
我用我写的jct模板工具做.
我一直认为jCT有这个能力,不过没有实际去做成组件.(当然可能要配合其他工具)
通过实战,找到一种比较好的开发模式.
4 楼 yunhaifeiwu 2008-11-30  
achun 写道
UI要解决的主要问题应该是数据和表现的管理.
表现也就是UI的视觉.
数据就是UI的内容.
从理论上说这符合模板的功能.
因此我一直认为UI就是对数据进行详细管理的模板.



这个理解与观点,我支持!

要设计可以复用的UI组件(指基于html的web组件,其他的还没琢磨),重要一点就是要对已经写好的且大量重复的html代码(或其他)进行封装。

许多浏览器都支持js,因此用js封装 方便一些。而封装,如果用面向对象的思想与方法进行,可把以往的知识运用到这里,少了许多思想与方法上的探索。故,我认为用js进行模拟面向对象是用js书写UI组件的基础之一。基础之二就是,会用js动态生成可视的DOM节点(如常见的div,文本框,按钮等),这个没难度,难度在于为这些节点关联事件响应函数。js太灵活了,仅提供了各种基本的技术,需要把他们综合才能实现。因此关联事件响应,并传递自定义参数,是基础知识之二。


在这两天的琢磨过程中,认为简单的封装,上面提到的两个基础知识点,就差不多了。如果要复杂的封装,如在一个已经封装好的组件中,在加入另一个已经写好的组件,这两个知识点还不够。

正如achun所言,UI组件是数据与表现的管理,如何把数据与表现进行描述并在js中实现,是UI复杂封装要考虑的问题,
初步思路时,用一个map数据结构保存UI组件挂入点(该组件可视部份在DOM树中的哪一个节点下),用另一个map数据结构保存各个组件对象。这样当需要时,直接从他们中查找出再使用就可以了。当然这种方法,在强大的js中,不会是高效的,但是能实现封装目的,有了这个封装方法,再结合优秀的其他方法优化它,必要时还可陶汰这种探索过的方法。 这样我至始至终有一个系列实现自已目的东东。在复杂的WEB视觉设计中,自已的灵活度非常的高。

因此,寻找一个高效的数据结构是UI复杂组件不可少的另一任务。js没提供map,但支持json,这个json太强了,把眼前简单封装搞到一定程度,再从json中寻找出一个高效的数据结构(json本身就是一个树状结构,现在思想有点混,还没理清)。
3 楼 achun 2008-11-30  
UI要解决的主要问题应该是数据和表现的管理.
表现也就是UI的视觉.
数据就是UI的内容.
从理论上说这符合模板的功能.
因此我一直认为UI就是对数据进行详细管理的模板.
2 楼 yunhaifeiwu 2008-11-29  
walkman 写道

yunhaifeiwu 写道

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

说明:
(1) 所有对象都具有prototype属性。


说说我对 &ldquo;prototype&rdquo; 的理解,首先我&ldquo;不太&rdquo;赞同楼主的这个观点。prototype 谁人不知谁人不晓?大名鼎鼎的 js 库啊!但是除了这个显赫的身份外,prototype 在 js 语言中还有两层意思:


1. 原型(中文解释)

2. 属性名(例如:aFunction.prototype)


所以在 js 中提到 prototype 时,我觉得尤其要对这两种含义加以区分。在下文中,对于第一种意思书写为:prototype 原型,对于第二种意思用斜体加以区分:prototype 属性


我的理解:


1. 每个对象都有 prototype 原型,但是不是每个对象都有 prototype 属性,prototype 属性只有函数才有


2. 一个对象的 prototype 原型就是创建该对象的构造函数的 prototype 属性的值


3. 因为以上第二点,所以&ldquo;所有的&rdquo;函数的原型就是 Function 对象的 prototype 属性的值,而和其自身的 prototype 属性无关!例如 Ext 中每个函数都有 createDelegate 方法,这是因为 Function 的 prototype 属性被 Ext 重写了


4. 补充第一点,除了函数以外,其他对象都没有 prototype 属性,只有一个指向其构造函数的 prototype 属性的&ldquo;内部引用&rdquo;(外界无法访问),这点体现在创造它的构造函数中,用函数创建对象的详细故事大家都比较了解,不多说了






真诚感谢walkman!


在这一点上,自已的确很迷惑,自已总结的第一点与第二点存在着明显的不协调!现在作了更改。


这里才次感谢walkman! ,我再查查有没有更合的理解与归纳!

1 楼 walkman 2008-11-29  
<div class='quote_title'>yunhaifeiwu 写道</div>
<div class='quote_div'><br/>3.2 prototype使用----能简单模拟类 <br/><br/>说明: <br/>(1) 所有对象都具有prototype属性。 <br/></div>
<p><br/>说说我对 “prototype” 的理解,首先我“不太”赞同楼主的这个观点。prototype 谁人不知谁人不晓?大名鼎鼎的 js 库啊!但是除了这个显赫的身份外,prototype 在 js 语言中还有两层意思:</p>
<p> </p>
<p>1. 原型(中文解释)</p>
<p>2. 属性名(例如:aFunction.prototype)</p>
<p> </p>
<p>所以在 js 中提到 prototype 时,我觉得尤其要对这两种含义加以区分。在下文中,对于第一种意思书写为:prototype 原型,对于第二种意思用斜体加以区分:<em>prototype</em> 属性</p>
<p> </p>
<p>我的理解:</p>
<p> </p>
<p>1. 每个对象都有 prototype 原型,但是不是每个对象都有 <em>prototype</em> 属性,<em>prototype</em> 属性只有函数才有</p>
<p> </p>
<p>2. 一个对象的 prototype 原型就是创建该对象的构造函数的 <em>prototype</em> 属性的值</p>
<p> </p>
<p>3. 因为以上第二点,所以“所有的”函数的原型就是 Function 对象的 <em>prototype</em> 属性的值,而和其自身的 <em>prototype</em> 属性无关!例如 Ext 中每个函数都有 createDelegate 方法,这是因为 Function 的 <em>prototype</em> 属性被 Ext 重写了</p>
<p> </p>
<p>4. 补充第一点,除了函数以外,其他对象都没有 <em>prototype</em> 属性,只有一个指向其构造函数的 <em>prototype</em> 属性的“内部引用”(外界无法访问),这点体现在创造它的构造函数中,用函数创建对象的详细故事大家都比较了解,不多说了</p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>

相关推荐

    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,创建出高质量的前端应用。

    此为本人学习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。

    reactjs-semantic-ui

    1. **ReactJS基础知识** - **组件化**:React的核心是组件,每个组件都是独立的代码单元,可以有自己的状态和生命周期方法。 - **JSX语法**:React引入了JSX,一种在JavaScript中书写HTML样式的语法扩展,使得HTML...

Global site tag (gtag.js) - Google Analytics