前言:
而今兄弟们对“js的继承方式有哪些”大约比较讲究,看官们都需要知道一些“js的继承方式有哪些”的相关文章。那么小编也在网络上搜集了一些有关“js的继承方式有哪些””的相关知识,希望大家能喜欢,各位老铁们一起来了解一下吧!1. 原型链继承
原型链继承:想要继承,就必须要提供父类(继承谁,提供继承的属性)
//父级function Person(name) { //给构造函数添加参数 this.name = name; this.age = 10; this.sum = function (){ console.log(this.name) }}//原型链继承function Per() { }Per.prototype = new Person(); //主要 实现继承var per1 = new Per();console.log(per1.age); //10
重点:让新实例的原型等于父类的实例
特点:1.实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性。(新实例不会继承父类实例的属性!)
缺点:
1>新实例无法向父类构造函数参数。
2>父子构造函数的原型对象之间有共享问题
2. 借用构造函数继承
使用call和apply借用其他构造函数的成员, 可以解决给父构造函数传递参数的问题, 但是获取不到父构造函数原型上的成员.也不存在共享问题
//父级function Person(name) { //给构造函数添加参数 this.name = name; this.age = 10; this.sum = function (){ console.log(this.name) }}//子构造函数function Per(name) { //使用call借用Person的构造函数 Person.call(this,name)}//测试是否有了Person的成员var stn = new Per('我是');stn.sum(); // 我是console.log(stn.age)
重点:用.call()和.apply()将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行(复制))
缺点:1、只能继承父类构造函数的属性。
2、无法实现构造函数的复用。(每次用每次都要重新调用)
3、每个新实例都有父类构造函数的副本,臃肿。
特点:1、只继承了父类构造函数的属性,没有继承父类原型的属性。
2、解决了原型链继承缺点1、2、3。
3、可以继承多个构造函数属性(call多个)。
4、在子实例中可向父实例传参。
3. 组合继承
借用构造函数 + 原型式继承
//父级function Person(name) { //给构造函数添加参数 this.name = name; this.age = 10; this.sum = function (){ console.log(this.name) }}//创建子构造函数function Per(name) { Person.call(this,name); //借用构造函数}Per.prototype = new Person() //继承原型链继承var str = new Per('zhao');console.log(str.name); //'zhao' 是继承了Per子构造函数的属性console.log(str.age); // 10 是继承了Person父类原型的属性
重点:结合了两种模式的优点,传参和复用
特点:1、可以继承父类原型上的属性,可以传参,可复用。
2、每个新实例引入的构造函数属性是私有的。
缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数
4. 原型链继承
//父级function Person(name) { //给构造函数添加参数 this.name = name; this.age = 10; this.sum = function (){ console.log(this.name) }}//设置父构建函数的原型Person.prototype.fn = function (){ console.log(this.age)}//构建子构造函数function Per() {}//实现继承var str = new Person(); //拿到父类的实例console.log(str.age); // 10str.fn(); 10
重点:用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理。
特点:类似于复制一个对象,用函数来包装。
缺点:1、所有实例都会继承原型上的属性。
2、无法实现复用。(新实例属性都是后面添加的)
5. 寄生式继承
//父级function Person(name) { //给构造函数添加参数 function fn(){} fn.prototype = name; //继承传入的参数 return new fn(); //返回函数对象}var str = new Person();//以上是原型式继承,给原型式继承在套一个壳子传递参数 function Per(name) { var fn1 = Person(name); fn1.name = "zhao"; return fn1}var fn3 = Per(str);console.log(fn3.name); //返回str对象,继承了str的属性
重点:就是给原型式继承外面套了个壳子。
优点:没有创建自定义类型,因为只是套了个壳子返回对象(这个),这个函数顺理成章就成了创建的新对象。
缺点:没用到原型,无法复用
6. 寄生组合式继承
function Person(name){ this.name = name; this.hobbies = ['a','b','v']};function student(name,age){ Person.call(this,name); this.age = age;}//关键的三步 实现继承// 使用F空函数当子类和父类的媒介 是为了防止修改子类的原型对象影响到父类的原型对象let fn = function (){};fn.prototype = Person.prototype;student.prototype = new fn();var fn1 = new student('zhao','24')console.log(fn1)
组合继承最大的缺点是最调用两次父构造函数
一次是设置子类实例的原型的时候:
student.prototype = new Person();
一次是在创建子类型实例的时候:
var fn = new student('zhao','24')7. es6实现继承
class parents { constructor(){ this.grandmather = 'rose'; this.grandfather = 'jack'; }}class children extends parents{ constructor(mather,father){ //super 关键字,它在这里表示父类的构造函数,用来新建父类的 this 对象。 super(); this.mather = mather; this.father = father; }}let child = new children('mama','baba');console.log(child)
标签: #js的继承方式有哪些