JavaScript中的原型与原型链

前言

本文将从几个代码示例来解释何为原型,何为原型链,如果你觉得本文对你有帮助的话,还望收藏,评论,点赞。🍠🍠🍠

一、🍣使用class实现继承

定义一个Student类

js 复制代码
class Student {
    //一个构造函数
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    introduce() {
        console.log(`你好我是${this.name},今年${this.age}`)
    }
}

const student = new Student("张三", 18)
student.introduce()

再定义一个Teacher类

js 复制代码
class Teacher {
    constructor(name, subject) {
        this.name = name;
        this.subject = subject;
    }

    teach() {
        console.log(`我是${this.name},我教${this.subject}`)
    }
}

注意:两个类都有一个相同的属性name,此时就可以用到继承来进行代码的复用

此处定义了一个Person类,其中有一个name属性,而Student类和Teacher类继承了Person类,也就是子对象获取了父对象的属性和方法。

graph TB Person-->Student Person-->Teacher
js 复制代码
class Person{
    constructor(name) {
        this.name=name
    }

    drink(){
        console.log(`${this.name}在喝水`)
    }
}

class Student extends Person{
    constructor(name, age) {
        super(name);
        this.age = age;
    }
    introduce() {
        console.log(`你好我是${this.name},今年${this.age}`)
    }
}


class Teacher extends Person{
    constructor(name, subject) {
        super(name);
        this.subject = subject;
    }

    teach() {
        console.log(`我是${this.name},我教${this.subject}`)
    }
}

const student = new Student("张三", 18)
student.introduce()
const teacher = new Teacher("李四", "js");
teacher.teach()
student.drink()
teacher.drink()

执行效果

二、🍙原型(Prototype)

原型(Prototype)是每个函数都有一个的属性,这个属性指向函数的原型对象,它被用来实现基于原型的继承。

先打印一下student这个对象

Prototype和__proto__:两者都是Object.prototype的别名,JavaScript 1.8.5之后的版本已经将__proto__属性标记为过时,建议使用prototype属性代替。

隐式原型可以通过,student.__proto__进行访问

显示原型可以通过,Student.prototype进行访问

由此可见,student.__proto__与Student.prototype指向了同一对象

一个对象的隐式原型,会指向构建出实例的类的显式原型

graph LR 对象的隐式原型-->类的显式原型

当我们在一个对象上尝试查找一个属性或者方法时,如果找不到对应的属性或者方法,就会前往隐式原型上寻找

三、🍜原型链(Prototype Chain)

创建一个Person类,一个Teacher类,然后让Teacher继承Person类,再实例化一个teacher对象,并调用teach()方法和drink()方法。

注意:Teacher类中并没有drink方法,同时注意其中的Object原型,下文会展示完整的原型链

js 复制代码
    class Person {
        constructor(name) {
            this.name = name
        }

        drink() {
            console.log("喝水")
        }
    }
    class Teacher extends Person {
        constructor(name, subject) {
            super(name);
            this.subject = subject;
        }

        teach() {
            console.log(`我是${this.name},我教${this.subject}`)
        }
    }
    const teacher = new Teacher("李四", "js");
    teacher.teach()
    teacher.drink()

当我们访问一个对象的属性或者方法时,首先会从自身去找对应的属性或者方法,如果没有找到,就会去其指向的原型上去找,如果其指向的原型没有找到,那么就会去其原型的原型上去找,这样就形成了一条链式的结构,所以,我们将其称之为原型链。

检查一个属性或者方法是否是自身所拥有的

通过hasOwnProperty可以检验一个属性或者方法是否属于对象本身,其中,name属性属于teacher对象,而teach方法则不属于

js 复制代码
const teacher = new Teacher("李四", "js");
console.log(teacher.hasOwnProperty("name"))
console.log(teacher.hasOwnProperty("teach"))

那么hasOwnProperty()方法又是哪儿来的呢?

完整的原型链:

其中hasOwnPrototype方法便是来自Object原型

四、🍟使用instanceof作类型判断

使用之前的代码,运行,并在浏览器打开控制台

js 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    class Person {
        constructor(name) {
            this.name = name
        }

        drink() {
            console.log("喝水")
        }
    }
    class Teacher extends Person {
        constructor(name, subject) {
            super(name);
            this.subject = subject;
        }

        teach() {
            console.log(`我是${this.name},我教${this.subject}`)
        }
    }
    const teacher = new Teacher("李四", "js");

</script>
</body>
</html>

其中,Teacher,Person,Object都是存在于一条原型链上,而Array不存在于这条原型链上,所有作类型判断时为false

判断一个数组

定义一个数组[],然后展开可见其原型为Array

再使用instanceof进行判断

对象也是同理,其原型为Object,在使用instanceof进行判断时为true

注意:我们日常说js中万物皆为对象的原因时,所有数据的原型都是Object

总结

理解原型和原型链是掌握JavaScript面向对象编程的关键。通过原型链,子类可以继承父类的属性和方法,同时也能够拥有自己的属性和方法。在实际开发中,我们可以利用原型链实现代码的复用和扩展。同时,由于JavaScript的对象都是通过原型链进行属性查找的,因此优化原型链的查找效率对于提高代码的性能也具有重要意义。

相关推荐
therese_1008631 分钟前
面试试试试试试题-答
面试
czhc11400756631 小时前
c# 1121 构造方法
java·javascript·c#
GISer_Jing3 小时前
3D Cesium渲染架剖析
javascript·3d·webgl
han_3 小时前
前端性能优化之CSS篇
前端·javascript·性能优化
z***I3944 小时前
JavaScript爬虫应用案例
开发语言·javascript·爬虫
清风徐来QCQ5 小时前
javaScript(map,ref,?,forEach,watch)
java·前端·javascript
前端布鲁伊5 小时前
再来聊聊,Vue3 项目中 Pinia 的替代方案
前端·面试
星月前端5 小时前
[特殊字符]面向 ArcGIS for JavaScript(4.x)开发者的「坐标系统(CRS / 投影)」全面解读
开发语言·javascript·arcgis
好学且牛逼的马5 小时前
【MyBatis-Plus | 常见问题与面试重点】
面试·mybatis
星空的资源小屋5 小时前
永久删除文件利器:Permadelete
java·javascript·人工智能