当前位置: 首页 > Web前端 > JavaScript

继承的几种方式

时间:2023-03-27 13:00:34 JavaScript

实现一个父类//定义一个动物类functionAnimal(name){//attributethis.name=name||'动物';//实例方法this.sleep=function(){console.log(this.name+'sleeping!');}}//原型方法Animal.prototype.eat=function(food){console.log(this.name+'eating:'+food);};原型链继承核心:使用父类的实例作为原型子类函数的Cat(){}Cat.prototype=newAnimal();Cat.prototype.name='cat';// TestCodevarcat=newCat();console.log(cat.name);console.log(cat.eat('fish'));console.log(cat.sleep());console.log(catinstanceofAnimal);//trueconsole.log(catinstanceofCat);//真正的特点1.很纯的继承关系,实例是子类的实例,也是父类的实例2.父类新增原型方法/原型属性,子类可以访问3.简单,容易实现缺点1.如果要添加新的原型属性和方法,必须在像newAnimal()这样的语句之后执行2.不能实现多重继承3.来自原型对象的所有属性被所有实例共享4.创建子类实例时,无法向父类构造函数传递参数推荐索引:(3、4两个致命缺陷)构造继承核心:使用父类构造函数增强子类实例,相当于复制实例将父类的属性赋予子类(未使用原型)functionCat(name){Animal.call(this);this.name=名称||'Tom';}//测试代码变量cat=newCat();console.log(cat.name);console.log(cat.sleep());console.log(catinstanceofAnimal);//错误判断sole.log(catinstanceofCat);//true特点:1.解决1.子类实例共享父类引用属性的问题。2.创建子类实例时,可以给父类传递参数3.可以实现多重继承(调用多个父类对象)缺点:1.实例不是父类的实例,而是子类的实例2.只能继承父类的实例属性和方法,不能继承原型属性/方法3.不能实现函数复用,每个子类都有一份父类的实例函数,影响性能推荐指数:★★(缺点3)实例继承核心:为父类实例增加新特性,返回函数Cat(name){varasa子类实例instance=newAnimal();instance.name=名称||'汤姆';returninstance;}//测试代码变量cat=newCat();console.log(cat.name);console.log(cat.sleep());console.log(catinstanceofAnimal);//trueconsole.log(catinstanceofCat);//false特点:1.调用方法没有限制,无论是newsubclass()还是subclass(),返回的Objects都是一样的效果缺点:1.实例是父类的实例,不是2.不支持多重继承的子类实例引用的优点,然后通过使用父类实例作为子类原型,实现函数重用functionCat(name){Animal.call(this);this.name=名称||'Tom';}Cat.prototype=newAnimal();//组合继承需要固定指向的构造函数Cat.prototype.constructor=Cat;//测试代码变体cat=newCat();console.log(cat.name);console.log(cat.sleep());console.log(catinstanceofAnimal);//trueconsole.log(catinstanceofCat);//真正的特点:1.弥补了方法2的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法2.既是子类的实例又是父类的实例3.没有共享引用属性的问题4.可以传递参数5.函数可以复用缺点:1.调用了两次父类构造函数,生成了两个实例(子类实例挡住了子类原型上的那个(是)推荐指数:★★★★(只多消耗一点内存)寄生组合继承核心:通过寄生的方式,切断父类的实例属性,使得父类的构造被调用两次时,不会两次初始化实例方法/属性,避免组合继承的缺点functionCat(name){Animal.call(this);this.name=name||'Tom';}(function(){//创建一个非实例方法的类varSuper=function(){};Super.prototype=Animal.prototype;//使用实例作为子类的原型Cat.prototype=newSuper();//需要修复构造函数Cat.prototype.constructor=Cat;})();//测试代码变量cat=newCat();console.log(cat.name);console.log(cat.sleep());console.log(catinstanceofAnimal);//trueconsole.log(catinstanceofCat);//true特点:完美缺点:实现复杂推荐指数:★★★★(实现复杂,扣一星)ExtendObject.create()Object.create()方法创建新对象,使用已有对象提供新创建的对象的__proto__Object.create(proto,[propertiesObject])参数proto新建对象的原型对象propertiesObject,可选。需要传入一个对象,对象的属性类型参考Object.defineProperties()的第二个参数。如果指定了该参数且没有undefined,则传递的对象自身的可枚举属性(即自己定义的属性,不是其原型链上的可枚举属性)会将指定的属性添加到新创建的对象值和对应的属性描述符中。返回值是一个具有指定原型对象和属性的新对象。手动实现function_create(proto,propertiesObject){functionF(){for(letkeyinpropertiesObject){this[key]=propertiesObject[key]}}F.prototype=protoreturnnewF()}