小白也能懂:JavaScript 原型链和隐藏类的奇妙世界

小白也能懂:JavaScript 原型链和隐藏类的奇妙世界

大家好!今天我们来聊聊 JavaScript 里两个听起来高大上但其实很简单的概念:原型链隐藏类。别被名字吓到,我会用最生活化的方式解释给你听!


一、原型链:JavaScript 的"家族族谱" 🧬

想象你有一个玩具箱(对象),你想找某个玩具(属性):

javascript 复制代码
const myToyBox = {
  car: "红色小汽车", // 自己的玩具
};

当你直接找 myToyBox.car,立刻就能找到。但如果想找一个不存在的玩具呢?

javascript 复制代码
console.log(myToyBox.robot); // 自己箱子里没有!

这时 JavaScript 会去"爸爸的玩具箱"里找 → 这就是原型链

javascript 复制代码
// 爸爸的玩具箱
const dadsToyBox = {
  robot: "变形金刚"
};

// 设置爸爸的箱子为你的原型
Object.setPrototypeOf(myToyBox, dadsToyBox);

console.log(myToyBox.robot); // ✅ 找到了变形金刚!

查找过程就像寻宝游戏

  1. 先翻自己的箱子(对象自身)
  2. 找不到就去爸爸的箱子(原型对象)
  3. 还找不到就去爷爷的箱子(原型的原型)
  4. 直到找到或家族尽头(null)

(示意图:对象 → 原型 → 原型的原型 → null)

🔑 关键点 :当你用 对象.属性 时,JavaScript 会沿着这条"家族链"层层查找!


二、原型链是链表吗?底层揭秘 🔍

很多教程说原型链像"链表",对也不对

  • 行为像链表:通过指针连接,顺序查找
  • 实现非链表:引擎用更高级方式优化

看个底层伪代码(V8引擎简化版):

cpp 复制代码
// 当访问 obj.property 时
Object* current = obj;
while (current != null) {
  if (current->HasProperty("property")) {
    return value; // 找到就返回
  }
  current = current->prototype; // 跳转到下一个原型
}
return undefined; // 找不到

就像你按地址串门找人:

javascript 复制代码
你家(对象)→ 爸爸家(原型)→ 爷爷家(Object.prototype)→ 终点(null)

三、隐藏类:引擎的"超强记忆术" 🧠

如果每次查属性都要遍历整条链,岂不慢死?别怕!JavaScript 引擎有个秘密武器------隐藏类

什么是隐藏类?

想象你去学校图书馆:

  • 无隐藏类:每次借书都从头找书名(超慢!)
  • 有隐藏类:管理员记住"科幻区第3书架"(直接拿书)

代码示例

javascript 复制代码
// 创建两个相同结构的对象
const obj1 = {};
obj1.name = "小明"; // 触发隐藏类 C1
obj1.age = 12;     // 转换到隐藏类 C2

const obj2 = {};
obj2.name = "小红"; // 同样触发 C1 → C2 转换

这时引擎会:

  1. {name, age} 结构创建共享的隐藏类
  2. 记录 nameage 在内存中的固定位置
  3. 后续访问时直接跳转地址(比查字典快10倍!)

什么时候会"失忆"?

javascript 复制代码
// ❌ 错误示范:打乱属性顺序
const obj3 = {};
obj3.age = 12;     // 创建新隐藏类 C3
obj3.name = "小刚"; // 转换到 C4(与 obj1/obj2 不同!)

📝 最佳实践

✅ 按固定顺序初始化属性

✅ 尽量在构造函数中赋值

❌ 避免动态增删属性


总结:三句话掌握精髓 💡

  1. 原型链是 JS 的属性查找机制------像家族寻亲,层层向上找
  2. 点操作符(.) 触发原型链遍历------从自己到原型链尽头
  3. 隐藏类是引擎的优化术------用固定内存布局加速访问

下次看到 obj.property,你就知道背后有一段精彩的"寻亲之旅"啦!建议写个简单例子体验一下,代码是最好的老师哦~

javascript 复制代码
// 动手实验!
const grandpa = { hobby: "钓鱼" };
const father = { job: "工程师" };
Object.setPrototypeOf(father, grandpa);

const me = {};
Object.setPrototypeOf(me, father);

console.log(me.hobby); // 试试输出什么?
相关推荐
江城开朗的豌豆18 分钟前
JavaScript篇:函数间的悄悄话:callee和caller的那些事儿
javascript·面试
江城开朗的豌豆34 分钟前
JavaScript篇:回调地狱退散!6年老前端教你写出优雅异步代码
前端·javascript·面试
TE-茶叶蛋1 小时前
Vue Fragment vs React Fragment
javascript·vue.js·react.js
Carlos_sam2 小时前
Opnelayers:封装Popup
前端·javascript
MessiGo3 小时前
Javascript 编程基础(5)面向对象 | 5.1、构造函数实例化对象
开发语言·javascript·原型模式
前端小白从0开始3 小时前
Vue3项目实现WPS文件预览和内容回填功能
前端·javascript·vue.js·html5·wps·文档回填·文档在线预览
JohnYan3 小时前
Bun技术评估 - 03 HTTP Server
javascript·后端·bun
开开心心就好4 小时前
高效Excel合并拆分软件
开发语言·javascript·c#·ocr·排序算法·excel·最小二乘法
特立独行的猫a4 小时前
Nuxt.js 中的路由配置详解
开发语言·前端·javascript·路由·nuxt·nuxtjs