一篇文章弄懂JS中的原型和原型链

本文详细解释了JavaScript中原型的概念,包括函数与对象如何访问原型,以及实例化对象的构造过程。通过具体示例展示了原型链的工作原理,并讨论了如何通过修改原型来扩展对象的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是原型?

🟢 每一个函数都有一个原型(是一个空间,或者是一个对象,内部能存储一些东西),原型内部都有一个constructor,这个属性表明当前这个原型具体是哪个函数的

函数访问原型的方法 : 函数.prototype

🟢 每一个对象都有一个__proto__ (注意:proto两边分别是两个下划线),可以去访问到自己构造函数的原型

🟢 实例化对象,本质上也是一个函数,所以它也可以访问到自己的构造函数对象访问原型的方法

对象访问原型的方法 : 对象.__proto__

🟢对象的访问规则,先在当前作用域(就是对象内部)查找,找到就使用;如果没有找到,则会顺着__proto__向上查找

<script>

    function Person(name, age) {
            this.name = name
            this.age = age
        }
        Person.prototype.a = '我是后续通过 JS 代码添加到函数的原型内部的属性'
        Person.prototype.sayHi = () => {
            console.log('你好')
        }


        console.log(Person.prototype)   // 打印函数 Person 的原型


        const p1 = new Person('AA001', 18)
        const p2 = new Person('AA002', 28)
        
        p1.sayHi()
        console.log(p1.a)

        console.log(p1.__proto__)   // 打印对象的构造函数的原型
        
        console.log(p1.sayHi)
        console.log(p2.sayHi)
        console.log(p1.sayHi == p2.sayHi)

</script>

❗❗❗  注意点 : 构造函数的函数体内,通常写属性;构造函数的原型内, 通常写方法(函数)

构造函数的原型内部添加方法, 并不是为了给构造函数使用,通常是为了给实例化对象使用

<script>

    function Person(name) {
            this.name = name
        }
        Person.prototype.sayHi = () => {
            console.log(111)
        }
        const p = new Person('AA666')
        p.sayHi()

        const arr = new Array()  //数组构造函数
        const obj = new Object()  //对象构造函数
        const reg = new RegExp()  //正则构造函数
        const date = new Date()  //时间构造函数

        console.log(arr) 
        console.log(obj) 
        console.log(reg)  
        console.log(date)  

</script>

🍀上诉打印结果为:

 ❗❗❗  记住,任何一个数组的构造函数都是Array;任何一个对象的构造函数都是Object;任何一个函数的构造函数都是Function

案例分析

🍀举一个小例子:

需求: 给数组扩展一个求最大值的方法

<script>

  Array.prototype.getMax = function () {
            let max = this[0]
            for (let i = 1; i < this.length; i++) {
                if (max < this[i]) {
                    max = this[i]
                }
            }
            return max
        }
        const arr1 = new Array(1, 2, 100, 5, 3, 4)
        const max = arr1.getMax()
        console.log(max)


        const arr2 = new Array(1, 2, 100, 5, 3, 4, 999)
        const max2 = arr2.getMax()
        console.log(max2)

</script>

🍀打印结果:

原型链

含义:查找对象的某一个属性:

🍀先在对象内部开始查找, 找到直接使用, 然后停止查找

🍀如果没有找到, 会去对象的__proto__查找, 如果找到直接使用, 然后停止查找

🍀如果这里没找到, 会继续去对象的 __proto__ 查找, 找到直接使用, 然后停止查找

🍀如果还是没找到, 会继续向上查找

🍀...

🍀直到找到顶层作用对象    Object.prototype, 找到就用, 找不到就返回一个 undefined

案例分析

🍀举一个小例子:

✏️ 问题1: p 的 __proto__ 指向谁?

✏️ 问题2: Person 的 __proto__ 指向谁?

✏️ 问题3: Person.prototype 的 __proto__ 指向谁?

✏️ 问题4: Function 的 __proto__ 指向谁?

✏️ 问题5: Function.prototype 的 __proto__ 指向了谁?

✏️ 问题6: Object 的 __proto__ 指向了谁?

✏️ 问题7: Object.prototype 的 __proto__ 指向了谁?

<script>

   function Person (name) {
            this.name = name
        }
        Person.prototype.sayHi = function () {
            console.log(100)
        }
        const p = new Person('QF001')

        console.log(p.__proto__ === Person.prototype)
        console.log(Person.__proto__ === Function.prototype)
        console.log(Person.prototype.__proto__ === Object.prototype)
        console.log(Function.__proto__ === Function.prototype)
        console.log(Function.prototype.__proto__ === Object.prototype)
        console.log(Object.__proto__ === Function.prototype)
        console.log(Object.prototype.__proto__)

</script>
<script>

         *   问题1: p 的 __proto__ 指向谁?
         *      + p 是 Person 的实例化对象
         *      + __proto__ 指向自身构造函数的原型
         *      + p.__proto === Person.prototype

 
         *  问题2: Person 的 __proto__ 指向谁?
         *      + Person 是构造函数, 本质上函数
         *      + 只要是一个函数, 他就是 Function 的实例
         *      + Person.__proto__ 指向了 他的构造函数的原型, 构造函数是 Function, 那么构造函数的 原型 Function.prototype
         *      + Person.__proto__ === Function.prototype


         *  问题3: Person.prototype 的 __proto__ 指向谁?
         *      + Person.prototype 其实就是  构造函数 Person 的原型对象, 本质上就是对象
         *      + 只要是一个 对象, 他就是 Object 的实例
         *      + Person.prototype.__proto__ 指向了 他的构造函数的原型, 构造函数 Object, 那么构造函数的原型 Object.prototype


         *  问题4: Function 的 __proto__ 指向谁?
         *      + Function 是构造函数, 本质上就是一个函数
         *      + 只要是一个函数, 他就是 Function 的实例
         *      + Function.__proto__ 指向了 他的构造函数的原型, 构造函数 Function, 那么 构造函数的原型 Function.prototype
         *      + Function.__proto__ === Function.prototype


         *  问题5: Function.prototype 的 __proto__ 指向了谁?
         *      + Function.prototype 其实就是 构造函数 Function 的原型对象, 本质上是对象
         *      + 只要是一个对象, 他就是 Object 的实例
         *      + Function.prototype.__proto__ 指向了 他的构造函数的原型, 构造函数 Object, 那么构造函数的原型 Object.prototype
         *      + Function.prototype.__proto__ === Object.prototype


         *  问题6: Object 的 __proto__ 指向了谁?
         *      + Object 是一个构造函数, 本质上还是一个函数
         *      + 只要是一个函数, 那么他的构造函数 就是 Function
         *      + Object.__proto__ 指向了他的构造函数的原型, 他的构造函数是 Function, 那么构造函数的原型 Function.prototype
         *      + Object.__proto__ === Function.prototype


         *  问题7: Object.prototype 的 __proto__ 指向了谁?
         *      + Object.prototype 是构造函数 Object 的原型对象, 本质上就是一个对象
         *      + 但是重点: Object.prototype 是 JS 顶层的对象
         *      + Object.prototype.__proto__ === null

</script>

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兰de宝贝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值