JavaScript原型和原型链(必考三座大三之一)

Posted 精通各种hello world的小希

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript原型和原型链(必考三座大三之一)相关的知识,希望对你有一定的参考价值。

Class

在学习原型和原型链之前,首先来说一下ES6诞生的新语法——class类,它是一个语法糖(就是更方便程序员使用的一种玩意),对比ES5,ES6中类的写法更加清晰、更像面向对象编程,一个类(构造函数)的所有代码都放入同一段代码块中,更加容易管理维护,通俗点来说,class实际上就是函数。

上代码!

  // 创建父类
    class Dog{
        // 创建父类属性
        constructor(name,color){
            this.name = name;
            this.color = color;
        }
        bark(){
            console.log(`我是${this.color}的${this.name},汪汪汪!!!`);
        }
    }
    // 子类1
    class HaShiQi extends Dog{
         // 创建子类属性
        constructor(name,color,hobby){
            // 接收父类属性直接用super(父属性1,父属性2)
            super(name,color);
            this.hobby = hobby;
        }
        run(){
            console.log(`大家好,我是${this.color}的${this.name},我喜欢${this.hobby}`)
        }
    }
    // 子类2
    class KeJi extends Dog{
        constructor(name,color,sport){
            super(name,color);
            this.sport = sport;
        }
        go(){
            console.log(`大家好,我是${this.color}的${this.name},我喜欢${this.sport}`)
        }
    }
    // 创建实例
    const dog1 = new HaShiQi('哈士奇','黑色','拆家');
    // 调用子类
    dog1.run();
    const dog2 = new KeJi('柯基','黄色','接飞碟'); 
    dog2.go();
    dog2.bark();

代码中,创建了Dog的父类,然后分别创建HaShiQi和KeJi类继承Dog类的属性和方法,创建了dog1和dog2两个实例,运行结果如下。

 

在这里先啰嗦一下,毕竟会有一些刚入门的小白对ES6的语法还不是很了解:

1.console.log()语句里面用到了“` `”模板字符串,它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量,类的属性通过${}来引入。

2.子类通过extends语句继承父类的属性和方法,通过super语句接收属性,方法直接调用即可。

原型

instanceof

我们平常判断变量的类型常常会用到typeof运算符,但是判断引用类型常常会返回object,不信?这里有图有真相!

所以我们接下来用到的instanceof 通过返回一个布尔值来表明,某个对象是否是某个特定类或者是该特定类的子类的一个实例。

第五行语句可能会有同学有疑问,为什么布尔值会是true?答案很简单,Object是所有类的祖先,上述类代码按照辈分来排列,应该是:Object---Dog---HaShiQi/KeJi ,所以instanceof就像DNA技术一样,来判断是否为某个类或者为某个类的父类(注意:instanceof只能用来判断引用类型)

prototype

在说明这玩意之前,我给大家先放一张图:

 我们称__proto__为隐式原型,prototype为显式原型,上述图片体现出,实例的隐式原型指向类的显式原型,原型这个概念对于初学者来说比较难懂,博主也是花了不少时间才搞懂它,先放一张思维导图给大家看看他们之间的关系。

 从图中我们可以看到,我们定义了一个对象HaShiQi,然后把对象的方法存储HaShiQi.prototype里面,通过new HaShiQi声明出dog1实例以后,属性name、color、hobby是存储在dog1实例里面,run()方法本身不在dog1实例里面,所以就需要通过__proto__隐式原型指向HaShiQi.prototype显式原型来获取的。

 敲黑板记笔记

1.每个class都有显式原型prototype

2.每个实例都有隐式原型__proto__

3.实例的__proto__指向class的prototype

4.执行规则先从自身寻找有没有该属性和方法,没有就去__proto__去寻找

原型链

有了这层知识以后,接下来给大家看看一张劲爆的图

 简单来说,就是HaShiQi类继承Dog类,Dog类继承Object类,Object.prototype提供js内置的方法hasOwnProperty,这个就是js调用机制的底层本质。

hasOwnProperty

该方法是js内置提供的方法,它用来判断该实例有没有这个属性,我们从控制台了解到,dog1拥有color这个属性,但是没有run()方法,怎么办呢?所以我们就要从隐式原型去寻找run()方法。

 

 同学们学废了吗?

 

 

 

以上是关于JavaScript原型和原型链(必考三座大三之一)的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript异步(必考三座大三之三)——第二集:event loop

前端面试送命题-JS三座大山

前端面试送命题-JS三座大山

理解JS的三座大山

如何理解JavaScript的原型和原型链

如何理解JavaScript的原型和原型链