JavaScript中创建自定义对象的方法

本文内容参考JavaScript高级程序设计(第3版)第6章:面向对象的程序设计

ECMA-262中把对象定义为:“无序属性的集合,其属性可以包含基本值、对象或者函数。”我所理解的就是对象就是一个结构体,结构体中有一些它的基本属性以及对结构体处理的方法,把它们封装起来称为一个整体。JS中所有的对象都是基于一个引用类型创建,这个引用类型可以是原生类型,如Array,Date等,也可以是开发人员自定义的类型。

下面主要总结下JS中创建对象的几种模式,分析他们各自的优缺点。

1. 工厂模式

/******************工厂模式*************************/
/***使用同一个接口创建多个对象,避免代码重复,用一个函数来封装以特定接口创建对象的细节***/
/*****缺点:不能识别对象的类型(都是Object类型)******/
function createPerson(name, age, job)
{
	var object = new Object();
	object.name = name;
	object.age = age;
	object.job = job;
	object.sayName = function()
	{
		alert(this.name);
	}
	return object;
}

var person1 = createPerson("Jack", "22", "singer");
var person2 = createPerson("Taylor", "30", "actor");

工厂模式创建一个接口函数,在接口函数中新建一个对象,并为其定义属性和方法,每创建一个新的对象就调用这个接口函数。这种模式避免了创建同一类型对象的代码重复,但是这样创建的对象都是Object类型,无法体现出自定义类型的独特性。

2.构造函数模式

/******************构造函数模式***********************/
/****与工厂模式的区别:********************************/
/****1.没有显式地创建对象******************************/
/****2.直接将属性和方法赋给了this对象*******************/
/****3.没有return语句*******************************/
/****缺点:每实例化一个对象就新创建了一个不同的Function实例(对象中的方法函数)*/
function Person(name, age, job)
{
	this.name = name;
	this.age = age;
	this.job = job;
	this.sayName = function()  //每实例化一个对象就新创建一个Function实例
	{
		alert(this.name);
	}
}

var person1 = new Person("Jack", "22", "singer");
var person2 = new Person("Taylor", "30", "actor");  //Person为实例的特定类型

构造函数模式也创建了一个函数接口,不过与工厂模式不同的是这不是普通的函数,而是构造函数。构造函数与普通函数在定义上没有区别,只是构造函数在调用时要在函数名前加一个“new”。用构造函数模式创建的对象有自己的类型名(如本例中的Person),但是它依然有缺陷:对象中的方法函数没有必要实例化,它最好可以只定义一次让所有同类型的对象共用,在这种模式下,每新建一个对象就新建了一次对象中的方法函数,代码不够简洁。

3.原型模式

/**********************原型模式************************/
/****原型对象可以让所有对象实例共享它所包含的属性和方法********/
/****缺点:所有实例在默认情况下都将取得相同的属性值,没有属于自己的属性值*****/
function Person()
{}
Person.prototype.name = "Louis";
Person.prototype.age = "23";
Person.prototype.job = "singer";
Person.prototype.friend = ["Harry", "Liam"];
Person.prototype.sayName = function()
{
	alert(this.name);
};

var person1 = new Person();
var person2 = new Person();

person1.age = "28";       //屏蔽原型对象中age属性,但不修改原型中的属性
alert(person1.age);       // 28 来自实例
alert(person2.age);       // 23 来自原型

person1.friend.push("zyan");    //修改了person1.friend引用的数组--原型对象中的属性
alert(person1.friend);    // "Harry,Liam,Zayn"
alert(person2.friend);    // "Harry,Liam,Zayn"
alert(person1.friend == person2.friend)  // true

无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个propotype属性,这个属性指向这个函数的原型对象。同时,这个原型对象也会获得一个constructor属性,这个属性包含一个指向这个新函数的指针。而调用构造函数创建一个新实例后,该实例的内部又将包含一个内部指针[[propotype]],这个指针指向构造函数的原型对象。原型对象中的属性和方法可以被所有对象的实例共享。

获取某个实例的属性时,先搜索实例本身,也就是它的构造函数里有没有这个属性,如果有就直接返回这个值,如果没有则继续搜索构造函数的原型对象中的属性。所以在某一个对象中添加一个原型中已有的属性或方法时,会屏蔽原型中的属性,但原型中的属性不会被修改。

共享是原型模式的优点,它避免了大量重复的代码,但同时也带来了弊端。如示例中,在原型对象中定义了一个引用类型Array的属性--friend,person1实例向数组中添加了一项,但由于friend属性也同时在person2中,所以person2中的friend也跟着改变了,这不利于各个实例的独特性。

4.组合使用构造函数模式和原型模式

/****************构造函数模式和原型模式混合********************/
/****构造函数模式用于定义实力属性,原型模式用于定义方法和共享属性****/
/****每个实例都有自己的一份实例属性副本,方法共享,节省内存*********/
function Person(name, age, job)
{
	this.name = name;
	this.age = age;
	this.job = job;
	this.friend = ["Harry", "Liam"];
}
Person.prototype.sayName = function()
{
	alert(this.name);
}

var person3 = new Person("Lious", 22, "singer");
var person4 = new Person("Zyan", 21, "dancer");

person3.friend.push("Nail");
alert(person3.friend);       //"Harry,Liam,Nail"
alert(person4.friend);       //"Harry,Liam"

