javascript实现继承的原理主要是依靠原型链机制。
第一种方法:
//首先创建一个父类对象
function SuperType(){ this.property = true; }
//在该对象的原型上添加了一个getSuperValue方法 SuperType.prototype.getSuperValue = function(){ return this.property; }; //创建了一个子类 function SubType(){ this.subproperty = false; } //继承了SuperType SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function(){ return this.subproperty; }; //创建一个子类的实例,但是这个实例已经可以访问父类的方法 var instance = new SubType(); //这里调用了父类的方法 alert(instance.getSuperValue()); // true;
优缺点:
1、当父类的一个属性时引用类型时,子类创建的所有实例会公用一个属性,一旦子类的某一个实例修改了该引用类型的属性,这个子类创建的所有实例的该属性值都会发生改变。
2、在创建子类的实例时,不能向父类的构造函数中传递参数。
所以这种方法很少会使用到。
第二种方法:
function SuperType(){ this.colors = ["red","blue"]; } //子类的构造函数调用了父类的构造函数 function SubType(){ SuperType.call(this); } //实现了继承 var instance1 = new SubType(); //修改了子类的一个实例的引用类型属性colors;但是另一个实例的该属性并没有改变,解决了上面第一种方式的问题。 instance1.colors.push("black"); alert(instance.colors); //red,blue,black var instance1 = new SubType(); alert(instance.colors); //red,blue //还可以向父类构造函数传递参数,但是不是完美了呢 function SuperType(name){ this.name = name; } function SubType(){ SuperType.call(this."zixu"); this.age = 22; } var instance = new SubType(); alert(instance.name); //zixu alert(instance.age); //22
优缺点:这种方式解决了第一种方式产生的两个问题,但是这种所有的方法都是定义在了构造函数中,这意味着每一个实例都会产生一个自己的方法,尽管他们只需要公用一个就行。这当然是有缺陷的。所以下面还有更好的方法。
第三种方法:
//这是父类,有一个引用类型成员colors function SuperType(name){ this.name = name; this.colors = ["red","blue"]; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name,age){ SuperType.call(this,name); this.age = age; } //实现了继承 SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType; //在子类的原型上添加方法,而不是构造函数中,解决了函数不能复用的问题 SubType.prototype.sayAge = function(){ alert(this.age); } //分别创建了两个实例,观察两个实例的结果,解决上述两个方法产生的问题。 var instance1 = new SubType("zixu",22); instance1.colors.push("black"); alert(instance1.colors); //red, blue, black instance1.sayName(); //zixu instance1.sayAge();22 var instance2 = new SubType("zixu2",23); alert(instance1.colors); //red, blue instance1.sayName(); //zixu2 instance1.sayAge();23
所以,这就是一般实现继承最常用的方法了。
但是,你以为这就结束了,那些大神们是不会满足的,再来看一下他们是怎么捣鼓的。
第四种方法:
function object(o){ function F(){} F.prototype = o; return new F(); } var person = { name:"zixu", friends:["a","b"] }; //此时subperson就具有了person对象的属性和方法 var subperson = object(person);
//当然,通过这种方法创建的子类,每一个子类实例对于引用类型的成员还是无计可施,改变了一个,其余的就都改变了。
ES5给这种方法规范了下,变成了一个Object.create()方法
第五种方法:
function createAnother(original){ var clone = object(original); clone.sayHi = function(){ alert("Hi"); }; return clone; }
这种方法其实和上一种原理一样。
好了,继承基本上就是这些了,主要掌握好第三种方法就好了,通过其它方法加以理解,就能很好的明白javascript中继承机制的原理。