如何将ES5中的继承方法改写为长尾词?

2026-04-02 23:511阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1152个文字,预计阅读时间需要5分钟。

如何将ES5中的继承方法改写为长尾词?

自从有了ES6的继承后,ES5的继承方式也退出了舞台,在实际开发中基本用不到,但在面试或某些情况下可能还会用到。先看看ES6的继承:

javascriptclass Father { constructor(a) { console.log(a); } play() { console.log(aaa); } static run() { }}

自从有了ES6的继承后,ES5的继承也退出了舞台,在实际开发也不会用得着,但在面试或许用的着;

先看看ES6的继承

class Father{ constructor(a){ console.log(a); } play(){ console.log("aaa"); } static run(){ console.log("static"); } } class Son extends Father{ constructor(){ super(); } } var s=new Son(); s.play(); Father.run() Son.run();

在ES6里只需要使用extends和super关键字即可继承父类的方法和属性(包括静态)

在ES5里没有这些关键字

ES5的继承

ES5的五种种继承方式:

  1. 对象冒充继承
  2. 原型链继承
  3. 组合继承
  4. 原型式继承
  5. 寄生式继承(重要)

对象冒充继承

function Father(_r){ this.r=_r; console.log("aa"); console.log(this.r); } Father.a=3; Father.run=function(){ console.log(Box.a); } function Son(){ Father.call(this,3);//改变this的指向,执行父类构造函数并传参到父类 } var b=new Son();//"aa",3 b.run();//TypeError

通过call或apply改变this指向,并执行了父类的构造函数

缺点:只能继承超类的构造函数,无法继承原型链上的方法

原型链继承

function Father(){ console.log("aa"); } Father.prototype.b=10; Father.prototype.play=function(){ console.log(this.b); } Son.prototype=new Father(); function Son(){ } var b=new Son(); b.play();//10

将父类的实例化对象赋值给子类的原型上实现的继承

缺点:覆盖子类原有的属性和方法,只能执行父类的属性和方法,无法执行父类的构造函数

组合继承

前面的两种继承(冒充,原型链)各有特点,把这两种继承组合起来称为组合继承

function Father(_r){ this.r=_r; console.log("aa"); } function Son(_r){ Father.call(this,_r);//冒充,改变父类的this指向子类 } Son.prototype=new Father(3);//原型链继承 var c=new Son(10);

使用原型链继承了父类的属性和方法,使用对象冒充继承了父类的构造函数

看起来很不错的样子,但这并不是完美的继承方式;

缺点:会覆盖子类原有的属性和方法,因为原型链继承会将父类实例化,提前执行了一次父类构造函数;当子类实例化对象后,实际上是执行了两次父类的构造函数。

使用场景:子类原本没有属性和方法,父类构造函数没有内容。

原型式继承

为了解决执行两次父类构造函数使用了一个中介,在继承时就不会执行父类的构造函数

function Father(_a){ this.a=_a } Father.prototype.play=function(){ console.log("aaa"); } function Agent(){ } Agent.prototype=Father.prototype; function Son(){ } Son.prototype=new Agent(); var o=new Son(); o.play();//aaa

使用了Agent的类作为中介,将父类的原型复制后,再进行实例化继承不会执行父类的构造函数;

如何将ES5中的继承方法改写为长尾词?

缺点:虽然解决了构造函数执行两次的问题,但是使用该方法继承后,构造函数一次也不会执行。

寄生式继承(完美继承)

封装了一个extend方法,该方法传入两个参数,分别是父类和子类

function extend(subClass, supClass) { function Agent() {} Agent.prototype = supClass.prototype; var o = subClass.prototype; subClass.prototype = new Agent(); if (Object.assign) { Object.assign(subClass.prototype, o); } else { if (Object.getOwnPropertyNames) { var names = Object.getOwnPropertyNames(o); for (var i = 0; i < names.length; i++) { var desc = Object.getOwnPropertyDescriptor(names[i]); Object.defineProperty(subClass.prototype, names[i], desc); } } else { for (var prop in o) { subClass.prototype[prop] = o[prop]; } } } subClass.prototype.constructor = subClass; //防止子类的构造函数被覆盖 if (supClass.prototype.constructor === Object) { supClass.prototype.constructor = supClass; //防止父类类的构造函数被覆盖 } // 存储父类,方便继承构造函数调用 subClass.prototype.superClass = supClass; } //调用 function Father(_r) { this.r = _r; console.log("Father"); } Father.prototype.play = function () { console.log("play game"); }; function Ball(_r) { this.superClass.call(this, _r); } var s = new Son(10);//Father s.play();//play game

extend方法,使用了Object.assgin、Object.getOwnPropertyNames、Object.getOwnPropertyDescriptor、Object.defineProperty都存在兼容问题,所以进行了判断。

该方法继承集合了前四种的优点,实现了ES5的完美继承;

结语:

ES5对比ES6的继承,麻烦太多太多,以后的实际工作也不会使用;

但是在面试的时候,面试官可能会问,多学一点总没错。

以上就是详解JavaScript之ES5的继承的详细内容,更多关于JavaScript ES5的继承的资料请关注易盾网络其它相关文章!

本文共计1152个文字,预计阅读时间需要5分钟。

如何将ES5中的继承方法改写为长尾词?

自从有了ES6的继承后,ES5的继承方式也退出了舞台,在实际开发中基本用不到,但在面试或某些情况下可能还会用到。先看看ES6的继承:

javascriptclass Father { constructor(a) { console.log(a); } play() { console.log(aaa); } static run() { }}

自从有了ES6的继承后,ES5的继承也退出了舞台,在实际开发也不会用得着,但在面试或许用的着;

先看看ES6的继承

class Father{ constructor(a){ console.log(a); } play(){ console.log("aaa"); } static run(){ console.log("static"); } } class Son extends Father{ constructor(){ super(); } } var s=new Son(); s.play(); Father.run() Son.run();

在ES6里只需要使用extends和super关键字即可继承父类的方法和属性(包括静态)

在ES5里没有这些关键字

ES5的继承

ES5的五种种继承方式:

  1. 对象冒充继承
  2. 原型链继承
  3. 组合继承
  4. 原型式继承
  5. 寄生式继承(重要)

对象冒充继承

function Father(_r){ this.r=_r; console.log("aa"); console.log(this.r); } Father.a=3; Father.run=function(){ console.log(Box.a); } function Son(){ Father.call(this,3);//改变this的指向,执行父类构造函数并传参到父类 } var b=new Son();//"aa",3 b.run();//TypeError

通过call或apply改变this指向,并执行了父类的构造函数

缺点:只能继承超类的构造函数,无法继承原型链上的方法

原型链继承

function Father(){ console.log("aa"); } Father.prototype.b=10; Father.prototype.play=function(){ console.log(this.b); } Son.prototype=new Father(); function Son(){ } var b=new Son(); b.play();//10

将父类的实例化对象赋值给子类的原型上实现的继承

缺点:覆盖子类原有的属性和方法,只能执行父类的属性和方法,无法执行父类的构造函数

组合继承

前面的两种继承(冒充,原型链)各有特点,把这两种继承组合起来称为组合继承

function Father(_r){ this.r=_r; console.log("aa"); } function Son(_r){ Father.call(this,_r);//冒充,改变父类的this指向子类 } Son.prototype=new Father(3);//原型链继承 var c=new Son(10);

使用原型链继承了父类的属性和方法,使用对象冒充继承了父类的构造函数

看起来很不错的样子,但这并不是完美的继承方式;

缺点:会覆盖子类原有的属性和方法,因为原型链继承会将父类实例化,提前执行了一次父类构造函数;当子类实例化对象后,实际上是执行了两次父类的构造函数。

使用场景:子类原本没有属性和方法,父类构造函数没有内容。

原型式继承

为了解决执行两次父类构造函数使用了一个中介,在继承时就不会执行父类的构造函数

function Father(_a){ this.a=_a } Father.prototype.play=function(){ console.log("aaa"); } function Agent(){ } Agent.prototype=Father.prototype; function Son(){ } Son.prototype=new Agent(); var o=new Son(); o.play();//aaa

使用了Agent的类作为中介,将父类的原型复制后,再进行实例化继承不会执行父类的构造函数;

如何将ES5中的继承方法改写为长尾词?

缺点:虽然解决了构造函数执行两次的问题,但是使用该方法继承后,构造函数一次也不会执行。

寄生式继承(完美继承)

封装了一个extend方法,该方法传入两个参数,分别是父类和子类

function extend(subClass, supClass) { function Agent() {} Agent.prototype = supClass.prototype; var o = subClass.prototype; subClass.prototype = new Agent(); if (Object.assign) { Object.assign(subClass.prototype, o); } else { if (Object.getOwnPropertyNames) { var names = Object.getOwnPropertyNames(o); for (var i = 0; i < names.length; i++) { var desc = Object.getOwnPropertyDescriptor(names[i]); Object.defineProperty(subClass.prototype, names[i], desc); } } else { for (var prop in o) { subClass.prototype[prop] = o[prop]; } } } subClass.prototype.constructor = subClass; //防止子类的构造函数被覆盖 if (supClass.prototype.constructor === Object) { supClass.prototype.constructor = supClass; //防止父类类的构造函数被覆盖 } // 存储父类,方便继承构造函数调用 subClass.prototype.superClass = supClass; } //调用 function Father(_r) { this.r = _r; console.log("Father"); } Father.prototype.play = function () { console.log("play game"); }; function Ball(_r) { this.superClass.call(this, _r); } var s = new Son(10);//Father s.play();//play game

extend方法,使用了Object.assgin、Object.getOwnPropertyNames、Object.getOwnPropertyDescriptor、Object.defineProperty都存在兼容问题,所以进行了判断。

该方法继承集合了前四种的优点,实现了ES5的完美继承;

结语:

ES5对比ES6的继承,麻烦太多太多,以后的实际工作也不会使用;

但是在面试的时候,面试官可能会问,多学一点总没错。

以上就是详解JavaScript之ES5的继承的详细内容,更多关于JavaScript ES5的继承的资料请关注易盾网络其它相关文章!