博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript继承方式详解
阅读量:5896 次
发布时间:2019-06-19

本文共 2955 字,大约阅读时间需要 9 分钟。

继承方式主要有六种:

1、原型链继承  存在对象共享的问题

2、构造函数继承  借助call apply方法实现  :函数复用性问题 每次实例化,都重新执行了一次父类,父类中的方法重复定义  

3、组合模式(原型链+构造函数)构造函数继承属性,原型链继承方法  :解决了对象共享,但是属性继承出现两次

4、原型方式 使用一个空间空函数

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(); //lc25b.sayhi();  //parent

3、混合方式 (原型方式+构造函数方式) 

使用构造函数继承属性,原型链继承方法

但是有一点不好的地方:  使用原型链继承时,实际上属性也继承了,重复了。 

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();

 

转载于:https://www.cnblogs.com/lydialee/p/4780400.html

你可能感兴趣的文章
Springboot配置(上)
查看>>
Luogu345: [POI2007]POW-The Flood
查看>>
java--Eclipse for mac 代码提示(代码助手,代码联想)快捷键修改
查看>>
Jdom的简单操作
查看>>
left join on/right join on/inner join on/full join on连接
查看>>
Codeforces 582B Once Again
查看>>
template.helper 多参数
查看>>
RadioButton布局图片+文字 实现tabhost效果
查看>>
[HEOI2012]采花
查看>>
access中设置不等于
查看>>
hdu 1221 Rectangle and Circle
查看>>
Android 四大组件之四(ContentProvider)
查看>>
Android 四大组件之一(Activity)
查看>>
扫描(一)
查看>>
MySQLDump在使用之前一定要想到的事情 [转载]
查看>>
PIE SDK矢量数据的读取
查看>>
两种方式分别改变alertdialog的宽和高
查看>>
TextView-setCompondDrawables用法
查看>>
由扭结理论中的琼斯多项式的证明想到的
查看>>
淘宝Hadoop集群的概况
查看>>