JavaScript 原型链继承和class继承

本文共有2989个字,关键词:原型链class继承

这段时间很多面试笔试,做了很多的笔试题,很多很基础的题目,勉强做出来了但漏洞百出。对前端的一些知识点还是很模糊的,有点浮躁,希望接下来多多研究总结一下,巩固自己的基础。
原型链和es6中的class的写法我常常混淆,今天遇到的一道笔试题,戳中了我的痛点,所以自己回来研究了一下。

题目:手写代码,实现JavaScript的封装和继承。

1.构造一个父类的Animal,拥有共享属性species,值为“动物”。
2.构造其子类Cat,拥有共享属性type,值为“猫科动物”,拥有对象属性name和color,拥有方法eat。
3.实例化两个Cat对象,name,color分别为“Hello,Blue”和“World,White”。

解答

  • 很基础的题目,基本了解过的同学都能写出来,下面我想尝试用原型链的方式和class的方式来实现。

一、原型链实现继承

  • 在es6之前,JavaScript的继承写法一般都是通过使用原型链的实现,即prototype,这种写法需要用一个中间对象来实现。我是参考廖雪峰老师的教程来实现的,直接上代码。
//1.构造一个父类的Animal,拥有共享属性species,值为“动物”。
    function Animal(){
        this.test1=function (){
            console.log("this is test1");
        }
    } 
    Animal.prototype.test2=function (){
        console.log("this is test2");
    }
    Animal.prototype.species="动物";
//我这里多写了两个测试方法,对于对象的公共方法,一般都是用test2的写法性能更好,因为test2是Animal共享的,test1在每示例化一个对象的时候,都会new一下这个test1的方法,消耗内存。

//2.构造其子类Cat,拥有共享属性type,值为“猫科动物”,拥有对象属性name和color,拥有方法eat。
    function Cat(name,color){
         Animal.call(this);//这里相当于在Cat实现了Animal的属性和方法,继承的关键
        this.name=name;
        this.color;
    }
    Cat.prototype.type="猫科动物";
         Cat.prototype.eat=function (){
             console.log(this.name+" eat");
         }
//封装一个函数实现继承的写法
    function inherits(Child, Parent) {
        var F = function () {};
        F.prototype = Parent.prototype;
        Child.prototype = new F();
        Child.prototype.constructor = Child;
    }

inherits(Cat,Animal);
//查看Cat的原型链,会发现已经实现了继承
//整个原型链:Cat.prototype ----> Animal.prototype ----> Object.prototype ----> null
console.log(Cat.prototype);

3.实例化两个Cat对象,name,color分别为“Hello,Blue”和“World,White”。
    var c1=new Cat("Hello","Blue");
    var c2=new Cat("World","White");
        //调用Cat共享的属性
    console.log(c1.type);
        //Cat实例对象调用继承Animal的方法
    console.log(c1.test2());
        //调用父类的属性
    console.log(c1.species);

二、class实现继承

  • es6可以通过class来实现类的写法,通过extends实现继承。
//1.构造一个父类的Animal,拥有共享属性species,值为“动物”。
class Animal{
    constructor(name){
        this.name=name;
    }
     test1(){
        console.log("this is test1");
    }
}
//构造函数用constructor来写
//定义在原型对象上的函数test1()(注意没有function关键字),这样就避免了Animal.prototype.test1 = function () {...}这样分散的代码。
//因为ES6明确规定,Class内部只有静态方法,没有静态属性。所以共享属性目前还是要这样写
Animal.prototype.species="动物";
//ES7有一个静态属性的提案
// class Animal{
//     static species="动物";
// }

//2.构造其子类Cat,拥有共享属性type,值为“猫科动物”,拥有对象属性name和color,拥有方法eat。
class Cat extends Animal{
    constructor(name,color){
        super(name);//直接继承父类的构造函数
        this.color=color;
    }
    eat(){
        console.log(this.name+" is eatting");
    }
}
Cat.prototype.type="猫科动物";


//3.实例化两个Cat对象,name,color分别为“Hello,Blue”和“World,White”。

var c1=new Cat("Hello","Blue");
var c2=new Cat("World","White");
console.log(Cat.prototype);
////调用Cat的共享方法
console.log(c1.eat());
//调用Cat共享的属性
console.log(c1.type);
//子类调用父类的方法
console.log(c1.test1());

「一键投喂 软糖/蛋糕/布丁/牛奶/冰阔乐!」

fengxianqi

(๑>ڡ<)☆谢谢老板~

使用微信扫描二维码完成支付

版权声明:本文为作者原创,如需转载须联系作者本人同意,未经作者本人同意不得擅自转载。
添加新评论
暂无评论