JavaScript基石——原型链

前言

前几天面试了几家公司的实习岗位,发现自己原型链的相关知识比较薄弱,借此机会找了许多资料学习了一番,现在就原型链这块的知识谈谈自己的理解

原型

对于使用过基于类的语言的开发者来说,JavaScript 实在是有些令人困惑------JavaScript 是动态的且没有静态类型,它也并不是一个完全的面向对象语言。

那么js是如何实现继承的呢?我们知道对于js的复杂对象,本质上都是一种结构:object。ES6前的js没有class这个关键字,于是设计者采用构造函数的方式来实现继承。

ini 复制代码
// 构造函数
function Person(name, age) {
    this.name = name;
    this.age = age;
}

// 生成实例
const person = new Person('ccat', 20);

当我们创建了一个实例化对象后,新的问题出现了,我们实例对象上的this绑定的是实例对象本身,无法像基于类的语言那样实现extends关键字的继承。于是原型对象诞生了,挂载在每一个实例对象上,为它们提供共享的属性和方法。

我们在浏览器控制台中new一个实例对象看看:

可以看到,在person这个对象上挂载着一个Prototype的属性,这就是这个实例对象的原型 。其中就可以看到这个实例对象是由哪个构造函数创建出来的。也就是说,我们可以在实例对象上找到他的构造函数

原型链

知道了原型的概念以后,我们怎么在这个实例对象上调用所谓的共享方法呢?

我们再来一段示例代码:

javascript 复制代码
function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.say = function (word) {
  console.log(`${this.name}说:${word}`);
}

const person = new Person('ccat', 20);

person.hasOwnProperty('say'); 
person.say('hi');

在控制台中输入代码:

可以看到实例对象本身是没有say这个函数的,但是我们却可以在person上调用say这个函数。这就是原型链的作用,让我们能够调用对象原型上的函数。

每个函数都有一个prototype属性,这个prototype属性就是我们的原型对象,我们拿这个函数通过new构造函数创建出来的实例对象,这个实例对象自己会有一个指针( _ proto _ )指向他的构造函数的原型对象,他们的关系如下:

最后借用MDN官方文档的一句话总结一下:

当谈到继承时,JavaScript 只有一种结构:对象。每个对象(object)都有一个私有属性指向另一个名为原型 (prototype)的对象。原型对象也有一个自己的原型,层层向上直到一个对象的原型为 null。根据定义,null 没有原型,并作为这个原型链(prototype chain)中的最后一个环节。

我们可以new一个Object的实例对象,沿着原型链去查找它的尽头,就可以找到这个null了

另外还找到一个对于_proto_的补充

__proto__ 并不是语言本身的特性,这是各大厂商具体实现时添加的私有属性,虽然目前很多现代浏览器的 JS 引擎中都提供了这个私有属性,但依旧不建议在生产中使用该属性,避免对环境产生依赖。生产环境中,我们可以使用 Object.getPrototypeOf 方法来获取实例对象的原型,然后再来为原型添加方法/属性。(摘自阮一峰的ES6入门)

这段话提醒我们在修改实例对象原型时不要直接修改_proto_上的属性方法,这会改变其构造函数原型对象,从而被所有实例所共享

结语

本篇文章就原型和原型链的知识做了一定程度上的讲解,其中的许多内容我都从其他原型链相关好文、以及各个官方文档中获得了灵感,如果有不准确的地方,烦请各位大佬指正

相关推荐
小飞952711 分钟前
前端面试题总结-01
面试
鱼樱前端12 分钟前
重度Cursor用户 最强 Cursor Rules 和 Cursor 配置 mcp 以及最佳实践配置方式
前端
曼陀罗13 分钟前
Path<T> 、 keyof T 什么情况下用合适
前端
锈儿海老师19 分钟前
AST 工具大PK!Biome 的 GritQL 插件 vs. ast-grep,谁是你的菜?
前端·javascript·eslint
飞龙AI21 分钟前
鸿蒙Next实现瀑布流布局
前端
快起来别睡了22 分钟前
代理模式:送花风波
前端·javascript·架构
海底火旺24 分钟前
电影应用开发:从代码细节到用户体验优化
前端·css·html
陈随易33 分钟前
Gitea v1.24.0发布,自建github神器
前端·后端·程序员
前端付豪36 分钟前
汇丰银行技术架构揭秘:全球交易稳定背后的“微服务+容灾+零信任安全体系”
前端·后端·架构
邹荣乐38 分钟前
uni-app开发微信小程序的报错[渲染层错误]排查及解决
前端·微信小程序·uni-app