javascript中类的定义及其方式(《javascript高级程序设计》学习笔记)


Posted in Javascript onJuly 04, 2011

关于javascript中类的继承可以参考阮一峰的Blog《Javascript继承机制的设计思想》,说的很透。

一、在javascript中实例化遇到的问题:

下面用《javascript高级程序设计》中的例子来做说明,假如现在定义了一个car的对象,它是Object类的实例。像下面这样的:

var oCar=new Object(); 
oCar.color = "red"; 
oCar.doors = 4; 
oCar.mpg = 23; 
oCar.showColor = function () { 
alert(this.color); 
};

现在又需要这样的一个实例,你可能会像这样来定义:
var oCar2 = new Object(); 
oCar2.color = "blue"; 
oCar2.doors = 5; 
oCar2.mpg = 25; 
oCar2.showColor = function () { 
alert(this.color); 
};

这样遇到的问题是每个对象都需要重新定义一次他的字段和方法。很麻烦。

二、类的定义--工厂方式实现:

对上面的例子进行一个包装,利用函数的返回值来做文章:

function createCar() { 
var oTempCar = new Object(); 
oTempCar.color = "red"; 
oTempCar.doors = 4; 
oTempCar.mpg = 23; 
oTempCar.showColor = function () { 
alert(this.color); 
}; 
return oTempCar; 
}

调用方式:

var oCar1 = createCar();
var oCar2 = createCar();

这种方式被称之为工厂方式。工厂方式看起来是省事多了。起码创建一个对象的时候不再需要那么多的行数。因为每个属性(color,doors,mpg)的值都是固定的,还需要再次进行改造,利用参数传递来实现:

function createCar(sColor, iDoors, iMpg) { 
var oTempCar = new Object(); 
oTempCar.color = sColor; 
oTempCar.doors = iDoors; 
oTempCar.mpg = iMpg; 
oTempCar.showColor = function () { 
alert(this.color); 
}; return oTempCar; 
} 
var oCar1 = createCar("red", 4, 23); 
var oCar2 = createCar("red", 4, 23); 
oCar1.showColor(); 
oCar2.showColor();

这样做看似的确可以实现了对象了。实现也很简单,调用也很方便。但是有两个不是很好的地方:

1、从语义上看,在创建对象时没有使用new运算符,似乎不是那么正规(通常创建一个对象都用一个new运算符来实现)。

2、不符合面向对象的特征--封装。在这个例子中,oCar1和oCar2都有自己的showColor方法,并且他们的showColor都是自己的实现。但是事实是他们共享的是同一个函数。

也是有办法解决这个共享函数的问题,利用函数指针来解决。在createCar函数之外再创建一个showColor函数,而oTempCar的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("red", 4, 23); 
oCar1.showColor(); 
oCar2.showColor();

虽然这样解决了重复创建函数的问题,但这样的话,就使showColor函数看起来不像是对象的方法。

三、类的定义--构造函数方式实现:

function Car(sColor, iDoors, iMpg) { 
//通过构造函数的形式,会为每个对象生成独立的属性和函数 
this.color = sColor; 
this.doors = iDoors; 
this.mpg = iMpg; 
this.showColor = function () { 
alert(this.color); 
}; } 
var oCar1 = new Car("red", 4, 23); 
var oCar2 = new Car("red", 4, 23); 
oCar1.showColor(); 
oCar2.showColor();

在Car类中,this指针代表了Car的一个实例,因此不需要返回值。虽然构造函数方式实现了类的定义,但是和工厂方式一样,他也是为每个实例创建一个单独的方法。虽然可以像工厂函数一样在函数之外再创建一个函数利用指针来解决这个问题,但是这么做的话,在语义上没有意义。

四、类的定义--原型方式实现:

利用对象的prototype属性,把它看成是创建新对象所依赖的原型。用空构造函数来设置类名。然后所有的属性和方法都被直接赋予prototype属性。

function Car() { } 
Car.prototype.color = "red"; 
Car.prototype.doors = 4; 
Car.prototype.mpg = 23; 
Car.prototype.showColor = function () { 
alert(this.color); 
}; 
var oCar1 = new Car(); 
var oCar2 = new Car(); 
alert(oCar1 instanceof Car);//output true这里存在两个问题:

1、构造函数没有参数。使用原型时,不能通过给函数参数传递参数来初始化属性值。

2、在有多个实例时,对其中一个实例的属性的更改会影响到另外一个实例的属性。

测试代码:

var oCar1 = new Car(); 
oCar1.color = "Green"; var oCar2 = new Car(); 
oCar2.color = "Black"; 
alert(oCar1.color); //output Green 
alert(oCar2.color); //output Black 
alert(oCar1.color); //output Black

当然了,也会有办法解决这个问题的。那就是混合的构造函数/原型方式

五、类的实现--混合的构造函数/原型方式实现

这种实现方式是将每个类的实例中共享的属性或者方法妨到原型链中实现,而将不需要共享实现的属性和方法放在构造函数中实现。这中类的实现方式是使用最广泛的方式。

function Car(sColor, iDoors, iMpg) { 
this.color = sColor; 
this.doors = iDoors; 
this.mpg = iMpg; 
this.drivers = new Array("Mike", "Sue"); 
} 
Car.prototype.showColor = function () { 
alert(this.color); 
}; var oCar1 = new Car("red", 4, 23); 
var oCar2 = new Car("blue", 3, 24); 
oCar1.drivers.push("Matt"); 
alert(oCar1.drivers); 
alert(oCar2.drivers);六、类的定义--动态原型方式实现

