首页 > 代码库 > 原型模式——javascript的面向对象

原型模式——javascript的面向对象

    javascript没有类这个概念,但是面向对象的标志确是拥有类概念。对于类抽象重复的解决方案在javascript中没有办法通过继承来实现。但是javascript的每个函数都自动添加一个名称为prototype属性,这是一个对象,我们可以将所有的实例通过一个原型链引用到prototype上,从而模拟类的方式。

    原型模式实现一个接口,该接口用于创建当前对象的克隆,从而实现创建重复的对象。

    在javascript中的继承关系就可以通过原型克隆一份父类给子类便可。我们可以定义一个所有类型的父类Class来实现继承的函数,所有其他类通过继承父类。Class类的代码如下:


function Class(){}
Class.extend = function(prop){
	var _super = this.prototype;
	initializing = true;
	var prototype = new this();
	initializing = false;
	fnTest = /xyz/.test(function(){xyz;})?/\b_super\b/:/.*/;
	for(var name in prop){
		prototype[name] = typeof prop[name] == "function"&&typeof _super[name] == "function"&&fnTest.test(prop[name])?
		(function(name,fn){
			return function(){
				var tmp = this._super;
				this._super = _super[name];
				var ret = fn.apply(this,arguments);
				this._super = tmp;
				return ret;
			};
		})(name,prop[name]):
		prop[name];
	}
	function Class(){
		if(!initializing){
			if(!this.ctor)
				return;
			else
				this.ctor.apply(this,arguments);
		}
	}
	Class.prototype = prototype;
	Class.prototype.constructor = Class;
	Class.extend = arguments.callee;
	return Class;
};

     第23行代码重写了Class(),定义了ctor作为构造函数,第8行到第19行根据prop的变量类型将父类的属性和方法克隆给子类,实现继承和重载的功能,同时定义_super来实现调用父类方法的功能。

    下面是一个Class函数的应用,通过模拟游戏打怪的方式,类图:

技术分享

效果图:

技术分享

实现代码:

<script>
			var mouse = null,shark = null;
			var player = new Player(20,500);
			function metMouse(){
				mouse = new Mouse(10,10,5,100);
				console.log("在("+mouse.x + "," + mouse.y +")生成老鼠");
				document.getElementById("mouseid").style.display = "block";
				setInterval(function(){
					if(!mouse.isDie())
						player.hurt(mouse.att);
					else
						console.log("老鼠已经死了");
				},2000);
			}
			function metShark(){
				shark = new Shark(10,15,10,120);
				console.log("在("+shark.x + "," + shark.y +")生成鲨鱼");
				document.getElementById("sharkid").style.display = "block";
				setInterval(function(){
					if(!shark.isDie())
						player.hurt(shark.att);
					else
						console.log("鲨鱼已经死了");
				},2000);
			}
			function attackMouse(){
				mouse.hurt(player);
			}
			function attackShark(){
				shark.hurt(player);
			}
		</script>
	</head>
	<body>
		<button onclick = "metMouse()">遇见老鼠</button>
		<button onclick = "metShark()">遇见鲨鱼</button>
		<button onclick = "attackMouse()" style = "display:none;" id = "mouseid">攻击老鼠</button>
		<button onclick = "attackShark()" style = "display:none;" id = "sharkid">攻击鲨鱼</button>
	</body>

怪兽的代码:

var Monster = Class.extend({
	ctor:function(_x,_y,_att,_blood){
		this.x = _x,
		this.y = _y,
		this.att = _att;
		this.blood = _blood;
	},
	attack:function(player){
		player.hurt(this.att);
	},
	hurt:function(player){
		this.blood -= player.att;
		console.log("怪兽受到" + player.att + "攻击");
		console.log("怪兽当前血量:" + this.blood);
	},
	isDie:function(){
		return this.blood <= 0;
	}
});

玩家的代码:

var Player = Class.extend({
	ctor:function(_att,_blood){
		this.att = _att;
		this.blood = _blood;
	},
	hurt:function(_att){
		this.blood -= _att;
		console.log("玩家受到" + _att + "伤害");
		console.log("玩家当前血量为:" + this.blood);
	}
});

Shark类

var Shark = Monster.extend({
	attack:function(player){
		_super.attack(player);
		player.hurt(20);
		console.log("鲨鱼怪物给玩家造成额外的20点伤害");
	},
	hurt:function(player){
		console.log("鲨鱼怪皮厚,减少10点伤害");
		this.blood = this.blood - player.att + 10;
		console.log("鲨鱼受到" + (player.att - 10) + "点伤害");
		console.log("鲨鱼当前血量:" + this.blood);
	}
});


本文出自 “走一停二回头看三” 博客,请务必保留此出处http://janwool.blog.51cto.com/5694960/1881559

原型模式——javascript的面向对象