侧边栏壁纸
  • 累计撰写 48 篇文章
  • 累计创建 20 个标签
  • 累计收到 11 条评论

【查缺补漏】JavaScript继承

uvdream
2021-09-04 / 0 评论 / 0 点赞 / 32 阅读 / 3,202 字
温馨提示:
本文最后更新于 2022-04-08,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

继承

原型链继承


function Animal() {

  this.cName = "动物";

}

Animal.prototype.getName = function () {

  return this.cName;

};

function Dog() {}

+Dog.prototype = new Animal();

Dog.prototype.getDogName = function () {

  return this.cName;

};

//会覆盖前面的getName方法

Dog.prototype.getName = function () {

  return "覆盖了老名字";

};

var dog = new Dog();

console.log(dog.cName);

console.log(dog.getDogName());

console.log(dog.getName());

存在问题: 引用值共享

问题分析


function Animal() {

   this.cName = "动物";

+  this.List=['小狗','小猫']

}

Animal.prototype.getName = function () {

  return this.cName;

};

function Dog() {}

Dog.prototype = new Animal();

var dog = new Dog();

var dog2=new Dog()


+// 这样看上去没问题

+dog2.cName="小狗"

+console.log(dog.cName)//动物

+console.log(dog2.cName)//小狗


+// 问题分析

+dog.List.push('老鼠')

+console.log(dog.List)//["小狗", "小猫", "老鼠"]

+console.log(dog2.List)//["小狗", "小猫", "老鼠"]

我们更改了 dog 的 cName,但是 dog2 的 cName 也跟着变了?由此引出第二种继承方式

原型链继承字面量添加方法存在问题


function Animal() {

    this.cName = "动物";

   this.List=['小狗','小猫']

 }

 Animal.prototype.getName = function () {

     console.log("获取name");

   return this.cName;

 };

 function Dog() {}

 Dog.prototype = new Animal();

+Dog.prototype={

+    getAge:function(){

+       console.log("获取age");

+   }

+ }

 var dog = new Dog();

 var dog2=new Dog()

+ dog.getAge()

+dog.getName()//错误dog.getName is not a function

以对象字面量方式创建原型方法会破坏之前的原型链,因为这相当于重写了原型链

构造方法继承


function Animal(){

    this.cName="动物"

    this.List=["小狗","小猫"]

}

Animal.prototype.getName=function(){

    return this.cName

}

function Dog(){

    // Animal() //错误的方式,此时this指向window

+    Animal.call(this)

}

var dog=new Dog()

var dog2=new Dog()

dog.List.push("老鼠")

console.log(dog.List);

console.log(dog2.List);

+ dog.getName()//错误dog.getName is not a function

存在问题:没办法拿到原型上的方法

组合继承


function Animal() {

    this.cName = "动物";

    this.List = ['小狗', '小猫']

}

Animal.prototype.getName = function () {

    console.log("获取name");

    return this.cName;

};

function Dog() {

+    Animal.call(this)

}

// 实例化这个时候会被影响,但是call之后被覆盖了就不会被影响,也就是两种组合方式互补

+Dog.prototype = new Animal();


var dog = new Dog();

var dog2 = new Dog()

dog.List.push("老鼠")

console.log(dog.List)

console.log(dog2.List);

dog.getName()

存在问题:Animal 方法被调用多次

寄生组合继承


function Animal() {

    this.cName = "动物";

    this.List = ['小狗', '小猫']

}

Animal.prototype.getName = function () {

    console.log("获取name");

    return this.cName;

};

function Dog() {

    Animal.call(this)

}

<!-- 兼容老版老版本浏览器,create为es6新特性 -->

if(!Object.create){

    Object.create=function(proto){

        function F(){}

        F.prototype=proto;

        return new F()

    }

}

+Dog.prototype.say=function(){

+    console.log("小狗叫了");

+}

-// Sub.prototype=new Super()


+Dog.prototype=Object.create(Animal.prototype)


+// Dog.prototype.say=function(){

+//     console.log("小狗叫了");

+// }

var dog = new Dog();

var dog2 = new Dog()

dog.List.push("老鼠")

console.log(dog.List)

console.log(dog2.List);

dog.getName()

dog.say()

存在问题:


 Dog.prototype.say=function(){

     console.log("小狗叫了");

 }

Dog 原型添加方法不能在Dog.prototype=Object.create(Animal.prototype)之前,在这之前会出现dog.say()不存在错误

class 继承


class Animal {

  cName = "动物";

  List = ["小狗", "小猫"];

  getName() {

    console.log("获取name");

  }

}

class Dog extends Animal {

  getAge() {

    console.log("获取age");

  }

}

var dog = new Dog();

var dog2 = new Dog();

console.log(dog.cName);

dog.List.push("老鼠");

console.log(dog.List);

console.log(dog2.List);

dog.getName();

dog.getAge();
0

评论区