小白也能懂: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. 记录 name 和 age 在内存中的固定位置
  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); // 试试输出什么?
相关推荐
liyi_hz20082 分钟前
O2OA(翱途) V10.1 即将发布|功能再升级,安全再加固,协同更高效!
java·javascript·windows·开源软件
志尊宝1 小时前
AI原生前端开发(029):AI辅助的文档自动生成
javascript·人工智能·ai-native
一个游离的指针2 小时前
ES6新特性:let、const、块级作用域
开发语言·javascript·es6
Hilaku2 小时前
删了一个没用的 console.log,生产环境直接崩了!
前端·javascript·程序员
真上帝的左手2 小时前
2. 编程语言-JavaScript
开发语言·javascript
2601_949847753 小时前
Form-data 跨端三方库仓颉适配全流程
前端·javascript·flutter
zyseo83 小时前
谷歌SEO 内容更新焕新流程:让老页面重新起量
java·前端·javascript
Oiiouui3 小时前
关于 Logto 登录系统的体验以及建议
javascript·安全·react
richdata3 小时前
从采购承诺到库存周转:降低库存资金占用的六个计划杠杆
大数据·前端·javascript
志尊宝5 小时前
AI原生前端开发(031):AI辅助的性能分析与瓶颈定位
javascript·人工智能·ai-native