这种方式和混合的构造函数/原型方式相比,提供了一种友好的编程风格(在混合的构造函数/原型方式中,showColor方法的定义是在方法体外实现的,而不是在构造函数的方法体内完成的)。这种类的定义方式使用也很多。
function Car(sColor, iDoors, iMpg) { 
this.color = sColor; 
this.doors = iDoors; 
this.mpg = iMpg; 
this.divers = new Array("Mike", "Sue"); if (typeof Car._initialized == "undefined") { 
Car.prototype.showColor = function () { 
alert(this.color); 
}; 
Car._initialized = true; 
}

七、类的定义--混合工厂方式实现
function Car() { 
var oTempCar = new Object(); 
oTempCar.color = "red"; 
oTempCar.doors = 4; 
oTempCar.mpg = 23; 
oTempCar.showColor = function () { 
alert(this.color); 
}; 
return oTempCar; 
} var car = new Car(); 
car.showColor();

这种方式和工厂方式看起来差不多。由于在Car()构造函数内部调用了new运算符,所以将忽略掉位于构造函数之外的new运算符。在构造函数内部创建的对象被传回变量var。虽然看起来有了new运算符了,比工厂方式有了一些进步,但是这种实现方式也是会出现重复创建方法的问题。因此也不推荐使用这种方式来定义类。
Javascript 相关文章推荐
关于JavaScript中var声明变量作用域的推断
Dec 16 Javascript
js中判断数字\字母\中文的正则表达式 (实例)
Jun 29 Javascript
JS中数组Array的用法示例介绍
Feb 20 Javascript
判断window.onload是否多次使用的方法
Sep 21 Javascript
总结JavaScript设计模式编程中的享元模式使用
May 21 Javascript
Bootstrap组件系列之福利篇几款好用的组件(推荐)
Jun 23 Javascript
微信小程序 image组件binderror使用例子与js中的onerror区别
Feb 15 Javascript
protractor的安装与基本使用教程
Jul 07 Javascript
小程序scroll-view组件实现滚动的示例代码
Sep 20 Javascript
layui实现鼠标移动到单元格上显示数据的方法
Sep 11 Javascript
微信小程序实现二维码签到考勤系统
Jan 16 Javascript
vuecli3.x中轻松4步带你使用tinymce的步骤
Jun 25 Javascript
js静态方法与实例方法分析
Jul 04 #Javascript
JavaScript 变量作用域分析
Jul 04 #Javascript
JavaScript XML和string相互转化实现代码
Jul 04 #Javascript
JS对外部文件的加载及对IFRMAME的加载的实现,当加载完成后,指定指向方法(方法回调)
Jul 04 #Javascript
jQuery 对Select的操作备忘记录
Jul 04 #Javascript
javascript开发技术大全 第4章 直接量与字符集
Jul 03 #Javascript
javascript开发技术大全-第3章 js数据类型
Jul 03 #Javascript
You might like
ThinkPHP中create()方法自动验证实例
2017/04/26 PHP
php和redis实现秒杀活动的流程
2019/07/17 PHP
只需一行代码,轻松实现一个在线编辑器
2013/11/12 Javascript
Bootstrap精简教程
2015/11/27 Javascript
Bootstrap导航条可点击和鼠标悬停显示下拉菜单的实现代码
2016/06/23 Javascript
BooStrap对导航条的改造实践小结
2016/09/21 Javascript
JS自定义函数实现时间戳转换成date的方法示例
2017/08/27 Javascript
Vue2.0 实现移动端图片上传功能
2018/05/30 Javascript
vue-router实现编程式导航的代码实例
2019/01/19 Javascript
Vue 使用Props属性实现父子组件的动态传值详解
2019/11/13 Javascript
11个Javascript小技巧帮你提升代码质量(小结)
2020/12/28 Javascript
Windows系统下安装Python的SSH模块教程
2015/02/05 Python
Python实现扩展内置类型的方法分析
2017/10/16 Python
python机器学习库scikit-learn:SVR的基本应用
2019/06/26 Python
Python求正态分布曲线下面积实例
2019/11/20 Python
python为什么要安装到c盘
2020/07/20 Python
python Cartopy的基础使用详解
2020/11/01 Python
Python爬虫实例之2021猫眼票房字体加密反爬策略(粗略版)
2021/02/22 Python
canvas实现高阶贝塞尔曲线(N阶贝塞尔曲线生成器)
2018/01/10 HTML / CSS
查找廉价航班和发现新目的地:Kiwi.com
2019/02/25 全球购物
Yankee Candle官网:美国最畅销蜡烛品牌之一
2020/01/05 全球购物
芭比波朗加拿大官方网站:Bobbi Brown Cosmetics CA
2020/11/05 全球购物
如何强制垃圾回收
2015/10/06 面试题
秘书岗位职责
2013/11/18 职场文书
初中优秀教师事迹材料
2014/08/18 职场文书
房屋买卖授权委托书
2014/09/27 职场文书
2014年工作总结与下年工作计划
2014/11/27 职场文书
2014年便民服务中心工作总结
2014/12/20 职场文书
黄石寨导游词
2015/02/05 职场文书
高中生打架检讨书1000字
2015/02/17 职场文书
2015年端午节国旗下演讲稿
2015/03/19 职场文书
2015年招生工作总结
2015/05/04 职场文书
机器人瓦力观后感
2015/06/12 职场文书
机关干部纪律作风整顿心得体会
2016/01/23 职场文书
高中化学教学反思
2016/02/22 职场文书
Python标准库pathlib操作目录和文件
2021/11/20 Python