三张图轻松KO⚡ JS 原型和原型链

简介: 三张图轻松KO⚡ JS 原型和原型链

image.png

📢 大家好,我是小丞同学,这一篇是 JS 高程精读系列的第 n 篇文章,主要解释 JS 中的原型和原型链


📢 非常感谢你的阅读,不对的地方欢迎指正 🙏


📢 愿你生活明朗,万物可爱


引言

原型和原型链据说是面试常考的东西(没面试过,不大清楚),对于初学者来说有一定的难度,但是其实它也非常的简单,几个概念理解好了就没什么问题了,我们先从一个例子出发,然后再引出相关的知识点,下面我们先来看一个例子


先定义一个类,添加一些属性和方法

class Student {
    constructor(name, score) {
        this.name = name
        this.score = score
    }
    say() {
        console.log(`我是${this.name}考了${this.score}`);
    }
}

然后我们 new 一个实例对象出来

const student = new Student('小丞同学', 99)

接着我们想要输出一下这个学生的姓名和成绩

console.log(student.name, student.score);

很顺利,控制台输出 小丞同学 99 ,接下来我们想要调用一下 say 方法

student.say()

成功输出image.png

没什么问题,很完美,接下来我们来打印一下实例化出来的对象 student

console.log(student)

我们看一下控制台输出

image.png

咦,我们发现在这个 student 对象上只有两个属性 name 和 score ,那我刚刚调用的 say 方法是哪里来的呢?  当我们展开 __proto__ 时就会发现,我们的 say 方法在其中,那这其实是因为我们在类中添加的方法,会被添加到这个类的原型对象上

image.png

当我们在调用 say 方法时,在自身上并没有找到这个方法,就会在自身的 __proto__ 上去找,而这个 __proto__ 也叫做隐式原型


接下来我们再看一个有意思的事情


我们说 student 这个实例对象是由这个大写的类 Student 来创建的,那么我们打印一下这个类,来看一下

console.log(Student)

打印出来就是一个类

image.png

而在这个类上会有一个方法 prototype ,我们来打印一下看看它是什么

console.log(Student.prototype)

image.png

我们会发现在它的上面也有一个 say 方法,同时是不是觉得这个又点眼熟呢  我们在控制台打印一下实例对象的隐式原型

console.log(student.__proto__)

image.png

你会发现它们两个尽然长的是一样的,我们可以比对一下,看看它们是不是完全相等的

image.png

可以看到,它们两个指向的是同一个对象,那么通过上面的一步步推理,我们可以得到这样一张图

image.png

那到底什么是原型呢?


原型

原型又分为显式原型和隐式原型


__proto__ 隐式原型

在对象上有一个属性叫做 __proto__,这个属性是对象所特有的,也叫做隐式原型,当我们尝试在一个对象上查找属性或者方法时,如果说找不到这个属性或者方法,就会在它的隐式原型上查找


prototype 显式原型

prototype 是函数所特有的属性,它是从一个函数指向一个对象,它的含义是函数的原型对象。


它的作用是什么呢?


它的作用就是包含所有实例对象共享的属性和方法,这也就是为了让该函数所实例化的对象们都可以找到公共的属性和方法


特别注意的是,任何函数在创建的时候,都会默认创建该函数的 prototype 对象


constructor 构造函数

在前面没有提这个属性,就是怕指向太多容易混乱


其实在对象上除了具有 __proto__ 属性外,还有一个 constructor 属性,这一点在我们打印对象的时候也能够注意到,那它是干什么的呢?


我们在控制台上输出对象本身、隐式原型、constructor 三个结果

console.log(student)
console.log(student.__proto__)
console.log(student.constructor)

image.png

我们可以发现 constructor 属性的值是创建 student 的类,也就是构造函数


这也就是 constructor 的含义,它指向该对象的构造函数,它的作用就是用来保存自己的构造函数引用


需要特别注意的是,所有的 constructor 属性的终点都是 Function


这是因为 Function 既可以看成是一个函数,也可以是对象,所有的函数和对象都是由 Function 构造函数而来


image.png

image.png

