存档

作者存档

面向对象的 JavaScript 代码

2009年2月19日

本篇文章节选自:http://lijing.9966.org/jayli/yshare/p1/code.html   原文作者:jay

JavaScript是基于原型的编程语言,但也有完整的面向对象特性。同时其书写风格灵活多变,包括函数式编程、原型风格编程和面向对象风格编程。

从代码风格来看,封装类型分为类式的封装和原型式的封装。
这里我们使用“人”(Person)的例子,构造一个“人”的类,人有名字,人可以“吃饭”、“睡觉”、“走路”等等

1,类式封装

最直接最简单的封装方法是将人名,吃饭,睡觉等属性和动作封装在Person类中.
<script>
/*定义一个"人"的类,人有名字,人也可以吃饭,睡觉,走路
*我们用类式封装来实现
*但是所有成员都是公有的,任何人都能够在外部访问name,eat,sleep,walk
*/

//Person类
var Person = function(name){

//公有成员
this.name = name;

//公有方法
this.eat = function(){
alert(this.name+’ is eating sth’);
};
this.sleep = function(){
alert(this.name+’ is sleeping’);
};
this.walk = function(){
alert(this.name+’ is walking’);
};
};

var jay = new Person(’jay’);
</script>

可以通过firebug看到“jay”的成员和属性。

但这样的代码有一个问题:不安全,因为类成员在任意命名空间都可以访问到。我们需要做改进:增加私有成员和私有方法。

通常约定私有成员变量用"_"开始,比如_value表示这是一个私有变量。

<script>
/*定义一个"人"的类,人有名字,人也可以吃饭,睡觉,走路
 *针对类式封装,增加私有成员,私有方法
 *这里增加的_setNickName和_getNickName只是说明私有方法的用法,实际中可以完全省略
 */

var Person = function(name){

	//私有成员
	var _nickname = 'nothing';
	//公有成员
	this.name = name;

	//私有方法
	var _setNickName = function(nickname){
		_nickname = nickname;
	};
	var _getNickName = function(){
		return _nickname;
	};

	//公共方法
	this.eat = function(){
		alert(this.name+' is eating sth');
	};
	this.sleep = function(){
		alert(this.name+' is sleeping');
	};
	this.walk = function(){
		alert(this.name+' is walking');
	};
	this.setNickName = function(nickname){//接口
		_setNickName(nickname);
	};
	this.getNickName = function(){//接口
		return _getNickName();
	};
};

var jay = new Person('jay');
</script>

这样就可以通过Person提供的接口对私有成员进行访问。

类式封装的优点:思路很清晰,适合那些有c++或java编程经验的人。

类式封装的缺点:内存利用不科学,因为每个实例都拥有各自的成员方法,而各自的方法是一样的,我们希望每个实例都共享一个方法。而成员受运行时影响比较大,则希望每个实例的成员可以占据单独的内存。原型式封装弥补了这个缺陷,原型使得每个实例都共享一份原型方法。

2,原型式封装

<script>
/*定义一个"人"的类,人有名字,人也可以吃饭,睡觉,走路
 *
 *原型式封装,每个实例都共享一份原型,(jjb.eat == jay.eat) = true
 */

var Person = function(name){
	var _nickname = 'nothing';
	this.name = name;

	this.setNickName = function(nickname){//接口方法
		_nickname = nickname;
	};
	this.getNickName = function(){//接口方法
		return _nickname;
	};
};

//原型
Person.prototype = {
	eat:function(){
		alert(this.name+' is eating sth');
	},
	sleep:function(){
		alert(this.name+' is sleeping');
	},
	walk:function(){
		alert(this.name+' is walking');
	}
};

var jay = new Person('jay');
var jjb = new Person('jjb');
</script>

这样jjb.eat == jay.eat,说明实例的eat是到Person的prototype.eat的引用.

原型式封装的优点:内存利用合理,缺点:初学难理解。

这种编码风格要注意的:1,方法在原型中定义,成员在类中定义,2,私有变量和接口函数写在类定义中,因为接口通常使用到私有变量。

3,静态变量

在C++,JAVA和C#中有类静态变量,如何在js中实现?

<script>
/*
 * 给“人”中定义一个静态变量“人数”,这样每个“人”的实例都共享一个“人”的名为“人数”的成员
 */

var Person = (function(){

	//私有静态成员
	var numOfPersons = 0;

	return function(name){
		//公有成员
		this.name = name;
		//私有成员
		var _nickname = 'nothing';

		//接口方法
		this.setNickName = function(nickname){
			_nickname = nickname;
		};
		this.getNickName = function(){
			return _nickname;
		};
		this.setNum = function(num){
			numOfPersons = num;
		};
		this.getNum = function(){
			return numOfPersons;
		};
	};

})();

//原型
Person.prototype = {
	eat:function(){
		alert(this.name+' is eating sth');
	},
	sleep:function(){
		alert(this.name+' is sleeping');
	},
	walk:function(){
		alert(this.name+' is walking');
	}
};

var jay = new Person('jay');
var jjb = new Person('jjb');

</script>

在这个例子中,jjb.getNum() = 0;jjb.setNum(3);jay.getNum() = 3;

kingabird JavaScript

对于构造函数的理解

2009年2月16日

在JavaScript的帮助手册里查到的解释是这样的:

一种 JScript 函数,具有两个特殊的性质:

  • new 运算符来调用此函数。
  • 通过 this 关键字将新创建对象的地址传递到此函数。

请使用构造函数来初始化新的对象。

在JS权威指南里看的解释是:

New创建了一个新的没有任何属性的对象,然后调用该函数,把新的对象作为this关键字的值传递。设计来和new运算符一起使用的函数叫做构造函数 ( constructor function 或 constructor )。

下面来创建一个构造函数然后使用 new 运算符调用它两次来创建两个新的对象:

function Rectangle ( w , y ){

this.widht = w;

this.height = h;

}

var rect1 = new Rectangle ( 2 , 4 );  // rect1 = { width = 2, heithg = 4 };

var rect2 = new Rectangle ( 8.5 , 11 );  // rect1 = { width = 8.4, heithg = 11 };

this 语句,来源 JavaScript 的帮助手册

this 语句@import url(../html-vss/msdnie4a.css);指当前对象。

this.property

必选的 property 参数指的是对象的属性。

说明

this 关键字通常在对象的 构造函数中使用,用来引用对象。

示例

在下面示例中,this 指的是新创建的 Car 对象,并给三个属性赋值。

function Car(color, make, model){
  this.color = color;
  this.make = make;
  this.model = model;
}

kingabird JavaScript ,

About

2009年2月10日

关于ID:kingaird 第一次用这个ID的时候还是个狗屁不懂的孩子,应该可以追述到上个世纪了。当时因为某些人想到了《国王与小鸟》的动画片,也由于糟糕的英文水平(现在依然糟糕),就想当然的用了 kingabird 。写这段的时候去查了下,到底这个动画的英文名字是什么,原来还真的不是 King and Bird 这句是不是很 囧~~`

关于本人:被称为八零后中的一员,默默无闻。设计出身,现从事于自己还算喜欢的职业;徘徊于设计与技术之间;混迹于互联网,目前有向艺术圈靠拢的趋势。

关于博客:由于最近看到的信息太多,太好,都割舍不过,所以有了建此博客的想法,记录下所看到,看想到的。关注互联网,关注技术,关注艺术,关注…

kingabird About