- 浏览: 1339293 次
- 性别:
- 来自: 湖南澧縣
文章分类
最新评论
-
虾米小尹:
不行啊!2.2-0.25=1.9500000000000002 ...
JavaScript浮点数运算 —— 精度问题 -
heluping000000:
引用String a= "abc",首先在 ...
String,到底创建了多少个对象? -
mack:
谢谢分享matcher.appendReplacement(s ...
string.replaceAll()中的特殊字符($ \)与matcher.appendReplacement -
wzt3309:
完全理解,比网上其他资料都要详细
String,到底创建了多少个对象? -
u014771876:
Java中十六进制转换 Integer.toHexString()
可以以六种方式定义类或对象:工厂方式、构造函数方式、原型方式、混合的构造函数/原型方式、动态原型方法、混合工厂方式 ,下面看看个体每种方式。
-
工厂方式
var oCar = new Object; oCar.color = "red"; oCar.doors = 4; oCar.mpg = 23; oCar.showColor = function () { alert(this.color); };
上面的创建方式有一点不太好就是的,如果要创建多个car对象时,这时我们就会要重复写上面的代码,指定color、doors、mpg与 showColor属性方法。要解决此问题,开发者创造了能创建并返回特定类型的对象的工厂函数(factory function)。例如,函数createCar()可用于封装前面列出的创建car对象的操作:
function createCar(color, doors, mpg) { var oTempCar = new Object; oTempCar.color = color; oTempCar.doors = doors; oTempCar.mpg = mpg; oTempCar.showColor = function () { alert(this.color + " " + this.doors + " " + this.mpg); }; return oTempCar; } var oCar1 = createCar("red", 4, 23); var oCar1 = createCar("blue", 3, 25);
以上方式存在功能问题:功能问题在于用这种方式必须创建对象的方法。上面的例子中,每次调用函数createCar(),都要创建新函数 showColor(),意味着每个对象都有自己的showColor()版本,事实上,每个对象都是可以共享同一个函数。但下面可以避开此种问题,请看重写后的代码:
function showColor() { alert(this.color + " " + this.doors + " " + this.mpg); } function createCar(color, doors, mpg) { var oTempCar = new Object; oTempCar.color = color; oTempCar.doors = doors; oTempCar.mpg = mpg; oTempCar.showColor = showColor; return oTempCar; }
-
构造函数方式
function Car(color, doors, mpg) { this.color = color; this.doors = doors; this.mpg = mpg; this.showColor = function () { alert(this.color + " " + this.doors + " " + this.mpg); }; } var oCar1 = new Car("red", 4, 23); var oCar2 = new Car("blue", 3, 25); oCar1.showColor(); oCar2.showColor();
你可能已经注意到第一个差别了,在构造函数内部无创建对象,而是使用this关键字。使用new运算符调用构造函数时,在执行第一行代码前就先创建出一个对象,然后才是执行构造函数,这与Java是一样的。在对象里面也只有用this才能访问该对象。this默认情况下是构造函数的返回值(不必明确使用 return运算符)
。
现在,用new运算符和类名Car创建对象,就更像创建ECMAScript中一般对象了。你也许会问,这种方式在管理函数方面是否存在与前一种方式相同的问题呢?是的。就像工厂函数,构造函数会重复生成函数,为每个对象都创建独立的函数版本。不过,与工厂函数相似,也可以用外部函数重写构造函数,同样的,语义上无任何意义。这就是原型方式的优势所在。
-
原型方式
该方式利用了对象的prototype属性,可把它看成创建新对象所依赖的原型。这里,用空构造函数来设置类名。然后所有的属性和方法都被直接赋予prototype属性。重新前面的例子,代码如下所示:
function Car() { } Car.prototype.color = "red"; Car.prototype.doors = 4; Car.prototype.mpg = 23; Car.prototype.showColor = function () { alert(this.color + " " + this.doors + " " + this.mpg); }; var oCar1 = new Car(); var oCar2 = new Car(); oCar1.showColor(); oCar2.showColor();
在这段代码中,首先定义构造函数(Car),其中无任何代码。接下来的几行代码,通过给Car的prototype属性添加属性定义Car对象的属性。调用new Car()时,原型的所有属性都被立即赋予要创建的对象,意味着所有Car实例存放的都是指向showColor()函数的指针。从语义上讲,所有属性看起来都属于一个对象,因此解决了前面两种方式的两个问题。
这个看起来是个非常好的解决方案。遗憾的是,并非尽如人意。
首先,这个构造函数没有参数。使用原型方式时,不能通过给构造函数传递参数初始化属性的值,因为car1和car2的color属性都等于"red",doors属性都等于4,mpg属性都等于23。这意味必须在对象创建后才能改变属性的默认值,这点很令人讨厌,但这还不是真真的问题所在。真正的问题出现在属性如果指向的是一个对象,而不是函数时。函数共享不会造成任何问题,因为代码区永远是可以共享的,但对象一般却不是我们所需要的多个实例共享的它。如果在上面代码的基础上为原型加如下属性时:
Car.prototype.Drivers = new Array('Mike','Sue'); oCar1.drivers.push('Matt'); alert(oCar1.drivers);//Mike,Sue,Matt alert(oCar2.drivers); //Mike,Sue,Matt
由于drivers是引用值,Car的两个实例都指向同一个数组。这意味着给car1.drivers添加值"Matt",在car2.drivers中也能看到。
上面创建对象有很多的问题,下面联合使用构造函数和原型方式来解决这些问题。
-
混合的构造函数/原型方式
用构造函数定义对象的所有非函数属性,用原型方式定义对象的函数属性(方法)。结果所有函数都只创建一次,而每个对象都具有自己的对象属性实例。再重写前面的例子,代码如下:
function Car(color, doors, mpg) { this.color = color; this.doors = doors; this.mpg = mpg; this.drivers = new Array("Mike", "Sue"); } Car.prototype.showColor = function () { alert(this.color + " " + this.doors + " " + this.mpg); }; var oCar1 = new Car("red", 4, 23); var oCar2 = new Car("blue", 3, 25); oCar1.drivers.push("Matt"); alert(oCar1.drivers);//Mike,Sue,Matt alert(oCar2.drivers);//Mike,Sue
现在就更像创建一般对象了。所有的非函数属性都在构造函数中创建。因为只创建showColor()函数的一个实例,所以没有内存浪费。这种方式是 ECMAScript主要采用的方式,它具有其他方式的特性,却没有它们的副作用。不过,有些开发者仍觉得这种方法不够完美。
-
动态原型方法
批评混合的构造函数/原型方式的人认为,面向对象的设计就要求把属性与方法封装在类里面,而在其外部定义方法的做法不合逻辑。因此,他们设计了动态原型方法,以提供像面向对象语言一样的更友好的编码风格。
动态原型方法的基本想法与混合的构造函数/原型方式相同,即在构造函数内定义非函数属性,而函数属性则利用原型属性定义。唯一的区别是赋予对象方法的位置,把函数属性的定义放置到了构造函数里。下面是用动态原型方法重写的Car类:
function Car(color, doors, mpg) { this.color = color; this.doors = doors; this.mpg = mpg; this.drivers = new Array("Mike", "Sue"); if (typeof Car._initialized == "undefined") { Car.prototype.showColor = function () { alert(this.color + " " + this.doors + " " + this.mpg); }; Car._initialized = true; } }
该方法使用标志(_initialized)来判断是否已给原型赋予了任何方法。该方法只创建并赋值一次,为取悦传统的OOP开发者,这段代码看起来更像其他语言中的类定义了。
-
混合工厂方式
创建假构造函数,只返回另一种对象的新实例。这段代码看来与工厂函数非常相似:
function Car(color, doors, mpg) { var oTempCar = new Object; oTempCar.color = color; oTempCar.doors = doors; oTempCar.mpg = mpg; oTempCar.showColor = function () { alert(this.color + " " + this.doors + " " + this.mpg); }; return oTempCar; }
与经典方式不同,这种方式使用new运算符,使它看起来像真正的构造函数:
var car = new Car();
由于在Car()构造函数内部调用了new运算符,所以将忽略赋值表达中的new运算符(位于构造函数之外)(注:如果返回的是一个基本类型,则会忽略方法里的return,具体原理请见《7、对象》——《构造函数》 一节) 。在构造函数内部创建的对象被传递回变量car。这种方式在对象方法的内部管理方面与经典方式有着相同的问题。建议还是避免使用这种方式。
-
采用哪种方式
如前所述,目前使用最广泛的是混合的构造函数/原型方式。此外,动态原型方法也很流行,在功能上与构造函数/原型方式等价。可以采用这两种方式中的任何一种。不过不要单独使用经典的构造函数或原型方式,因为这样会给代码引入问题。
发表评论
-
HTML、JS、JSON特殊字符
2010-12-13 23:47 25892JS到HTML特殊字符转换 这几天做项目,发现从服务器端以J ... -
HTML — HTTP URL 中的特殊字符
2009-10-31 18:16 33141. + URL中的+号表示空格 ... -
HTML — CSS选择器
2009-10-25 21:11 2179一个样式规则由两部分组成:选择器和样式声明。选择器表明要为哪一 ... -
部分解决JsUnit无法在firefox3、safari 测试的问题
2009-10-25 07:03 1449在上一篇中出现了一个问题,就是用 jsunit2.2alpha ... -
JsUnit——eclipse插件(四)
2009-10-25 06:59 2455这节我们来看看如何通过JsUnit插件来运行前几节所测试过的测 ... -
10、JavaScript跨浏览器需注意的问题——ajax基础笔记
2009-10-21 22:19 1380向表中追加行 创建表格行时,我们要把创建的 tr 追加到 t ... -
JsUnit详解——Web服务方式(三)
2009-10-21 00:21 2463上两节提到过以Web方式来运行JsUnit,不过不是很详细,这 ... -
JsUnit详解——《ajax基础》笔记(二)
2009-10-20 22:38 2548使用标准/定制查询串 如此说来,测试运行工具是很强大的,但是 ... -
JsUnit详解——《ajax基础》笔记(一)
2009-10-20 19:57 2638JsUnit与JUnit对比 JsUnit也有setUp() ... -
使用Firefox的Web开发插件
2009-10-18 17:53 1482Firefox的Web开发插件为Firefox浏览器增加了大量 ... -
9、访问WEB服务(REST)——ajax基础笔记
2009-10-18 17:24 4057最其名的WEB服务实现是S ... -
8、读取响应头部——ajax基础笔记
2009-10-18 17:20 6765你有时可能需要从服务器获取一些内容,例如,可能想“ping”一 ... -
7、使用JSON向服务器发送数据——ajax基础笔记
2009-10-18 17:20 5243看过前面的例子后(使用XML向服务器发送复杂的数据结构),你可 ... -
6、请求参数作为XML发送——ajax基础笔记
2009-10-18 17:20 1806如果只是使用一个包含 名/值 对的简单查询串,这可能不够健壮, ... -
4、将使用W3C DOM动态生成页面——ajax基础笔记
2009-10-18 17:19 1461使用W3C DOM动态生成页面 dynamicContent ... -
3、将响应解析为XML——ajax基础笔记
2009-10-18 17:18 1077将响应解析为XML parseXML.xml清单: < ... -
2、使用innerHTML属性创建动态内容——ajax基础笔记
2009-10-18 17:17 1937使用innerHTML属性创建动态内容 如果结合作用HTML ... -
1、使用XMLHttpRequest对象——ajax基础笔记
2009-10-18 17:17 2030XMLHttpRequest最早是在 IE5 中以active ... -
30、JavaScript代码优化
2009-10-16 21:25 1578JavaScript代码的速度被分成两部分:下载时间和执行速度 ... -
JavaScript代码优化(二)
2009-10-16 01:32 1205◆字符串的使用 在IE6和IE7中因字符串级联导致的主要问题 ...
相关推荐
1. **正确** - 类可以看作是一类对象的模板,而对象是根据类创建的具体实例。 2. **正确** - Java会为未初始化的成员变量赋予默认值,如数值变量为0,布尔变量为false,引用变量为null。 3. **错误** - 局部变量在...
类和对象的概念和定义方法 在C++中,类是用户自定义的数据类型,用于描述对象的特征和行为。类是抽象的,不能直接创建对象,而是通过类创建对象。对象是类的实例,每个对象都有其自己的数据成员和成员函数。 ### ...
方法定义是类中实现特定功能的代码块,包括类的方法和构造方法等。 2. 执行 `Person p = new Person();` 语句时,系统会在堆内存中为 `Person` 对象分配空间,存储实例变量,同时在栈内存中为引用变量 `p` 分配空间...
实验1 类的定义、对象数组的使用 1.定义一个学生类(Student), 属性有 1)非静态属性String studentNumber 2)非静态属性String studentName 3)非静态属性int markForMaths 4)非静态属性int markForEnglish 5)非...
6. **访问修饰符**:Java有public、private、protected和默认四种访问修饰符,它们控制类、方法和变量的可见性。 7. **静态成员和非静态成员**:静态成员属于类,而非静态成员属于类的每个实例。静态成员在内存中...
Java是一种广泛使用的面向对象的编程语言,其核心概念包括类和对象。类是Java中的蓝图,定义了数据(属性)和行为(方法)的模板,而对象是类的实例,代表程序中的具体实体。让我们深入了解一下Java类和对象的基础...
练习题分为选择题和填空题两部分,涵盖了类的定义、对象的声明、成员函数、访问权限、继承等关键概念。 选择题 1. 下列有关类的说法不正确的是( )。答案:C. 一个类只能有一个对象 知识点:类的定义、对象的...
【C语言程序设计课件第6章类与对象.ppt】深入解析 在C++编程中,类与对象是面向对象编程(OOP)的核心概念。面向对象编程是一种编程范式,它基于“对象”的概念,这些对象可以包含数据(属性)和行为(方法)。本...
你可以通过类对象访问其属性和方法,或者通过调用类的`__init__`方法创建实例对象。例如: ```python class People: name = 'jack' p = People() # 实例化 print(p.name) # 访问属性 ``` 3. **属性** ...
对象是类的实例,它们拥有类定义的所有属性和方法。`test2`可能包含了创建对象并调用其成员函数的代码,以展示如何通过对象来操作数据。 3. 构造函数与析构函数:C++中的构造函数用于初始化新创建的对象,而析构...
题目中没有直接提到静态变量或方法,但在实际编程中,静态变量是所有类实例共享的,而静态方法不依赖于任何特定的对象实例就可以调用。 8. **包(package)**:包是Java中组织类的一种方式,可以避免命名冲突并提供...
类方法可以用`@classmethod`装饰器标识,可以被类或其对象调用,而静态方法用`@staticmethod`装饰器,不与特定实例绑定,可以直接通过类名或对象名调用。 6. **面向对象的特性**: 面向对象编程的三大特性是封装、...
在本段内容中,我们将会讨论Java编程语言的基础知识点,包括类和对象的使用、基本数据类型、数组、方法的定义和调用等。 首先,我们来看看关于Java的类、对象以及数组的概念。Java是一种面向对象的编程语言,它的...
9. 类对象:一个Java类可以创建多个对象,每个对象有自己的存储空间,可以独立初始化。选项B和C是错误的,选项D(以上都无)表示没有正确答案。 10. 包引用:要使用特定包中的类,需要在程序顶部使用`import`关键字...
4. **类与对象**:在Labview中,类是对象的蓝图,定义了对象的属性和方法。对象是类的实例,具有类所定义的特征和行为。创建类后,通过实例化过程可以生成对象,每个对象都有自己的属性值。 5. **事件驱动编程**:...
了解如何定义类,包括属性(数据成员)和方法(成员函数),是掌握面向对象编程的关键。 2. **封装**:封装是面向对象的核心特性之一,它允许我们将数据和操作这些数据的方法绑定在一起,隐藏内部实现细节,对外...
* Java 语言基础:类的定义、构造方法、成员变量、成员方法 2. 银行账户功能模拟: * 属性:账号、储户姓名、地址、存款余额、最小余额 * 方法:存款、取款、查询 知识点: * 面向对象编程基本概念:类、对象、...
缺省构造函数是没有参数的构造函数,而拷贝构造函数是一种特殊的构造函数,接收一个本类对象的引用,用于创建新对象并复制已有对象的状态。 4. 析构函数:对象生命周期结束时自动调用,负责清理对象资源。 5. 静态...
类是创建对象的蓝图,定义了对象的状态(属性)和行为(方法)。在Java中,使用`class`关键字来声明一个类。对象则是类的实例,具有类定义的属性和方法。例如,你可以定义一个名为`Person`的类,包含`name`、`age`...
面向对象编程是一种编程范式,它通过类和对象来组织代码,强调数据和操作数据的方法的封装。在PHP5及以上版本中,对OOP的支持大大增强,使得开发者可以构建更加结构化和可维护的程序。 1. **类(Class)**:类是...