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

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


[color=blue]

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

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


本博文与另一篇博文《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>



[color=blue]
3.2 prototype使用----能简单模拟类
[/color]
说明: (经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能模拟类

[color=blue]
3.3 apply与call 使用
[/color]
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调用父类的构造函数。这样执行子类构造函数,也能执行父类的函数。

[color=blue]
3.4 模拟类继承
[/color]
使用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>


[color=blue]
3.5 用js实现自已定义的类体系
[/color]
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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值