继承方式主要有六种:
1、原型链继承 存在对象共享的问题
2、构造函数继承 借助call apply方法实现 :函数复用性问题 每次实例化,都重新执行了一次父类,父类中的方法重复定义
3、组合模式(原型链+构造函数)构造函数继承属性,原型链继承方法 :解决了对象共享,但是属性继承出现两次
4、原型方式 使用一个空间空函数
立即学习“Java免费学习笔记(深入)”;
5、寄生方式 在原型方式上增加额外了方法
6、寄生组合方式(解决了属性继承出现2次的问题)
1、原型链方式
子类在继承父类时,是将子类的prototype指向父类的一个实例对象。 在子类实例化时,所有子类的实例都会共享父类的那个实例上(假设叫p)的属性和方法,如果p上有引用型的属性,则子类的实例可以修改该引用型的属性,导致其他实例上的该属性也被修改。
//原型链方式
function A(){
this.name = 'lc';
this.stus = ['a','b','c'];
}
A.prototype.introduce = function (){
alert(this.name);
}
function B(){}
B.prototype = new A();
var s1 = new B();
var s2 = new B();
console.log(s1.stus); //['a','b','c']
s1.stus.push('d'); //改变s1上的属性,会影响s2上的该属性
console.log(s2.stus); // ['a','b','c','d']如果改成下面的,则不会影响。
//原型链方式
function A(){
this.name = 'lc';
this.stus = ['a','b','c'];
}
A.prototype.introduce = function (){
alert(this.name);
}
function B(){}
B.prototype = new A();
var s1 = new B();
var s2 = new B();
s1.stus = ['d']; //在s1上增加了属性, 就近原则,不在查找原型链上的同名属性
console.log(s1.stus); //['d']
console.log(s2.stus); // ['a','b','c']2、构造函数方式继承
共用构造函数,方法都是在内部定义,复函复用性问题无从谈起。
//构造函数方式继承
function A(name){
this.name = name;
this.type = 'parent';
this.introduce = function (){ alert(this.name);}
}
A.prototype.sayhi = function (){
alert(this.type);
}
function B(name,age){
A.call(this,name); //使用call方法 实现继承 但是父类中的方法重复定义 无复用性
this.age = age;
this.introduce = function (){ alert(this.name+this.age);}
}
var b = new B('lc',25);
b.introduce(); //lc25
b.sayhi(); //parent3、混合方式 (原型方式+构造函数方式)
使用构造函数继承属性,原型链继承方法
但是有一点不好的地方: 使用原型链继承时,实际上属性也继承了,重复了。
function A(name){
this.name = name;
this.type = 'parent';
}
A.prototype.sayhi = function (){
alert(this.type);
}
function B(name,age){
A.call(this,name);
this.age = age;
this.introduce = function (){ alert(this.name+this.age);}
}
B.prototype = new A();4、原型式继承
使用了一个中间空函数,实现继承后,返回一个对象。
function extend(parent){
function F(){}
F.prototype = parent;
return new F();
}5、寄生式继承 在原型式的基础上,再为对象添加属性 方法
function extend(parent){
function F(){}
F.prototype = parent;
return new F();
}
function createObj(p){
var clone = extend(p);
clone.name = 'hello';
clone.say = function (){}
return clone;
}6、寄生组合式继承
在继承方法的时候,不再实例化父类型的构造函数,而是使用inheritPrototype方法. 使用一个中间空函数,让这个空函数去继承父类原型,然后实例化这个空函数(继承了父类prototype中的所有方法)。将子类的原型指向这个实例化的空对象即可。
避免了实例化父类的构造函数。
/* 寄生组合式继承 */
function inheritPrototype(subType, superType) {
// var obj= extend(superType.prototype);
function F(){}
F.prototype = superType.prototype;
var obj= new F();
//obj.constructor = subType;
subType.prototype = obj; //不可将subType的prototype直接指向superType,否则的话,对子类prototype的修改会反应到父类上, 引用型变量
subType.prototype.constructor = subType;
}对象冒充: 使用构造函数的方式声明类,将一个类的方法指向另一个构造函数(因为构造函数本身就是一个方法函数),实现继承
function A(){
this.name = {name1:'hello'};
this.say = function (){ console.log(this.name);}
}
function B(){
this.method = A;
this.method();
delete this.method;
}
var bObj = new B();
java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号