javascript中的面向对象编程(一)-乾蓝洛-博客园
- 博客分类:
- 技术杂绘
javascript中的面向对象编程(一)-乾蓝洛-博客园
2011年10月26日
Javaspript封装 1、面向对象语言的要求
(1)封装―把相关的信息(无论数据或方法)存储在对象中的能力
(2)聚集―把一个对象存储在另一个对象内的能力
(3) 继承―由另一个类(或多个类)得来类的属性和方法的能力
(4)多态―编写能以多种方法运行的函数或方法的能力
ECMAScript支持这些要求,因此可被看作面向对象的.
2、对象的实例化
var obj = new Object()
var ostringobj = new String()
ECMAScript中也可以把()去掉
var obj = new object;
var ostringobj = new String;
3、对象废除
ECMAScript中有无用存储单元收集程序,意味着不必专门销毁对象来释放内存.
也可强制废除对象:eg:
var obj = new Object();
obj = null
5、对象类型
5.1 本地对象
Object Array Function String Boolean Number Date RegExp Error EvalError RangeError ReferenceError SyntaxError TypeError URIError
5.2 自定义对象
6、作用域,全部都是公共的
对ECMAScript来说,讨论作用域几乎毫无意义。ECMAScript只存在一种作用域(公有作用域)
许多开发都制定了一个规约:私有的属性建议前后加下划线,如:obj._color_ = “red”;
7、静态作用域并非静态的
严格来说,ECMAScript并没有静态作用域,不过,它可以给构造函数提供属性和方法. 构造函数是函数,函数是对象,对象可以有属性和方法。
如:function sayHi(){
alert(“hi”); };
sayHi.alternate = function(){ alert(“hellow”);}
调用:
sayHi(); sayHi.alternate();
8、关键字this
在ECMAScript中,要掌握的最重要的概念之一是关键字this的用法.
它用在对象的方法中,关键字this总是指向调用该方法的对象:
eg:
var oCar = new Object();
oCar.color=“red”;
oCar.showColor=function(){
alert(this.color); //等价于 oCar.color
}
说明:利有this,可在任意多个地方重用同一个函数.
谁调用它这个this就指向谁
如:function ShowColor()
{
alert(this.Color);
}
var oCar1 = new Object();
oCar1.Color = “red”;
oCar1.ShowColor = ShowColor; //这时this是ocar1
var oCar2 = new Object();
oCar2.Color = “blue”;
oCar2.ShowColor=ShowColor; //这时this是ocar2
oCar1.ShowColor(); // output “red”
oCar2.ShowColor(); //outpub “blue”
注意:引用对象的属性时必须使用this.
eg: function ShowColor() { alert(Color); //error } 自定义类和对象
1、工厂模式
ECMAScript中对象的属性可在对象创建后动态定义.
如:
var oCar = new Object();
oCar.Color = "red";
oCar.doors = 4;
oCar.mpg = 23;
oCar.ShowColor = function(){
alert(this.Color);
}
调用时 oCar.ShowColor(); //output “red”
问题:需要创建多个Car实例怎么办?
工厂模式:
function CreateCar(){ //每次调用都创建新的实例
var oCar = new Object();
oCar.Color = "red";
oCar.doors = 4;
oCar.ShowColor = function(){
alert(this.Color);
}
return oCar;
}
调用:
var car1 = CreateCar();
var car2 = CreateCar();
car2.color=’blue’;
alert(car1.Color); //output “red”
car2.ShowColor(); //output “blue”
改造并加入参数:
function CreateCar(color,doors,mpg){
var oCar = new Object();
oCar.Color = color;
oCar.doors = doors;
oCar.mpg = mpg;
oCar.ShowColor = function(){
alert(this.Color); }
return oCar; }
var car1 = CreateCar("red",4,23);
var car2 = CreateCar("blue",4,20);
alert(car1.Color); //output “red”
car2.ShowColor(); //output “blue”
JavaScript中的封装
问题:上面的例子中,每次调用函数createCar(),都要创建新函数showColor(),意味着每个对象都有自己的showColor()版本,事实上,每个对象都共享了同一个函数,showColor每次创建都要分配内存空间
解决方法:
function showColor()
{
alert(this.color);
}
function createCar(sColor,iDoors,iMpg)
{
var oTempCar = new Object();
oTempCar.color = sColor;
oTempCar.doors = iDoors;
oTempCar.mpg= iMpg;
oTempCar.showColor = showColor;
return oTempCar;
}
var oCar1 = createCar("red",4,23);
var oCar2 = createCar("blue",3,25); oCar1.showColor(); //output “red” oCar2.showColor(); //output “blue” 问题2 问题:从功能上讲,这样解决了重复创建函数对象的问题,但该函数看起来不像对象的方法.
解决办法:
所有这些问题引发了开发者定义的构造函数的出现
构造函数方式
形式如下:
function Car(sColor,iDoors) {
this.color = sColor;
this.doors = iDoors;
this.showColor=function(){
alert(this.color); } }
// oCar.ShowColor = function(){
// alert(this.Color); }
//调用
var oCar1 = new Car(“red”,4);
var oCar2 = new Car(“blue”,4);
oCar1.showColor();
oCar2.showColor();
问题:存在着和工厂模式相同的问题,创建对象的方法,都分配内存空间
解决方法:也可以用外部函数重写构造函数,同样的,语义上无任何意义.这就是原型方式的优势所在.
function Car(){};//相当于定义了一个空的类
Car.prototype.color = “red”;//object的一个属性prototype
Car.prototype.doors = 4;
Car.prototype.showColor = function(){
alert(this.color);
}
//调用
var oCar1= new Car();
var oCar2 = new Car();
oCar1.showColor(); //output “red”
oCar2.color=“blue”;
oCar2.showColor(); //output “blue”,需要实例化的时候才分配内存空间
此种方式,调用new Car()时,原型的所有属性都被立即赋予要创建的对象,意味着所有Car实例存放的都是指向showColor()函数的指针.所有属性看起来都属于同一个对象,因此解决了前面两种方式的两个问题
可以用instanceof运算符测试对象的类型
eg: alert(oCar1 instanceof Car) //output “true”;
问题:
1、构造函数没有参数.必须创建后才能改变属性的默认值,有些讨厌
2、真正的问题在于,当属性指向对象时,对象会被多个实例共享。不灵活
如:
function Car(){};
Car.prototype.color = “red”;
Car.prototype.doors = 4;
Car.prototype.showColor = function(){
alert(this.color);
}
Car.prototype.drivers = new Array(“a”,”b”);
//call
var oCar1 = new Car();
var oCar2 = new Car();
oCar1.drivers.push(“c”);
alert(oCar1.drivers); //output “a”,”b”,”c”;
alert(oCar2.drivers); //outpub “a”,”b”,”c”;
解决方法: 联合使用构造函数和原型方式
联合使用构造函数和原型方式,就可像用其他程序设计语言一样创建对象.这种概念非常简单,即用构造函数定义对象的所有非函数属性,用原型方式定义对象的函数属性(方法).结果所有函数都只创建一次,而每个对象都具有自己的对象属性实例.
eg: function Car(sColor,iDoors){//实例化的时候不实例化ShowColor这个函数
this.color = sColor;
this.doors = iDoors;
this.drivers = new Array();
}
Car.prototype.ShowColor = function(){
alert(this.color);
}
//Call
var oCar1 = new Car(“red”,4,23);
var oCar2 = new Car(“blue”,3,25);
oCar1.drivers.push(“a”);
oCar2.drivers.push(“b”);
alert(oCar1.drivers); //output “a”;
alert(oCar2.drivers); //output “b”;
} 问题:此种方式已接近完善
但类的定义分散在两部分,感觉还不是很完美
解决办法:
动态原型方法
Function Car(sColor,iDoors,iMpg){
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers=new Array();
if (typeof Car._initialized==“undefined”){//initialized随便起的,刚创建的时候肯定不存在
Car.prototype.showColor = function(){
alert(this.color);
};
Car._initialized = true;
//下次再定义这个类的实例,initalized就有值了,就不会重新定义这个方法了
}
}
//call
} var oCar = new Car("yellow",10,20);
} oCar.showColor(); //output “yellow”
采用哪种方式?
如前所述,目前使用最广泛的是混合的构造函数/原型方法.此外,动态原型方法也很流行,功能上和前者等价.可以采用上述方法中的一种.
实例:
1、利用javaScript的面向对象技术封装一个字符串连结的类.
传统的方式:
var str=“hellow”
str +=“world”
缺点:字符串的不变性,导致这种做法很没有效率
} 改进一
var Arr = new Array();
Arr[0]=“hellow”;
Arr[1]=“world”;
var str = Arr.join(““);
虽然解决了效率问题,但不太优雅.
} 改进二
function StringBuffer()
{
this._strings_=new Array(); //私用属性
}
StringBuffer.prototype.append = function(str)
{
this._strings_.push(str);
}
StringBuffer.prototype.toString=function(){ return this._strings_.join(“”); //join() 方法用于把数组中的所有元素放入一个字符串。
}
} //call 使用
} var strobj = new StringBuffer();
} strobj.append("hellow");
} strobj.append("world");
} alert(strobj.toString());
修改对象已有的属性,创建新方法
Eg1:
Number.prototype.toHexString=function()
{
return this.toString(16);
}
//call
var iNum=15;
alert(iNum.toHexString()); //output “f”
} Eg2 给array扩展3个方法
Array.prototype.enqueue=function(vItem)
{
this.push(vItem);//想对象添加值
}
Array.prototype.dequeue = function()
{
return this.shift();
shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值
}
Array.prototype.indexOf=function(vItem){
for(var i=0;i<this.length;i++)
{
if (vItem == this[i])
return i;
}
return -1;
}
} //call
} var arr = new Array();
} arr.enqueue("aaa");
} arr.enqueue("bbb");
} arr.enqueue("ccc");
} arr.dequeue();
} alert(arr.indexOf("aaa"));
Eg3.扩展Object
Object.prototype.alert = function()
{
alert(this.valueOf());
}
//call
var str=“hellow”;
var iNum = 25;
str.alert();
iNum.alert();
重定义已有方法
Function.prototype.toString = function(){
return “”; }
function sayHi(){
alert(“hi”); }
//call
alert(sayHi.toString()); //output “”
发表评论
-
新课标人教版必修五第二单元阅读理解专项训练
2012-01-20 11:41 750新课标人教版必修五第二单元阅读理解专项训练 2011年11月 ... -
2012-1-17
2012-01-20 11:41 5962012-1-17 2012年01月17日 十二星座男生 ... -
小学十一册英语期末测试题(答案)(终于给同学们打完答案了,颈椎已经酸麻。请同学们一定要先认真答题后再对照答案改正。这样才能保证期末考出好成绩!)
2012-01-20 11:41 701小学十一册英语期末测试题(答案)(终于给同学们打完答案了,颈椎 ... -
JS学习---ECMAScript对象
2012-01-19 16:31 601JS学习---ECMAScript对象 2010年11月25 ... -
【转】 Flex远程调用机制RemoteObject应用技巧
2012-01-19 16:31 702【转】 Flex远程调用机 ... -
AS3.0 中root和parent的用法
2012-01-19 16:31 755AS3.0 中root和parent的用法 2011年01月 ... -
Flex 4中DropDownList的奇怪问题
2012-01-19 16:31 620Flex 4中DropDownList的奇怪问题 2011年 ... -
关于malloc函数后free内存空间的疑问
2012-01-17 06:16 757关于malloc函数后free内存空间的疑问 2011年11 ... -
c库函数和系统调用的区别(很模糊)
2012-01-17 06:16 590c库函数和系统调用的区 ... -
系统调用、POSIX、C库、系统命令和内核函数
2012-01-17 06:16 528系统调用、POSIX、C库、 ... -
怎样评价学生的习作
2012-01-17 06:16 586怎样评价学生的习作 20 ... -
如何培养小学生写日记的兴趣
2012-01-17 06:16 702如何培养小学生写日记 ... -
神马五一第一天
2012-01-16 04:56 572神马五一第一天 2011年04月30日 神马五一第一天, ... -
神马都是浮云
2012-01-16 04:56 519神马都是浮云 14小时前 看透了好多,也经历的 ... -
在金钱面前一切都是浮云
2012-01-16 04:56 539在金钱面前一切都是浮云 2012年01月12日 神马世界 ... -
? ,浮云。
2012-01-16 04:56 553? ,浮云。 2012年01月11日 ... -
消逝的战场之神马将军
2012-01-16 04:56 565消逝的战场之神马将军 2012年01月14日 还记得小时 ...
相关推荐
我总结的Android编程规范 - 薰衣草的旋律 - 博客园1
开源的搜索引擎工具包和web搜索引擎系统 - austin lius fashion - 博客园.docx开源的搜索引擎工具包和web搜索引擎系统 - austin lius fashion - 博客园.docx开源的搜索引擎工具包和web搜索引擎系统 - austin lius ...
开源的搜索引擎工具包和web搜索引擎系统 - austin lius fashion - 博客园.pdf开源的搜索引擎工具包和web搜索引擎系统 - austin lius fashion - 博客园.pdf开源的搜索引擎工具包和web搜索引擎系统 - austin lius ...
推荐--jQuery使用手册 - 仰天一笑 - 博客园
ibatis缓存介绍 - 勇泽 - 博客园ibatis缓存介绍 - 勇泽 - 博客园ibatis缓存介绍 - 勇泽 - 博客园ibatis缓存介绍 - 勇泽 - 博客园
Java并发编程:线程池的使用 - 平凡希 - 博客园平凡希博客园首页联系管理随笔 - 127 文章 - 1 评论 - 94Java并发编程:线程池的使用在前面
【转】c# xml添加 删除 修改数据 - badnewfish - 博客园.htm【转】c# xml添加 删除 修改数据 - badnewfish - 博客园.htm【转】c# xml添加 删除 修改数据 - badnewfish - 博客园.htm【转】c# xml添加 删除 修改数据 -...
javascript小技巧&&JavaScript[对象_属性]集锦 [转载了多篇] - 天轰穿_net-vs2005-ajax入门 - 博客园
Entity Framework 6 Recipes 中文翻译系列-By博客园-china_fucan
3. Re:JS面向对象的程序设计 4. Re:查看LINUX进程内存占用情 1. 查看LINUX进程内存占用情况 2. Linux上Oracle 11g安装步
图解]ARP协议(一) - 博客园.pdf
Spring.NET学习笔记 - 刘冬.NET - 博客园
C# 绘制统计图(柱状图, 折线图, 扇形图) - steven_2005 - 博客园
AjaxPro使用说明 - lexus - 博客园 Ajax是异步Javascript和XML(Asynchronous JavaScript and XML)的英文缩写。"Ajax"这个名词的发明人是Jesse James Garrett,而大力推广并且使Ajax技术炙手可热的是Google。Ajax的...
C#编程总结(九)字符编码 - 停留的风 - 博客园.mhtml
JAVA中堆和栈的区别 - 路人浅笑 - 博客园,网上摘取学习java的资料,介绍了JAVA中堆和栈的区别 ,希望对大家有所帮助!
Linux 桌玩家指南:06. 优雅地使命令及 Bash 脚本编程语中的美学与哲学 - 京游侠 - 博客园Linux 桌玩家指南:06. 优雅地使命令及 Bas
数字设计中的时钟与约束 - IC_learner - 博客园.pdf
QVector常见使用方法 - 浅浅念 - 博客园随笔- 68 文章- 0 评论- 14博客园 首页 新随笔 联系 管理 订阅QVector常见使用方法仅在此简
Qt 格式化字符串 - Avatarx - 博客园博客园首页新随笔联系管理订阅随笔- 1695 文章- 0 评论- 3Qt 格式化字符串Qt字符串格式化性能比较