JavaScript 定义类,定义属性,定义方法的几种方式详解及分析
来源:互联网 发布:手机淘宝账号余额查询 编辑:程序博客网 时间:2024/06/11 17:47
JavaScript 定义类,定义属性,定义方法的几种方式详解及分析
提起面向对象我们就能想到类,对象,封装,继承,多态。在《
javaScript
高级程序设计》
(人民邮电出版社,曹力、张欣译。英文名字是:
Professional JavaScript for Web
Developers
)这本书中描述的还算比较详细。我们看看
JavaScript
中定义类的各种方法。
1.工厂方式
javaScript
中创建自己的类和对象,
我们应该是必须掌握的,我们都知道javaScript中对象的属性可以在对象创建后动态定义,比如下面的代码:
//定义var oCar = new Object(); oCar.color = "red"; oCar.doors = 4; oCar.showColor = function() { alert(this.color);} //调用oCar.showColor();我们很容易使用
oCar
对象,但是我们创就是想创建多个
Car
实例。我们可以使用一个
函数来封装上面的代码来实现:
//定义function createCar() { var oCar = new Object(); oCar.color = "red"; oCar.doors = 4; oCar.showColor = function() { alert(this.color); } return oCar; } //调用var ocar1 = createCar(); var ocar2 = createCar(); ocar1.color = "black"; ocar1.showColor(); ocar2.showColor();顺便说一下,
javaScript
对象默认成员属性都是
public
的。
这种方式我们称为工厂方式,
我们创造了能创建并返回特定类型的对象的工厂。
这样做有点意思了,但是在面向对象中我们经常使用创建对象的方法是:
Car car=new Car();
使用
new
关键字已经深入人心,
因此我们使用上面的方法去定义总感觉别扭,
并且每次
调用时都去创建新的属性以及函数,
功能上也不实际。
下来我们看看构造函数的形式定义类。
2
.构造函数
这种方式看起来有点象工厂函数。具体表现如下:
//定义function Car(color, doors) { this.color = color; this.doors = doors; this.showColor = function() { alert(this.color); }; } //调用var car1 = new Car("red", 4); var car2 = new Car("blue", 4); car1.showColor(); car2.showColor();看起来效果很明显,
有差别了吧。
感觉有点意思了。
在构造函数内部创造对象使用
this
关
键字,使用
new
运算符创建对象感觉非常亲切。但是也有点问题:每次
new
对象时都会
创建所有的属性,
包括函数的创建,
也就是说多个对象完全独立,
我们定义类的目的就是为
了共享方法以及数据,
但是
car1
对象与
car2
对象都是各自独立的属性与函数,
最起码我们
应该共享方法。这就是原形方式的优势所在。
3
.原型方式
利用对象的
prototype
属性,可把它看出创建新对象所依赖的原型。方法如下:
//定义function Car() { }; Car.prototype.color = "red"; Car.prototype.doors = 4; Car.prototype.drivers = new Array("Tom", "Jerry"); Car.prototype.showColor = function() { alert(this.color); } //调用:var car1 = new Car(); var car2 = new Car(); car1.showColor(); car2.showColor(); alert(car1.drivers); car1.drivers.push("stephen"); alert(car1.drivers); //结果:Tom,Jerry,stephen alert(car2.drivers); //结果:Tom,Jerry,stephen //可以用json方式简化prototype的定义: Car.prototype = { color: "red", doors: 4, drivers: ["Tom", "Jerry",'safdad'], showColor: function() { alert(this.color); } 首先这段代码的构造函数,其中没有任何代码,接下来通过对象的prototype属性添加属性定义Car对象的属性。这种方法很好,但是问题是Car的对象指向的是Array指针,Car的两个对象都指向同一个Array数组,其中一个对象car1改变属性对象的引用(数组Array)时,另一个对象car2也同时改变,这是不允许的。同时该问题也表现在原型不能带任何初始化参数,导致构造函数无法正常初始化。这需要另一种方式来解决:那就是混合的构造函数/原型模式。4. 混合的构造函数/原型模式联合使用构造函数和原型方式,定义类就非常方便。 //定义function Car(color,doors) { this.color=color; this.doors=doors; this.drivers=new Array("Tom","Jerry"); } Car.prototype.showColor=function(){ alert(this.color); } //调用:var car1=new Car('red',4); var car2=new Car('blue',4); car1.showColor(); car2.showColor(); alert(car1.drivers); car1.drivers.push("stephen"); alert(car1.drivers); //结果:Tom,Jerry,stephen alert(car2.drivers); //结果:Tom,Jerry alert(car1 instanceof Car);该方法是把属性放在内部定义,
把方法放在外边利用
prototype
进行定义。
解决了第三种
方法的问题。
这种方法其实应该来说非常友好了,但是比起
java
的语法来,应该有一些不和谐,感觉
比较凌乱,对
C++
来说,我们就没有那么麻烦的感觉了,可是开发
C++
的研发人员一般情
况下很少涉及
javaScript
,而对
J2EE
的研发人员来说,这种方式总有一些别扭。总感觉不
是友好的封装,
其实只不过是视觉上封装效果不是很好而已,
要想达到视觉封装效果而又能
达到这种方法的效果的也可以,个人认为其实比较麻烦。那就是动态原型法。
5.
动态原型
对于习惯使用其他语言的开发者来说,使用混合的构造函数
/
原型方式感觉不那么和谐。毕
竟,定义类时,大多数面向对象语言都对属性和方法进行了视觉上的封装。考虑下面的
C#
类:
class Car //class
{
public string color = “red”;
public int doors = 4;
public int mpg = 23;
public Car(string color, int doors, int mpg) //constructor
{
this.color = color;
this.doors = doors;
this.mpg = mpg;
- JavaScript 定义类,定义属性,定义方法的几种方式详解及分析
- JavaScript定义类,定义属性,定义方法的几种方式详解与分析
- JavaScript定义类,定义属性,定义方法的几种方式详解与分析
- JavaScript定义类,定义属性,定义方法的几种方式详解与分析
- JavaScript定义类的几种方式
- JavaScript定义类的几种方式
- JavaScript定义类的几种方式
- JavaScript定义类的几种方式
- JavaScript定义类的几种方式
- JavaScript定义类的几种方式
- javascript定义类的几种方法
- javascript定义类的几种方法
- javascript定义函数的几种方式
- Javascript定义函数的几种方式
- Javascript对象定义的几种方式
- javascript定义函数的几种方式
- JavaScript定义对象的几种方法
- javascript定义类或对象的几种方式
- 关于ARM的PC指针(什么时候PC+8,PC+4,PC-4,PC-8)
- Linux下的bash
- Android Studio中的快捷键介绍
- jQuery对下拉框Select操作总结
- jquery中的图片放大镜插件--jqzoom的配置参数
- JavaScript 定义类,定义属性,定义方法的几种方式详解及分析
- 读取()txt文件中的内容与向txt文件中写入内容(覆盖重写与在末尾续写+FileOutputStream与FileWriter)
- SVN中 “containing working copy admin area is missing” 问题
- 01背包
- getsupportfragmentmanager()找不到这个方法
- SVN误删根目录导致无法安装无法卸载无法更改办法( invalid device K:\)
- STM32F4板子使用LWIP进行组播收发数据的完整过程,附代码
- 【代码笔记】iOS-评分系统(小星星)
- SQLSERVER2008R2创建分区表、转换分区表、交换数据