这种方法综合了构造函数模式和原型模式的优点,构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性。每个实例都会有自己的一份实例属性的副本,同时又共享着对方法的引用,最大限度地节省了内存。在这种模式下person1改变它的friend属性并不会影响到person2,因为friend属性写在了构造函数中,每创建一个新的实例都会生成这个属性的新的副本,所以person1和person2中的friend数组是不同的数组。

构造函数模式个原型模式的混合模式是实际开发中最常用的创建对象的模式。

时间: 2024-10-03 16:15:00

JavaScript中创建自定义对象的方法的相关文章

Javascript 中创建自定义对象的方法(设计模式)

Javascript 中创建对象,可以有很多种方法. Object构造函数/对象字面量: 抛开设计模式不谈,使用最基本的方法,就是先调用Object构造函数创建一个对象,然后给对象添加属性. 1 var student = new Object(); 2 student.name = "xiao ming"; 3 student.age = 20; 4 student.getName = function () { 5 alert(this.name); 6 } 熟悉javascrip

Floodlight 中创建消息对象的方法

在 floodlight 中创建各种openflow message 和 action 等采用的是简单工厂方式,BasicFactory类(实现OFMessageFactory接口,)会根据消息的类型创建不同的对象,达到更好的封装效果:此外这里调用的是枚举类型的方法.下面是具体代码: ----------工厂接口,还有OFActionFactory,约束需要具体工厂完成的事情 public interface OFMessageFactory { // 根据消息类型得到具体的实例 public 

在JavaScript中重写jQuery对象的方法

jQuery是一个很好的类库,它给我们解决了很多的客户端编程,任何东西都不是万能的,当它不能满足我们的需求时我们需要对它进行重写,同时也不要影响其原有的功能或者修改其原有的功能:我现在的web应用程序大多数时候的数据交互都是通过Ajax来完成的,这样就可以将一些隐藏字段的数据保存在HTML标签的属性中,使HTML标签的代码量减少,如:ID,Timestamp等等,这些不需要用户输入但又不得不提交的字段,通过表单提交的做法是 <input name="ID" value="

JavaScript中创建字典对象(dictionary)实例

这篇文章主要介绍了JavaScript中创建字典对象(dictionary)实例,本文直接给出了实现的源码,并给出了使用示例,需要的朋友可以参考下 对于JavaScript来说,其自身的Array对象仅仅是个数组,无法提供通过关键字来获取保存的数据,jQuery源码中提供了一种非常好的方式来解决这个问题,先看一下源码: 复制代码代码如下: function createCache() { var keys = []; function cache(key, value) {  // Use (k

在Javascript 中创建JSON对象--例程分析

作者:iamlaosong 要想用程序从网页上抓数据,需要熟悉HTML和JavaScript语言,这里有一个在Javascript 中创建JSON对象的例程,学习并掌握其内容,在此对此例程做个注释,记录我掌握的知识,以备将来验证是否正确. 程序很简单,分三部分: 1.<h2>部分:用大字符显示标题: 2.<p>部分:显示一段信息的结构,但无内容,内容在后面添加: 3.<scrip>部分:Javascript程序,先定义了一个JSON结构的变量JSONObject,然后,

javascript中的Array对象的方法

检测数组:只考虑一个全局作用域的情况下可以使用value instanceof Array 来判断一个对象是否是数组:如果要考虑多个全局的作用域,则使用Object.prototype.toString.call(value) == "[object Array]" 转换方法:toString toLocaleString  join 栈方法:(后进先出)在数组末尾插入一项,在数组末尾弹出一项.push:在数组末尾插入一项或多项,并返回现在的数组长度:pop:弹出数组最后一项,并返回.

JavaScript中的string对象及方法

string对象 string对象的两种创建 var a="hello"; var b=new String("hello"); //下面是方法 //charAt()根据下标 找字符串中的字符  alert(a.charAt(3));//根据下标返回字符串某个字符  alert(a.charAt(10));//空的,找不到这个下标 //charCodeAt()返回指定位置的字符   var a="Hello world!Hello world!"

Exchange 2013 PowerShell创建自定义对象

PowerShell是一个基于对象的Shell,在写一行程序,脚本和函数时,給了我们很大的灵活性.当生成详细的报告时,我们需要从代码中自定义我们的数据输出,或者可以通过管道输送到其它的命令.我们还需要能够控制和定制代码的输出,这样我们可以合并来自多个源的数据到一个单独的对象.在这一节中,我们将学习下基本的构建定制的对象 首先我们要做的时创建一个邮箱对象的集合,将用来作为一组新的自定义对象的数据源: $mailboxes = Get-Mailbox 可以添加自定义的属性用于后续整个管道的对象属性,

在JavaScript中生成自定义的对象

使用对象便于组织信息.下面我们介绍如何在JavaScript中生成自定义的对象. ---------------------- JavaScript 对象 在前面几章中我们学到JavaScript中有些内置的对象,比如String, Date, Array等等.除此之外,你还可以定义自己的对象. 对象是一种特殊的数据,含有属性和函数. 下面让我们用一个例子来说明:比如一个人是一个对象.属性是与对象有联系的值,比如人的属性包括姓名,身高,体重,年龄,肤色,眼睛的颜色等等.所有人都有这些属性,但是每