JS原型和原型链详解

文章详细解释了JavaScript中的原型概念,包括构造函数的作用、原型对象的特性以及如何通过prototype属性共享方法。还探讨了constructor属性,指出其用于指向原型对象的构造函数,并讨论了实例对象如何通过原型链访问属性和方法。最后,概述了原型链的查找规则和结构,强调了对象成员查找机制的重要性。
摘要由CSDN通过智能技术生成

1、原型

1.1 什么是原型

原型是Javascript中的继承的基础,JavaScript的继承就是基于原型的继承。

说到原型会涉及两个概念:构造函数、原型对象。

1.2 构造函数

 		function Star() {

            //我就是构造函数

        }
        // new一下调用
        new Star()

封装是面向对象思想中比较重要的一部分,js面向对象可以通过构造函数实现的封装。

构造函数方法很好用,但是 存在浪费内存的问题,所以为了解决这个问题,官方提出了原型的概念。

1.3 原型对象

JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象,所以我们也称为原型对象。

这个对象可以挂载函数,对象实例化不会多次创建原型上函数,节约内存。

所以我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可以共享这些方法。

        function Star(name, age) {
            this.name = name
            this.age = age
        }
        console.log(Star.prototype);//返回一个对象称为原型对象
        Star.prototype.sing = function () {
            console.log('我会唱跳rap');
        }//创建一个共同的方法
        console.log(new Star());

在这里插入图片描述

我们来new两个对象,看看它们的方法是不是相等,如果是true说明方法是共享的。

        const cxk = new Star('蔡', 18)
        const zxy = new Star('张学友', 18)
        console.log(cxk.sing() === zxy.sing());

在这里插入图片描述

1.4 构造函数和原型里面的this指向谁 ?

构造函数和原型对象中的this都指向实例化的对象

我们来看两段示例体会一下:

		let that;//声明一个that来接受构造函数里面的this
        function Person(name) {
            this.name = name
            that = this
        }
        const o = new Person()
        console.log(that === o);//true

在这里插入图片描述

		let that;
        function Person(name) {
            this.name = name
        }
        Person.prototype.sing = function() {
            that = this
        }
        const o = new Person()
        o.sing()
        console.log(that === o);//true

在这里插入图片描述

2、 constructor属性

2.1 在哪里?

每个原型对象里面都有个constructor 属性(constructor 构造函数)

 		function Person(name) {
            this.name = name
        }
        Person.prototype.sing = function() {
        }
        console.log(Person.prototype);

在这里插入图片描述

2.2 作用

该属性指向该原型对象的构造函数, 简单理解,就是指向我的妈妈,我是有妈妈的孩子。
在这里插入图片描述

2.3 使用场景

如果有多个对象的方法,我们可以给原型对象采取对象形式赋值。

但是这样就会覆盖构造函数原型对象原来的内容,这样修改后的原型对象 constructor 就不再指向当前构造函数了。

此时,我们可以在修改后的原型对象中,添加一个 constructor 指向原来的构造函数。

		function Person(name) {
            this.name = name
        }
        Person.prototype = {
            sing: function() {
                console.log('我会唱跳rap');
            },
            eat: function() {
                console.log('我特能吃');
            }
        }
        console.log(Person.prototype.constructor);

在这里插入图片描述

		function Person(name) {
            this.name = name
        }
        Person.prototype = {
            constructor: Person,
            sing: function () {
                console.log('我会唱跳rap');
            },
            eat: function () {
                console.log('我特能吃');
            }
        }
        console.log(Person.prototype.constructor);

在这里插入图片描述

3、为什么实例对象能够访问原型对象里面的属性和方法?

对象都会有一个属性 proto 指向构造函数的 prototype 原型对象,之所以我们对象可以使用构造函数 prototype 原型对象的属性和方法,就是因为对象有 proto 原型的存在。

对象原型__proto__指向原型对象 prototype

在这里插入图片描述

在每一个prototype原型和对象原型__proto__里面都有constructor属性,constructor都指向创建实例对象/原型的构造函数。

简单理解,就是实例对象或者原型对着你说:’‘你看这是我妈妈“,而构造函数对着你说:”你看这都是我的孩子“。
互相指明它们之间的关系。

4、 原型链

基于原型对象的继承使得不同构造函数的原型对象关联在一起,并且这种关联的关系是一种链状的结构,我们将原型对象的链状结构关系称为原型链。

4.1 原型链-查找规则

  1. 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
  2. 如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)
  3. 如果还没有就查找原型对象的原型(Object的原型对象)
  4. 依此类推一直找到 Object 为止(null)
  5. __proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线
  6. 可以使用 instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

4.2 原型链结构图

在这里插入图片描述

4.3 概括

所有的JS对象都有一个prototype属性,指向它的原型对象。当试图访问一个对象的属性时,如果没有在该对象找到,它还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

东方青云、

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

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

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

打赏作者

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

抵扣说明:

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

余额充值