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

相关推荐
Σίσυφος19009 小时前
C++ 多肽经典面试题
开发语言·c++·面试
终端鹿9 小时前
Vue3 模板引用 (ref):操作 DOM 与子组件实例 从入门到精通
前端·javascript·vue.js
软件测试媛9 小时前
2026软件测试面试题大全(含答案+文档)
功能测试·测试工具·面试·ai软件测试
蜡台10 小时前
Vue 打包优化
前端·javascript·vue.js·vite·vue-cli
卷帘依旧11 小时前
JavaScript中this绑定问题详解
前端·javascript
NAGNIP12 小时前
一文搞懂CNN经典架构-DenseNet!
算法·面试
花间相见12 小时前
【MySQL面试题】—— MySQL面试高频问题汇总:从原理到实战,覆盖90%考点
数据库·mysql·面试
yaaakaaang12 小时前
(八)前端,如此简单!---五组结构
前端·javascript
野生技术架构师12 小时前
1000道互联网大厂Java岗面试原题解析(八股原理+场景题)
java·开发语言·面试
YuanDaima204812 小时前
[CrewAI] 第15课|构建一个多代理系统来实现自动化简历定制和面试准备
人工智能·python·面试·agent·crewai