每日一个知识点:理解JavaScript 的原型和原型链

要理解 JavaScript 的原型和原型链,咱们用​​生活化的比喻​ ​+​​代码示例​​来拆解,保证你看完能拍着大腿说"原来这么简单!"

一、先想一个问题:对象为什么能"自带"方法?​​

比如,你创建一个空对象 const cat = {},但它却能调用 cat.toString()(输出 [object Object])。明明你没给 cat写过 toString方法,它哪来的?

​​答案:​​ 这些方法是从它的"原型"那里"继承"来的!

​​二、原型(Prototype):对象的"爸爸"​​

JavaScript 里的每个对象(除了 null),都有一个隐藏属性 __proto__(现代浏览器可直接访问),它指向另一个对象------​​原型对象​​(Prototype)。

原型对象就像对象的"爸爸",对象可以从"爸爸"那里​​继承属性和方法​​。

举个栗子:

arduino 复制代码
// 创建一个空对象
const cat = {};

// 查看 cat 的原型(爸爸)
console.log(cat.__proto__); 
// 输出:{ constructor: Object, ... } (即 Object.prototype)

cat的原型是 Object.prototype(所有对象的"祖宗"),所以 cat能继承 Object.prototype里的方法(比如 toString、hasOwnProperty)。

​​三、构造函数:批量生产对象的"工厂"​​

如果你想批量创建类似的对象(比如很多猫),可以用​​构造函数​​。

构造函数是专门用来"生产对象"的函数,它的 prototype属性(注意是大写的 P)就是它生产的所有对象的"原型"(爸爸)。

举个栗子:

javascript 复制代码
// 定义一个"猫"的构造函数
function Cat(name) {
  this.name = name; // 每个猫实例的私有属性
}

// 给 Cat 的原型(爸爸)添加一个方法(所有猫都能继承)
Cat.prototype.meow = function() {
  console.log(`${this.name}:喵喵~`);
};

// 生产猫实例
const tom = new Cat("Tom");
const luna = new Cat("Luna");

// tom 和 luna 都能调用 meow 方法(从原型继承的)
tom.meow(); // Tom:喵喵~
luna.meow(); // Luna:喵喵~

// 查看实例的原型(爸爸)
console.log(tom.__proto__ === Cat.prototype); // true!
console.log(luna.__proto__ === Cat.prototype); // true!
  • ​​关键点​ ​:所有通过 new Cat()生成的实例(tom、luna),它们的 __proto__都指向 Cat.prototype(构造函数的原型对象)。

  • ​​好处​ ​:不用给每个猫单独写 meow方法,只需要写在原型上,所有实例共享同一个方法,省内存!

四、原型链(Prototype Chain):找属性/方法的"寻亲链"​​

当你访问一个对象的属性或方法时(比如 tom.name或 tom.eat),JavaScript 会按以下顺序找:

  1. 先看对象自己有没有这个属性/方法(tom自己的 name)。

  2. 如果没有,就去它的原型(tom.__proto__,即 Cat.prototype)里找。

  3. 如果还没有,就去原型的原型(Cat.prototype.__proto__,即 Object.prototype)里找。

  4. 直到找到 null(所有链的终点),如果还没找到,就报错。

这条层层查找的"链条",就是​​原型链​​。

举个栗子:

javascript 复制代码
// 给 Object.prototype 加一个方法(所有对象都能继承)
Object.prototype.sayHi = function() {
  console.log("你好呀!");
};

const tom = new Cat("Tom");

// tom 自己没有 sayHi,但原型链能找到:
tom.sayHi(); // 你好呀!(来自 Object.prototype)

// 查看原型链关系:
console.log(tom.__proto__ === Cat.prototype); // true(爸爸)
console.log(Cat.prototype.__proto__ === Object.prototype); // true(爷爷)
console.log(Object.prototype.__proto__); // null(祖先)
  • ​原型链示意图​ :tom → Cat.prototype → Object.prototype → null

​​五、总结:原型和原型链的本质​​

  • ​​原型(Prototype)​ ​:对象的"爸爸",存储可被继承的属性和方法(通过 构造函数.prototype定义)。

  • ​​原型链(Prototype Chain)​ ​:对象找属性/方法时的"寻亲路径",通过 __proto__层层连接,直到 null。

  • ​​核心目的​ ​:实现对象的​​属性/方法共享​ ​,避免重复代码(比如所有对象都能用 toString)。

​​一句话记住:​​

原型是"爸爸",原型链是"家族族谱",对象找东西时,会顺着家族族谱往上翻,直到找到或翻到最顶头的空白页(null)。

明白了吗?同学,今天又进步了。加油,未来可期。

相关推荐
子兮曰4 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰4 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万4 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝4 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋4 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁4 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄4 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95274 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大4 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师4 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端