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的对象都是通过原型链进行属性查找的,因此优化原型链的查找效率对于提高代码的性能也具有重要意义。

相关推荐
博客zhu虎康8 分钟前
ElementUI 的 form 表单校验
前端·javascript·elementui
贵州晓智信息科技42 分钟前
如何优化求职简历从模板选择到面试准备
面试·职场和发展
CodeClimb1 小时前
【华为OD-E卷-木板 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
咸鱼翻面儿1 小时前
Javascript异步,这次我真弄懂了!!!
javascript
qq_589568101 小时前
Echarts的高级使用,动画,交互api
前端·javascript·echarts
暴富的Tdy3 小时前
【CryptoJS库AES加密】
前端·javascript·vue.js
℘团子এ3 小时前
js和html中,将Excel文件渲染在页面上
javascript·html·excel
胡西风_foxww5 小时前
【es6复习笔记】Promise对象详解(12)
javascript·笔记·es6·promise·异步·回调·地狱
秃头女孩y5 小时前
【React中最优雅的异步请求】
javascript·vue.js·react.js