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

JavaScript继承

时间:2023-03-27 16:23:38 JavaScript

构造函数编写在ES6之前,类的创建都是使用构造函数进行的。下面的代码是一个构造函数的写法。我们习惯于将构造函数的首字母大写:functionPerson(name,age){this.name=namethis.age=age}Person.prototype.running=function(){console.log(this.name+"running~")}constperson=newPerson('lisa',18)person.running()//lisarunning~这段代码中,方法并没有直接写在构造函数“Among”中,而是写在了原型中。这是因为我们在创建实例对象时,为其属性和方法分配了存储空间,但是方法是一样的。每次创建实例对象都为方法分配空间有点浪费,但是写在原型中就不存在这种情况。当一个实例对象调用一个方法时,它会去原型中寻找这个方法,而那个方法从头到尾只有一个“一个”。多个构造函数的属性和方法重叠有时候我们在写构造函数的时候,会发现它们的属性或方法是一样的,就像下面两个构造函数:Teacherclass:functionTeacher(name,age,title){this.name=namethis.age=agethis.title=title}Teacher.prototype.eating=function(){console.log(this.name+"eating~")}Teacher.prototype.teaching=function(){console.log(this.name+"teaching~")}Studentclass:functionStudent(name,age,sno){this.name=namethis.age=agethis.sno=sno}Student.prototype.eating=function(){console.log(this.name+"eating~")}Student.prototype.studying=function(){console.log(this.name+"studying~")}我们可以找到Teacher类和Student类的名字,年龄属性和饮食重叠。这时候就可以利用面向对象中封装和继承的思想,将相同的属性和方法封装到一个父类中,然后让Teacher类和Student类继承。在ES6之前,extends的继承关键字是不存在的,那我们就来说说基于原型链的继承方式。(1)使用构造函数Person(name,age){this.name=namethis.age=age}Person.prototype.eating=function(){console.log(this.name+"eating~")}//subclassfunctionStudent(name,age,sno){Person.call(this,name,age)this.sno=sno}Student.prototype=newPerson()Student.prototype.studying=function(){console.log(this.name+"studying~")}conststu=newStudent('lisa',18,111)stu.eating()stu.studying()显然,在这个方法中,我们调用了两次父类构造函数。(2)原型继承的思想可以如下图所示:Teacher类和Student类的构造函数的原型都指向各自的中间原型,中间原型最终指向Person类。按照这个思路,我们可以写一个继承的函数:name=namethis.age=age}Person.prototype.running=function(){console.log(this.name+"running~")}functionStudent(sno){this.sno=sno}Student.prototype=inherit(Person)Student.prototype.studying=function(){console.log(this.name+"studying~")}conststu=newStudent('lisa',18,1111)stu.running()//lisarunning~stu.studying()//lisstudying~在这个函数中,我们设计了一个中间构造函数,其原型指向传入的构造函数,这个继承函数最终返回中间构造函数的实例对象。这时我们只需要将Student构造函数的原型指向返回的实例对象即可完成图中的模式。这个inherit函数也可以用Object中的setPrototypeOf来写,就是下面的方法:constobj2=inherit2(obj)console.log(obj2.name)//彼得或使用Object.create()方法:functioninherit3(obj){constnewObj=Object.create(obj)//返回一个对象,并且这个对象的原型会指向objreturnnewObj}constobj={name:'peter'}constobj1=inherit3(obj)console.log(obj1.name)(3)寄生组合模式functioninherit(obj){functionmiddleFn(){}middleFn.prototype=newobj()returnnewmiddleFn()}functioninheritPrototype(sub,sup){sub.prototype=inherit(sup)sub.prototype.constructor.name=sub}inheritPrototype(Student,Person)最后sub的原型中的构造函数指向sub