最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

天天即时看!实现js继承的几种方式以及他们的优缺点

来源:博客园

7.实现继承的几种方式以及他们的优缺点

①类式继承(构造函数)

var father = function() { this.age = 52; this.say = function() {  alert("hello i am "+ this.name " and i am "+this.age + "years old");  }} var child = function() { this.name = "bill"; father.call(this);} var man = new child();man.say();

特点就是创建子类实例时,可以向父类传递参数,可以实现多继承(call多个父类对象)


(资料图片)

缺点:

  • 实例并不是父类的实例,只是子类的实例

  • 只能继承父类的实例属性和方法,不能继承原型属性/方法

  • 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能

②组合式继承(伪经典继承)

原型链继承经典继承组合。使用原型链继承方式实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又保证每个实例都有各自的属性。

SuperType.prototype.greet = function() {  return "hello~," + this.card.name;}•function SuperType(gender) {  this.card = {    name: "佩奇",    age: 20,    gender: gender   }}​

优点如上

不足:无论在什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部

③原型式继承

两种方法:

一、借用构造函数(本质上就是做了一次浅复制)

借用构造函数,在一个函数内部创建一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回这个临时类型的一个新实例。

二、使用Object.create() ES5通过增加Object.create()方法,将原型式继承的概念规范化了

// 借用构造函数function helperFun(targetObj) {  function newFun() {}  newFun.prototype = targetObj;  return new newFun();}•let myObj = {  username: "dog",  age: 14,  other: {    hobby: "reading",    taste: "sore"   }}•console.log(myObj);let newObj = helperFun(myObj)newObj.username = "cat";newObj.other.hobby = "sleeping";console.log(newObj);​--------------------------------------------------------// Object.create()let presentIbj = {  username: "熊大",  sex: "male",  age: 19,  greet() {    console.log("name is  " + this.username);   }}•let newObj1 = Object.create(presentIbj);let newObj2 = Object.create(presentIbj);newObj1.username = "熊二";console.log(newObj1);console.log(newObj2);​

④寄生式继承

寄生式继承就是创建一个仅用于封装继承过程的函数,该函数在内部以某种方式(使用原型式继承对一个目标对象进行浅复制,增强这个浅复制的能力)来增强对象,最后就好像像真的是它做了所有工作一样返回对象。引用类型的属性始终会被继承和共享。

/ 寄生式继承function helperFun(targetObj) {    function newFun() {};    newFun.prototype = targetObj;    return new newFun();}​function packInherit(originObj) {    let evalObj = helperFun(originObj);    evalObj.greet = function() {        console.log("hello~," + this.name);    };    return evalObj;}​let initObj = {    name: "虹猫",    like: ["reading", "running"],    age: 20}​let newObj1 = packInherit(initObj);console.log(newObj1); //[ "reading", "running", "蓝兔" ]newObj1.like.push("蓝兔");console.log(newObj1.like); //[ "reading", "running", "蓝兔" ]newObj1.greet(); //hello~,虹猫​let newObj2 = packInherit(initObj);newObj2.name = "蓝兔";console.log(newObj2); //{ greet: [Function (anonymous)], name: "蓝兔" }newObj2.greet(); //hello~,蓝兔console.log(newObj2.like); //[ "reading", "running", "蓝兔" ]

优点就是:上手简单,无需单独创建构造函数。

缺点就是:函数复用率降低。

⑤寄生组合式继承

寄生组合继承是为降低父类构造函数的开销。通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。

// 寄生组合式Super.prototype.say = function() {    console.log(this.name);}function Super(name) {    this.name = name,    this.colors = ["red", "blue", "green"]}function Son(name, age) {    this.age = age;    Super.call(this, name)}​var another = Object.create(Super.prototype);another.constructor = Son;var another = Object.assign(Son.prototype(), Super.prototype())// Son.prototype = another;var instance1 = new Son("duck", 19)instance1.instance1.colors.push("pink")var instance2 = new Son("cat", 18)

优点就是:只调用一次父构造函数,并且避免了在子原型上添加不必要,多余的属性。与此同时,原型链还能保持不变

缺点就是:代码太复杂

⑥class语法继承

// class继承class Parent {    constructor(name, gender) {        this.name = name;        this.gender = gender;        this.greet = function() {            console.log("greet");        };    }    speak() {        console.log("parent speak")    }​    static speak() {        console.log("static speak")    }}​//class 子类 extends 父类class Son extends Parent {    //在子类的构造方法中调用父类的构造方法    constructor(name, gender, hobby) {        super(name, gender);        this.hobby = hobby;    }    //子类中声明的方法名和父类中的方法名相同时,子类中的方法将覆盖继承于父类的方法    speak() {        console.log("Son speak");    }}const grandson = new Son("lucky", "male", "reading");console.log(grandson.name, grandson.gender, grandson.hobby); //lucky male readinggrandson.greet(); //greetgrandson.speak(); //Son speakSon.speak(); //static speak

关键词: 构造函数 优点就是 缺点就是