博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
整理js继承
阅读量:7008 次
发布时间:2019-06-28

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

实现继承的方法:

一,原型链:利用原型让一个引用类型继承另一个引用类型的属性和方法

function SuperType(){    this.property=true;}SuperType.prototype.getSuperValue=function(){    return this.property;};function SubType(){    this.subproperty=false;}//继承了SuperTypeSubType.prototype=new SuperType();SubType.prototype.getSubValue=function(){      return this.subproperty;} var instance=new SubType(); alert(instance.getSuperValue());  //true

注意问题:

a:所有引用类型默认都继承了Object,也是通过原型链实现的,所有函数的默认原型都是Object的实例。

alert(instance instanceof Object);  //true

b:确定原型和实例之间的关系,可以用instanceof操作符和isPrototypeOf()方法。

实例与原型链中出现过的构造函数都会返回true。

alert(instance instanceof SubType);  //true

原型链中出现过的原型,都可以说是原型链派生的实例的原型,返回true。

alert(SubType.prototype.isPrototypeOf(instance));  //true

c:给原型添加方法的代码一定要放在替换原型的语句之后。

d:通过原型链实现继承时不能使用对象字面量创建原型的方法,这样会重写原型链,之前的原型链被切断,SubType和SuperType之间没有关系了。

e:原型链的问题:每个实例都会共享属性,子类型不能向超类型中传参

优点:实例的方法可以共享

缺点:所有实例的属性共享

二,借用构造函数:在子类的构造函数内部调用超类型构造函数

function SuperType(){    this.colors=["red","blue","green"];//该数组就是引用类型值}function SubType(){   //继承了SuperType   SuperType.call(this);//SuperType.call(this)的意思就是使用SuperType 对象代替this对象,那么Subtype中不就有SuperType的所有属性和方法了,instance1对象就能够直接调用SuperType的方法以及属性了}var instance1=new SubType();instance1.colors.push("black");alert(instance1.colors);  //red,blue,green,blackvar instance2=new SubType();alert(instance2.colors);//red,blue,green

a:可以传递参数

b:借用构造函数问题:方法都在构造函数中定义,因此所有函数无法复用

优点:解决了原型链实现继承属性共享的问题,可以传递参数

缺点:函数无法复用,每个实例的方法都不相同

三,组合继承:将原型链和借用构造函数的技术组合到一块,扬长补短,思想:使用原型链对原型属性和方法的继承,使用借用构造函数实现对实例属性的继承。

function SuperType(name){            this.colors=["red","green","blue"];            this.name=name;        }        //用原生链的方式将方法写在外面,让每个实例使用相同的方法        SuperType.prototype.sayName=function(){            alert(this.name);        };        function SubType(name,age){            //第二次调用SuperType()            SuperType.call(this,name);  //让每个实例分别拥有自己的属性            this.age=age;        }        //继承方法        SubType.prototype=new SuperType();   //第一次调用SuperType()        //弥补因重写原型而失去的默认的constructor属性        SubType.prototype.constructor=SubType;         SubType.prototype.sayAge=function(){            alert(this.age);        };        var instance1=new SubType("jane",29);        instance1.colors.push("black");        alert(instance1.colors); //red,green,blue,black        instance1.sayName();  //jane        instance1.sayAge();  //29        var instance2=new SubType("tom",30);        alert(instance2.colors);//red,green,blue        instance2.sayName();  //tom        instance2.sayAge();  //30        alert(instance1.sayName==instance2.sayName);  //true        alert(SubType.prototype.constructor==SubType);//true

优点:最常用的继承模式,解决了借用构造函数,函数不能复用的问题,以及原型链属性共享,以及不能传参的问题

缺点:如代码中所说,调用了两次超类型构造函数,如果删除instance2的colors属性,依然会返回red,green,blue,这样就无法删除colors属性

delete instance2.colors;alert(instance2.colors);//red,green,blue

四,原型式继承:基于已有的对象创建新对象

Object.create()方法实现原型式继承:

//传入一个参数的情况下,对象名  var person={       name:"jane",       friends:["tom","nike","van"]   };   var anotherPerson=Object.create(person);   anotherPerson.name="greg";   anotherPerson.friends.push("rob");   var yetAnotherPerson=Object.create(person);   yetAnotherPerson.name="linda";   yetAnotherPerson.friends.push("barbie");   alert(person.friends); //tom,nike,van,rob,barbie*
//Object.create()方法传入两个参数,第一个参数,对象名,第二个参数:属性都是通过自己的描述符定义的。var person={    name:"jane",    friends:["tom","nike","van"]};var anotherPerson=Object.create(person,    {
    //以这种方式指定的任何属性都会覆盖原型对象上的同名属性。 name:{ value:"greg" } }); alert(anotherPerson.name); //greg

优点:不用再创建自定义的类型了

缺点:引用类型值的属性都会共享相应的值

五,寄生式继承:封装继承过程的函数

//createAnother函数接收了一个参数,也就是将要作为新对象基础的对象。function createAnother(original){    //把original对象传递给Object函数,将返回的结果赋给clone    var clone=Object(original);    //再为clone对象添加一个方法    clone.sayHi=function(){        alert("hi");    };    return clone;//返回这个对象}var person={    name:"jane",    friends:["tom","nike","van"]};var anotherPerson=createAnother(person);anotherPerson.sayHi();//hi  anotherPerson具有Person不具有的方法sayHi()

优点:为对象添加函数

缺点:函数无法复用

六,寄生组合式继承:使用寄生式继承超类型的原型,再将结果返回给子类型的原型。

function inheritPrototype(SubType,SuperType){            var prototype=Object(SuperType.prototype);//创建对象            prototype.constructor=SubType;  //弥补因重写原型而失去的默认的constructor属性            SubType.prototype=prototype;//指定对象        }function SuperType(name){            this.name=name;            this.colors=["red","green","blue"];        } SuperType.prototype.sayName=function(){            alert(this.name);        }; function SubType(name,age){            SuperType.call(this,name);            this.age = age;        } inheritPrototype(SubType,SuperType); SubType.prototype.sayAge=function(){            alert(this.age);        }; var instence=new SubType("jane",29); instence.sayName(); instence.sayAge();

优点:解决了组合继承的两次调用超类型构造函数问题

 

转载于:https://www.cnblogs.com/wgj32/p/5722806.html

你可能感兴趣的文章
模块封装代码
查看>>
《Machine Learning》(第一章)序章
查看>>
【右键禁用U盘的小技巧】
查看>>
执行sql语句后的数据处理api
查看>>
jquery $.each的用法
查看>>
Python --元组与列表的差异
查看>>
PHP TP增删改
查看>>
VMware虚拟机与主机联通及配置上网
查看>>
single-row function和muti-row function
查看>>
keepalived
查看>>
意向锁
查看>>
线性规划
查看>>
常见错误分析-笔记
查看>>
P1256 显示图像(广搜)
查看>>
MongoDB(课时29 MapReduce)
查看>>
Slurm任务调度系统部署和测试(源码)(1)
查看>>
李超树详解
查看>>
怎样才是全能的程序员?
查看>>
with as的用法
查看>>
springboot oauth 鉴权之——授权码authorization_code鉴权
查看>>