天天看点

JavaScript中原型链继承的问题

若单独使用原型链来实现继承,会存在引用类型在所有子类中共享的问题。

function SuperType(){
			this.name=['hello'];// 数组为一种引用类型
		}

		function SubType(){

		}

		SubType.prototype=new SuperType();
		var sub=new SubType();
		var sub1=new SubType();
		console.log(sub.name);// hello

		sub.name.push(' world');
		

		console.log(sub1.name);// hello world

		console.log(sub.name);// hello world
           

通过程序运行的结果来看,虽然只是在

sub

这一个实例中修改了

name

属性的值,但是 在另一个实例

sub1

中,

name

的属性值也发生了改变。

具体原因是因为name是引用类型,所有的

name

都指向同一块内存空间,所以一次改变就会引起全局改变,相当于其他语言的静态变量。

但是如果不是引用类型就不存在这种问题,每创建一个实例,都会为每个实例的

name

属性重新分配一个内存空间,相互之间不干扰。

function SuperType1(){
			this.name='hello';
		}

		function SubType1(){

		}

		SubType1.prototype=new SuperType1();
		var sub=new SubType1();
		var sub1=new SubType1();
		console.log(sub.name);// hello

		sub.name='hello world';
		

		console.log(sub1.name);// hello 

		console.log(sub.name);//hello world
           

另外,就算给

name

刚开始赋值为String类型,由于后期的字符串操作函数返回的都只是一个字符串而不是一个String的引用类型,所以导致

name

本身类型的改变(不再是引用类型),不会引起子类共享的问题。

function SuperType1(){
			var hel=new String('hello');
			this.name=hel;
		}

		function SubType1(){

		}

		SubType1.prototype=new SuperType1();
		var sub=new SubType1();
		var sub1=new SubType1();
		console.log(sub.name);// 

		sub.name=sub.name.toUpperCase();
		
		console.log(sub.name instanceof String);//false,不再是String类型

		console.log(sub1.name);//

		console.log(sub.name);//
           

程序运行结果如下

JavaScript中原型链继承的问题

参考资料:JavaScript高级程序设计(第三版)第6章

继续阅读