原型模式——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);
	}
});
时间: 2024-10-20 20:30:05

原型模式——javascript的面向对象的相关文章

原型模式 -- JavaScript语言的灵魂

原型模式就是将原型对象指向创建对象的类,使这些类共享原型对象的方法与属性.JS是基于原型链实现对象之间的继承,是对属性或者方法的共享,而不是对属性和方法的复制. // 图片轮播类 var LoopImages = function (imgArr, container) { this.imagesArray = imgArr; this.container = container; } LoopImages.prototype = { // 创建轮播图片 createImage:function

设计模式(六):原型模式

在读这个模式,头脑里就浮想两个问题: 1. JavaScript的原型模式与普遍的原型模式有什么区别? 2. JavaScript的原型模式与prototype有什么关系? 原型模式定义 原型模式(创建型设计模式)是用一个对象做模板,克隆出新对象. 另外原型模式中的克隆分为"浅克隆"和"深克隆": 浅克隆: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象. 深克隆: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象

JavaScript 面向对象 (prototype 原型模式)

一. JavaScript 设计思想 1994年,网景公司(Netscape)发布了Navigator浏览器0.9版.这是历史上第一个比较成熟的网络浏览器,轰动一时.但是,这个版本的浏览器只能用来浏览,不具备与访问者互动的能力.比如,如果网页上有一栏"用户名"要求填写,浏览器就无法判断访问者是否真的填写了,只有让服务器端判断.如果没有填写,服务器端就返回错误,要求用户重新填写,这太浪费时间和服务器资源了. 因此,网景公司急需一种网页脚本语言,使得浏览器可以与网页互动.工程师_Brend

「JavaScript里的面向对象」— 5.原型模式

本文原文来源:<Object-Oriented JavaScript>By Stoyan Stefanov 本文翻译来源:赤石俊哉 原创翻译 版权申明: 如果您是原文的原作者并且不希望此文被公开,可以联系作者删除.本文翻译由 赤石俊哉 翻译整理,您可以用于学习目的,但是禁止转载. 第五章 原型模式(Prototype) 在这一章节中你将会学习使用"函数(function)"对象中的prototype属性.在JavaScript的学习过程中,理解prototype的工作原理是

JavaScript之面向对象学习七(动态原型模式和寄生构造函数模式创建自定义类型)

一.动态原型模式 在面向对象学习六中的随笔中,了解到组合构造函数模式和原型模式创建的自定义类型可能最完善的!但是人无完人,代码亦是如此! 有其他oo语言经验的开发人员在看到独立的构造函数和原型时,很可能会感到非常困惑.因为对象在其他oo语言中往往是封装在一块的,而构造函数确是和原型分开的,所以并没有真正意义上的封装,所以动态原型模式正是致力与解决这一问题的一个方案! 动态原型模式将所有的信息都封装在构造函数中(包括原型和实例属性),通过在构造函数中实例化原型(仅在必要的情况下)实现封装,又保持了

JavaScript之面向对象学习六原型模式创建对象的问题,组合使用构造函数模式和原型模式创建对象

一.仔细分析前面的原型模式创建对象的方法,发现原型模式创建对象,也存在一些问题,如下: 1.它省略了为构造函数传递初始化参数这个环节,结果所有实例在默认的情况下都将取得相同的属性值,这还不是最大的问题! 2.最大的问题是原型中的所有属性是被很多实例所共享的,这种共享对于函数非常合适,对于那些包含基本值的属性也说得过去,因为我们知道可以在实例上添加一个同名属性,可以隐藏原型中的对应属性.但是对于包含应用类型值的属性来说,问题就非常严重了,代码如下: function Person(){ } Per

js面向对象及原型(javaScript高级程序设计第3版)

一.创建对象 创建一个对象,然后给这个对象新建属性和方法. var box = new Object(); //创建一个Object对象 box.name = 'Lee'; //创建一个name属性并赋值 box.age = 100; //创建一个age属性并赋值 box.run = function () { //创建一个run()方法并返回值 return this.name + this.age + '运行中...'; }; alert(box.run()); //输出属性和方法的值 上面

【JavaScript】面向对象与原型

ECMAScript有两种开发模式: 1.函数式(过程化) 2.面向对象(OOP) 但是ECMAScript没有类的概念,因此与基于类的语言的对象也有所不同. 一.创建对象 var box=new Object(); box.name='lee';                          //属性 box.run=function(){                  //方法 returnthis.name+'运行中...'; } alert(box.run()); 关于工厂模式方

《JavaScript》——面向对象之原型

上一篇文章我主要介绍的是在JavaScript里对象的创建,可是,在对象的创建过程中有很多知识我们还没有学习,那就是原型,原型式什么东东哪?在这里我想用自己的理解跟大家说说,有不对的地方大家可以给我提意见. 首先说,原型就是对象,这个对象中的属性和方法可以被共享,被谁共享哪?就是被实例们共享(当我们创建一个对象后,然后再用这个对象去实例化许多实例). 我们创建的每个对象都有一个 prototype(原型)属性,这个属性是系统自动创建的,通过这个属性(prototype)就可以直接访问到该对象的原