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_上的属性方法,这会改变其构造函数的原型对象,从而被所有实例所共享

结语

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

相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
晨米酱3 天前
AGENTS.md:Agent 的上下文策略层
面试·架构·agent
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
彧azz3 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端