修改了构造函数的原型对象,constructor指向谁  functionName.prototype = {}  原型对象、实例对象、构造函数之间的关系 一张图搞定,前面的内容懂了,自己推一下

image.png

原型链

原型链其实也很简单:对象 => 对象的原型 => 原型的原型 => 原型的原型的原型 => null,这就是原型链


那这是什么意思呢,在我们前面在讲查找原则的时候,其实也有提到,当一个要查找对象上的属性或者方法时,如果在自身上没有找到,就会在隐式原型对象下查找,直到找到,或者到达尽头 null


在这个查找的过程形成的一条由 __proto__ 连接而成的链就是原型链


image.pngimage.png

image.png

总结

__proto__ 和 constructor 属性是对象所特有的

prototype 属性是函数特有的

__proto__ 的作用是作为桥梁提供一种成员访问机制,不停的通过 __proto__ 去查找

prototype 的作用是让函数所实例化的对象拥有公共的属性和方法

constructor 属性的含义是指向对象的构造函数

修改构造函数的原型对象,需要手动调整 constructor


相关文章
|
1月前
|
JavaScript 前端开发
如何在JavaScript中实现基于原型的继承机制
【8月更文挑战第14天】如何在JavaScript中实现基于原型的继承机制
24 0
|
17天前
|
JavaScript 前端开发
JavaScript基础知识-原型(prototype)
关于JavaScript基础知识中原型(prototype)概念的介绍。
24 1
|
1月前
|
JavaScript 前端开发
JavaScript中什么是原型?有什么用?
JavaScript中什么是原型?有什么用?
13 1
|
1月前
|
JavaScript 前端开发 Java
什么是JavaScript原型对象
【8月更文挑战第2天】什么是JavaScript原型对象
49 9
|
20天前
|
开发者 图形学 iOS开发
掌握Unity的跨平台部署与发布秘籍,让你的游戏作品在多个平台上大放异彩——从基础设置到高级优化,深入解析一站式游戏开发解决方案的每一个细节,带你领略高效发布流程的魅力所在
【8月更文挑战第31天】跨平台游戏开发是当今游戏产业的热点,尤其在移动设备普及的背景下更为重要。作为领先的游戏开发引擎,Unity以其卓越的跨平台支持能力脱颖而出,能够将游戏轻松部署至iOS、Android、PC、Mac、Web及游戏主机等多个平台。本文通过杂文形式探讨Unity在各平台的部署与发布策略,并提供具体实例,涵盖项目设置、性能优化、打包流程及发布前准备等关键环节,助力开发者充分利用Unity的强大功能,实现多平台游戏开发。
44 0
|
28天前
|
JavaScript 前端开发 开发者
揭开JavaScript的神秘面纱:原型链背后隐藏的继承秘密
【8月更文挑战第23天】原型链是JavaScript面向对象编程的核心特性,它使对象能继承另一个对象的属性和方法。每个对象内部都有一个[[Prototype]]属性指向其原型对象,形成链式结构。访问对象属性时,若当前对象不存在该属性,则沿原型链向上查找。
23 0
|
3月前
|
设计模式 JavaScript 前端开发
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
JavaScript的继承机制基于原型链,它定义了对象属性和方法的查找规则。每个对象都有一个原型,通过原型链,对象能访问到构造函数原型上的方法。例如`Animal.prototype`上的`speak`方法可被`Animal`实例访问。原型链的尽头是`Object.prototype`,其`[[Prototype]]`为`null`。继承方式包括原型链继承(通过`Object.create`)、构造函数继承(使用`call`或`apply`)和组合继承(结合两者)。ES6的`class`语法是语法糖,但底层仍基于原型。继承选择应根据需求,理解原型链原理对JavaScript面向对象编程至关重要
76 7
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
|
1月前
|
设计模式 JavaScript 前端开发
js对原型和继承的理解
了解JavaScript中原型和继承的概念对于编写优雅高效的代码、理解库和框架的内部机制以及执行高级设计模式都有着重要的意义。
36 0
|
1月前
|
JavaScript 前端开发
详细讲解!JavaScript原型 !
详细讲解!JavaScript原型 !
|
3月前
|
JavaScript
js奥义:原型与原型链(1)
js奥义:原型与原型链(1)