完美原型prototype类的继承方法

原创 2014年06月03日 13:57:05
JavaScript中的面向对象的设计大家用的非常多了,我在进行类的继承应用时发现了一些问题。
看下面代码:
function ClassA()
{
  this.abc = 7678;
  this.def = [1,88,66];
  alert("执行了 ClassA 的构造函数");
}


ClassA.prototype.getABC = function ()
{
  alert(this.abc);
}


function ClassB()
{
  this.xyz = 5252;
}


ClassB.prototype = new ClassA();


ClassB.prototype.getDEF = function ()
{
  alert(this.def);
}


var x = new ClassB();
x.getABC();
var y = new ClassB();
y.getDEF();

这是一个比较常见继承方法,它是通过把子类的原型对象(prototype)设置成父类的一个实例来进行继承的。
但是只简单的这样设置继承有四个缺点:


  缺点一:执行上面代码会发现父类的构造函数不是像JAVA中那样在给子类进行实例化时执行的,而是在设置继承的时候执行的,并且只执行一次。这往往不是我们希望的,特别是父类的构造函数中有一些特殊操作的情况下。


  缺点二:由于父类的构造函数不是在子类进行实例化时执行,在父类的构造函数中设置的成员变量到了子类中就成了所有实例对象公有的公共变量。由于JavaScript中继承只发生在“获取”属性的值时,对于属性的值是String,Number和Boolean这些数据本身不能被修改的类型时没有什么影响。但是Array和Object类型就会有问题。如在上面代码之后加入:
x.def[1] = 100;
alert(x.def[1]);
alert(y.def[1]);
这里我们只改了x.def的值,而y.def也一起改变了。


  缺点三:如果父类的构造函数需要参数,我们就没有办法了。


  缺点四:子类原本的原型对象被替换了,子类本身的constructor属性就没有了。在类的实例取它的constructor属性时,取得的是从父类中继承的constructor属性,从而constructor的值是父类而不是子类。


为了解决这四个缺点,我试了几种方法,下面是我觉得最好的一种。方法如下:

function Class(nd)
{
	var fu = nd.constructor;
	if(typeof(nd.extend)==="function")		//Class的继承
	{
		var Bs = new Function();
		Bs.prototype = nd.extend.prototype;
		fu.prototype = new Bs();
		fu.prototype.Super = nd.extend;
		fu.prototype.constructor = fu;		//constructor是非壮举属性,只能这样设置
		delete nd.extend;
	}
	for(var name in nd)						//为Class添置方法
	{
		var t = name.indexOf("static_")==0;
		var obj = t?fu:fu.prototype;
		obj[t?name.replace("static_",""):name] = nd[name];
	}
	return fu;
}
//========================


var ClassA = Class({constructor: function()
	{
		this.abc = 123;
		this.def = [1,88,66];
	}
	,
	getAbc: function ()
	{
		alert(this.abc);
	}
	,
	abcAdd: function (s)
	{
		return (s+this.abc);
	}
	,
	static_aaa: 123456//这是一个静态变量
	,
	static_ppp: function ()//这是一个静态方法
	{
		alert("static Method "+this.aaa);
	}
});


var ClassB = Class({extend: ClassA, constructor: function()
	{
		this.Super();
		this.xyz = 5252;
	}
	,
	getDEF: function ()
	{
		alert(this.def);
	}
	,
	abcAdd: function ()//重载abcAdd方法
	{
		return (1+this.abc);
	}
});


ClassA.ppp();


var x = new ClassB();
x.getAbc();
var y = new ClassB();
y.getDEF();
x.def[1] = 100;
alert(x.def[1]);
alert(y.def[1]);


版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jslang/article/details/28257103

裸板调试方法合集

-
  • 1970年01月01日 08:00

关于prototype以及继承方面的理解

学习笔记(致 渐悟) 写在前面的话 今天看的时候,看到有关继承和原型链prototype时遇到些疑问,特回来研究下,同时也感谢JS群网友"渐悟"的指导,非常感谢! 先给Demo,再说话 ...
  • vchenpeng
  • vchenpeng
  • 2016-09-04 23:40:52
  • 212

js中的prototype和基于prototype的继承总结

与其他编译语言的继承相比,javascript也有一套继承实现方式,即使用prototype原型及其链的方式。1、我们先用一个简单的例子先理解原型链, (http://img.blog.csdn.n...
  • houyaowei
  • houyaowei
  • 2016-05-18 15:00:47
  • 392

JS中的prototype属性实现继承

在JS中没有类的概念,继承是通过对象和对象之间实现的。其中主要是利用prototype属性来实现的。 函数中的prototype属性,又叫原型对象。构造函数可以通过prototype属性来添加函数。...
  • IstarI
  • IstarI
  • 2016-07-07 15:15:15
  • 1125

关于javascript-prototype继承

1.最基本的用法 把ClassA的一个实例赋值给ClassB, ClassB就继承了ClassA的所有属性。  代码入下:   function ClassA()   {     ...
  • u011313703
  • u011313703
  • 2017-08-15 17:57:08
  • 77

js prototype 原型继承问题

1,js 原型继承问题总结 1. js 原型继承 是引用类型 而不是复制类型 ,所以 对原型的修改会引起所以实例的变化 2. 子类对象中的写操作只访问子类对象中的成员;他们之间不会互相影响,所...
  • z_l_ming
  • z_l_ming
  • 2016-06-28 17:21:44
  • 503

js中继承的几种用法总结(apply,call,prototype)

一,js中对象继承 js中有三种继承方式 1.js原型(prototype)实现继承 script type="text/javascript"> function Pers...
  • u014345282
  • u014345282
  • 2016-05-27 20:17:03
  • 1710

js 采用prototype实现继承

//采用prototype的方式实现js继承         //调用A的构造函数时,没有给他传递参数。这是prototype中标准做法,要确保构造函数没有任何参数         functio...
  • y_f123
  • y_f123
  • 2014-05-20 12:02:04
  • 478

prototype继承

String.prototype.trim = function() { return "哈哈"; }; alert("$4 eee ha Yi 表 ".trim()); test aa...
  • weiyanghuadi
  • weiyanghuadi
  • 2013-05-29 20:14:42
  • 313

实现javaScript对象的"继承"的两种方法(prototype与闭包)

实现javaScript对象的"继承"的两种方法(prototype与闭包)
  • canot
  • canot
  • 2016-02-28 16:13:32
  • 1455
收藏助手
不良信息举报
您举报文章:完美原型prototype类的继承方法
举报原因:
原因补充:

(最多只允许输入30个字)