自定义JavaScript类型的一个例子

Javascript没有类的概念,ECMA-262把Javascript对象定义为“无序属性的集合,其属性可以包含基本值、对象和函数。”。我们可以把JavaScript对象看作是Hash对象,其中属性就是键,值可以是数据或函数。

自定义JavaScript对象最简单的办法就是创建一个Object的实例,然后为它添加属性方法。看下面代码:

var person = new Object();
person.name = 'Jim';
person.age = 30;
person.job = 'IT';
person.sayName = function(){
	alert(this.name);
};

 

显然,这种方式会产生大量重复代码。为解决这一问题,通常可以用工厂模式。

一、工厂模式

这种模式采用了软件工程中的工厂设计模式的思想。看下面代码:

function createPerson(name, age, job){
	var o = new Object();
	o.name = name;
	o.age = age;
	o.job = job;
	o.sayName = function(){
		alert(this.name);
	};
	return o;
}
var person1 = createPerson('Jim', 30, 'IT');
var person2 = createPerson('Tom', 27, 'Doctor');

 

工厂模式虽然解决了重复代码的问题,但与创建Object实例方式一样,没解决对象类型的问题。于是,构造函数模式出现了。

二、构造函数模式

JavaScript中有一个很重要的概念:函数是对象,函数名实际上是一个函数对象指针。创建算自定义函数,从而添加自定义的属性方法。改写前面的代码:

function Person(name, age, job){
	this.name = name;
	this.age = age;
	this.job = job;
	this.sayName = function(){
		alert(this.name);
	};
}

var person1 = new Person('Jim', 30, 'IT');
var person2 = new Person('Tom', 27, 'Doctor');
alert(person1 instanceof Person); //true

 

     创建自定义函数意味着可以将函数名作为自定义对象类型,这也是构造函数模式优越于工厂模式之处。然而这种模式也缺点。因为函数是对象,因此自定义函数是的方法也应该是对象,对象属于引用类型,因此:

alert(person1.sayName == person2.sayName); //false

我们在一个构造函数中用两个方法去完成相同的任务,显然会带来内存的额外开销。

三、原型模式

为了共享自定义对象的属性方法,引入了原型模式。看下面的代码:

function Person(){
}
Person.prototype = {
	constructor: Person,
	name : 'Jim',
	age : 30,
	job : 'IT',
	friends : ['Kite'],
	sayName : function () {
		alert(this.name);
	}
};
var person1 = new Person();
person1.sayName(); // Jim
var person2 = new Person();
person2.name = 'Tom';
person2.sayName(); // Tom
person1.friends.push('Mike');
alert(person1.friends); // Kite,Mike
alert(person2.friends); // Kite,Mike
alert(person1.friends === person2.friends); //true

原型模式是所有的属性方法都是共享的,与其它语言中的静态类 相似。虽然解决了原型模式中对象方法的重复使用问题,但如果属性是引用类型就有问题了。Person.prototype对象中有一个名为friends属性,该属性包含一个字符串数组。然后新建了两个Person实例,接着向person1.friends属性引用的数组新增了一个字符串。由于friends数组存在于Person.prototype而非person1中,所以对person1的修改也会在person2中反映出来。因此实际应用中很少单独用这种方法。

四、构造函数/原型混合模式

创建自定义JavaScript类型的最常见方式就是构造函数/原型混合模式,构造函数用于定义非共享的属性,原型模式用来定义方法和共享的属性。取两者之长,发挥各自优势。下面重写了前面的代码:

function Person(name, age, job){
	this.name = name;
	this.age = age;
	this.job = job;
	this.friends = ['Kite'];
}
Person.prototype = {
	constructor: Person,
	sayName : function () {
		alert(this.name);
	}
};
var person1 = new Person('Jim', 30, 'IT');
var person2 = new Person('Tom', 27, 'Doctor');
person1.friends.push('Mike');
alert(person1.friends); // Kite,Mike
alert(person2.friends); // Kite
alert(person1.friends === person2.friends); //false
alert(person1.sayName === person2.sayName); //true

这种混合模式目前也是ECMAScript 中使用最广、认同度最高的自定义JavaScript类型的方法。

转自:http://www.riafan.com/article/ajax/customize-type-with-javascript.html

以上是自定义JavaScript类型的一个例子的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>