登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
导读
排行榜
资讯
发帖说明
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
写博客
小组
VIP申请
VIP网盘
网盘
联系我们
发帖说明
道具
勋章
任务
淘帖
动态
分享
留言板
导读
设置
我的收藏
退出
腾讯QQ
微信登录
1
2
/ 2 页
下一页
返回列表
首页
›
业界区
›
业界
›
一文搞清楚什么是JavaScript prototype原型链 ...
一文搞清楚什么是JavaScript prototype原型链
[ 复制链接 ]
甘子萱
2025-6-6 09:54:42
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
JavaScript prototype 详解
JavaScript 中,
prototype(原型)
是面向对象编程的核心概念之一。它通过
原型链(Prototype Chain)
实现继承,使对象可以共享其他对象的属性和方法。理解原型机制是掌握 JavaScript 面向对象编程的关键。
什么是 prototype?
每个 JavaScript
函数
(构造函数)都有一个 prototype 属性,它是一个对象。所有由该函数创建的
实例对象
都会继承这个原型对象的属性和方法。
function Person(name) {
this.name = name;
}
// 方法添加到原型,所有实例共享
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}`);
};
const p1 = new Person("Joe");
const p2 = new Person("Mary");
p1.sayHello(); // Hello, my name is Joe
p2.sayHello(); // Hello, my name is Mary
// 实例的 __proto__ 指向构造函数的 prototype
console.log(p1.__proto__ === Person.prototype); // true
复制代码
在上面的代码中:
Person.prototype 是 Person 构造函数的原型对象。
sayHello 方法被所有 Person 的实例共享,而不是每个实例都创建一份新的拷贝,节省内存。
p1.__proto__ 指向 Person.prototype,表示 p1 继承了 Person.prototype 上的方法。
__proto__ 是实例对象的隐式原型引用(非标准属性,可以用 Object.getPrototypeOf() 替代)。
属性__proto__ 与 prototype 关系
JavaScript 中每个对象都有一个隐藏的 __proto__ 属性(这个并非标准属性,虽然大部分浏览器都支持),它指向创建该对象的构造函数的 prototype:
console.log(p1.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true
复制代码
这个原型链的结构如下:
// 访问对象属性时,若当前对象没有,则沿原型链向上查找。
// Object.prototype 是原型链的终点,其 __proto__ 为 null。
p1 → Person.prototype → Object.prototype → null
复制代码
原型链继承
可以通过 prototype 让一个构造函数继承另一个构造函数的方法和属性。
注意,使用 Object.create 创建的子对象不会调用父构造函数,仅用于设置原型:
function Parent(name) {
this.name = name;
}
Parent.prototype.makeSound = function() {
console.log("Parent are saying.");
};
function Child(name, age) {
Parent.call(this, name); // 继承属性
this.age = age;
}
// 使用 Object.create 创建新的原型对象,让 Child 继承 Parent 的方法
Child.prototype = Object.create(Parent.prototype);
// 修正 constructor 指向,否则 Child.prototype.constructor 会指向 Parent
Child.prototype.constructor = Child;
Child.prototype.speak = function() {
console.log("Child is talking.");
};
const d = new Child("Child1", 18);
d.makeSound(); // Parent are saying.
d.speak(); // Child is talking.
复制代码
步骤分析:
Object.create(Parent.prototype)
创建一个新对象,其原型指向 Parent.prototype,确保子类原型不污染父类。
修复 constructor 指向
若不修复,Child.prototype.constructor 将指向 Parent,导致实例的 constructor 错误。
构造函数借用 (Parent.call)
在子类构造函数中调用父类构造函数,初始化实例属性。
ES6 class 语法的 prototype
ES6 的 class 是原型的语法糖,本质仍基于原型链:
class Person {
constructor(name) {
this.name = name;
}
// 方法自动添加到 Person.prototype
sayHello() {
console.log(`Hello, my name is ${this.name}`);
}
}
const p = new Person("Tom");
p.sayHello(); // Hello, my name is Tom
// 静态方法添加到构造函数本身
Person.staticMethod = function() {
console.log("This is a static method.");
};
console.log(Object.getPrototypeOf(p) === Person.prototype); // true
复制代码
在这个例子中:
sayHello 方法实际存储在 Person.prototype。
static 关键字定义的方法属于构造函数本身,而非原型。
prototype验证
构造函数与原型的关系
// 验证 Object 是 Function 的实例
console.log(Object instanceof Function); // 输出: true
// 验证 Function 继承自 Object.prototype
console.log(Object.getPrototypeOf(Function.prototype) === Object.prototype); // 输出: true
// 自定义函数和对象
function A() {}
const a = new A();
// 验证自定义函数是 Function 的实例
console.log(A instanceof Function); // 输出: true
// 验证自定义对象的原型是自定义函数的 prototype
console.log(Object.getPrototypeOf(a) === A.prototype); // 输出: true
// 验证自定义函数的 prototype 的原型是 Object.prototype
console.log(Object.getPrototypeOf(A.prototype) === Object.prototype); // 输出: true
// 原型链的终点
console.log(Object.prototype.__proto__); // null
复制代码
prototype图形展示
// https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
+----------------+ constructor +---------------------+
| Function | <------------ | Function.prototype |
| (Function 本身) | ------------> | (Function 原型) |
+----------------+ prototype +---------------------+
__proto__ ^ |
| |
|------------------------------ | __proto__
| __proto__ |
| v
+----------------+ constructor +------------------+ +--------+
| Function | <---------- | Object.prototype | ---------> | 终点 |
| (Object 函数) | ----------> | (所有对象的基类) | __proto__ | null |
+----------------+ prototype +------------------+ +--------+
^
|
| __proto__
|
+----------------+ constructor +----------------------+
| function Foo() | <--------- | Foo.prototype |
| (自定义函数) | ----------> | (自定义函数原型对象) |
+----------------+ prototype +----------------------+
^
|
|
+----------------+ |
| new Foo() | -----------------------|
| (函数实例对象) | __proto__
+----------------+
复制代码
实例化对象步骤(new 关键字的执行过程)
实例化 const newFoo = new Foo(); 的步骤
function Foo() {}
const newFoo = new Foo();
复制代码
1. 创建一个新对象
JavaScript 先创建一个新的空对象 newFoo。
const newFoo = {};
复制代码
2. 设置新对象的原型
newFoo.__proto__ 被设置为 Foo.prototype,即 newFoo 继承了 Foo.prototype 的属性和方法。
newFoo.__proto__ = Foo.prototype;
复制代码
3. 执行构造函数,并绑定 this
const result = Foo.apply(newFoo, arguments);
复制代码
调用 Foo 构造函数,并将 newFoo 作为 this 传入。
若 Foo 显式返回一个对象,则 new 操作符返回该对象;否则返回 newFoo。
4. 返回对象
若构造函数返回对象,则返回该对象。否则返回新创建的 obj。
return typeof result === "object" && result !== null ? result : newFoo;
复制代码
原型链分析
基于上面 const newFoo = new Foo(); 进行分析。
原型链指向
newFoo.__proto__ === Foo.prototype // ✅ `newFoo` 的原型是 `Foo.prototype`
Foo.prototype.__proto__ === Object.prototype // ✅ `Foo.prototype` 的原型是 `Object.prototype`
Object.prototype.__proto__ === null // ✅ `Object.prototype` 的原型是 `null`(即原型链的终点)
复制代码
构造器关系
newFoo.constructor === Foo.prototype.constructor // ✅ `newFoo` 的构造函数是 `Foo`
Foo.prototype.constructor === Foo // ✅ `Foo.prototype` 的 `constructor` 指向 `Foo` 本身
Foo.prototype.constructor.prototype === Foo.prototype // ✅ `Foo.prototype.constructor` 的 `prototype` 仍然是 `Foo.prototype`
复制代码
说明:
当我们创建一个新对象时,它的 constructor 属性通常来源于它的原型(即 Foo.prototype.constructor)。
使用 Object.create 或修改原型时,有可能需要手动修正 constructor 指向。
Function 和 Object 互相指向
Foo.prototype.__proto__.constructor.__proto__ === Function.prototype // ✅ `Object` 构造函数的 `__proto__` 指向 `Function.prototype`
Function.prototype === Object.__proto__ // ✅ `Function.prototype` 就是 `Object` 的 `__proto__`
Function.prototype.__proto__.__proto__ === null // ✅ `Function.prototype.__proto__` 是 `Object.prototype`,再往上是 `null`
复制代码
构造器和原型链的循环指向
Foo.prototype.constructor.prototype.constructor === Foo // ✅ 循环指向 `Foo`
Foo.prototype.constructor.prototype.constructor.prototype === Foo.prototype // ✅ 再次循环指向 `Foo.prototype`
Foo.prototype.constructor === Foo // ✅ `Foo.prototype.constructor` 仍然指向 `Foo`
复制代码
Object 和 Function 之间的关系
Object.prototype.constructor === Object // ✅ `Object.prototype` 的 `constructor` 是 `Object`
Object.prototype.constructor.__proto__ === Function.prototype // ✅ `Object` 构造函数本身是 `Function` 的一个实例
Function.constructor.__proto__ === Function.prototype // ✅ `Function` 构造函数的 `__proto__` 也是 `Function.prototype`
Function.prototype.__proto__ === Object.prototype // ✅ `Function.prototype` 继承自 `Object.prototype`
Function.__proto__.__proto__ === Object.prototype // ✅ `Function.__proto__` 继承自 `Function.prototype`,最终指向 `Object.prototype`
Object.prototype.__proto__ === null // ✅ `Object.prototype` 是原型链终点
复制代码
原型使用的注意事项
避免直接修改内置原型
如 Array.prototype.myMethod = ... 可能导致兼容性问题。
原型属性的共享特性
引用类型(如数组)的属性可能被所有实例意外修改:
function MyClass() {}
MyClass.prototype.data = [];
const a = new MyClass();
a.data.push(1); // 所有实例的 data 都会变化
复制代码
性能优化
将方法定义在原型上,而非构造函数内,减少内存占用。
总结
prototype 属性
每个 JavaScript 函数 都有一个 prototype 属性(除了箭头函数)。
prototype 是一个对象,所有由该函数创建的实例都会共享 prototype 上的方法。
__proto__ 指向该对象的原型(即构造函数的 prototype),形成原型链。
通过 Object.create() 进行原型继承,ES6 class 语法是 prototype 的语法糖。
原型链终点 为 Object.prototype,其
proto
为 null。
new 关键字的作用
创建一个新对象 newFoo
设置 newFoo.__proto__ = Foo.prototype
执行 Foo 并绑定 this
返回 newFoo 或构造函数返回的对象
构造函数、原型和 Object 的关系
Foo.prototype 继承自 Object.prototype
Object.prototype 是所有对象的原型链终点
Object 和 Function 互相指向,Object 也是 Function 的一个实例
Function.prototype.__proto__ === Object.prototype,最终 Function 也继承自 Object
更多链接:
https://github.com/microwind/design-patterns
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
一文
清楚
什么
JavaScript
prototype
相关帖子
一文学习 Spring 声明式事务源码全流程总结
JavaScript this绑定规则:告别踩坑指南!
什么是环回地址127.0.0.1?
一文学习 工作流开发 BPMN、 Flowable
别急着动手写代码:先想清楚这几点,后面少改八百回
别急着动手写代码:先想清楚这几点,后面少改八百回
别急着动手写代码:先想清楚这几点,后面少改八百回
别急着动手写代码:先想清楚这几点,后面少改八百回
别急着动手写代码:先想清楚这几点,后面少改八百回
【JavaScript高级编程】拆解函数流水线 上
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
业界
一文学习 Spring 声明式事务源码全流程总结
0
112
米嘉怡
2026-03-23
安全
JavaScript this绑定规则:告别踩坑指南!
0
70
诈知
2026-03-24
业界
什么是环回地址127.0.0.1?
0
154
曲愍糙
2026-03-25
业界
一文学习 工作流开发 BPMN、 Flowable
0
397
凌彦慧
2026-03-25
业界
别急着动手写代码:先想清楚这几点,后面少改八百回
0
942
琴丁辰
2026-03-27
业界
别急着动手写代码:先想清楚这几点,后面少改八百回
0
555
恿榫
2026-03-27
业界
别急着动手写代码:先想清楚这几点,后面少改八百回
0
25
阎一禾
2026-03-27
业界
别急着动手写代码:先想清楚这几点,后面少改八百回
0
844
越蔓蔓
2026-03-27
业界
别急着动手写代码:先想清楚这几点,后面少改八百回
0
702
扈季雅
2026-03-27
业界
【JavaScript高级编程】拆解函数流水线 上
0
260
姥恫
2026-03-30
回复
(31)
谅潭好
2025-10-10 06:32:53
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
感谢分享,学习下。
劳暄美
2025-10-24 17:33:24
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
用心讨论,共获提升!
辉伫
2025-11-5 02:07:51
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
感谢分享,下载保存了,貌似很强大
醋辛
2025-12-2 18:41:49
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
谢谢分享,辛苦了
注思
2025-12-5 10:05:38
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
过来提前占个楼
方方仪
2025-12-10 08:07:09
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
这个有用。
劳暄美
2026-1-12 17:01:07
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
谢谢分享,试用一下
祖柔惠
2026-1-15 02:02:43
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
谢谢分享,辛苦了
梢疠
2026-1-17 13:20:12
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
感谢发布原创作品,程序园因你更精彩
决台
2026-1-17 14:39:28
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
喜欢鼓捣这些软件,现在用得少,谢谢分享!
辈霖利
2026-1-19 12:18:36
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
很好很强大 我过来先占个楼 待编辑
敖雨燕
2026-1-19 12:33:40
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
热心回复!
谅潭好
2026-1-20 09:02:16
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
谢谢分享,试用一下
钦遭聘
2026-1-22 04:25:52
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
喜欢鼓捣这些软件,现在用得少,谢谢分享!
晦险忿
2026-1-24 10:47:18
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
新版吗?好像是停更了吧。
粒浊
2026-1-24 12:42:52
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
过来提前占个楼
拼匍弦
2026-1-29 02:50:24
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
这个有用。
思矿戳
2026-1-29 05:13:49
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
前排留名,哈哈哈
挽幽
2026-1-30 05:38:59
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
东西不错很实用谢谢分享
下一页 »
1
2
/ 2 页
下一页
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
浏览过的版块
代码
安全
程序
科技
签约作者
程序园优秀签约作者
发帖
甘子萱
2026-1-30 05:38:59
关注
0
粉丝关注
25
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
3934307807
991125
anyue1937
9994892
kk14977
6845359
4
xiangqian
638210
5
神泱
9522
6
韶又彤
9916
7
宋子
9878
8
荪俗
9020
9
闰咄阅
9997
10
刎唇
9999
查看更多
今日好文热榜
580
Qt 技巧笔记(十四):QTableWidget 表格组
259
【JavaScript高级编程】拆解函数流水线 上
442
Claude 绝密模型泄露!Sora 关停、AI 工具
388
P10387 [蓝桥杯 2024 省 A] 训练士兵
110
电容是什么?一个“快充快放”的微型充电宝
943
做了一个网页天气可视化 2
694
Redis命令处理机制源码探究
722
读2025世界前沿技术发展报告27核力量
1
读2025世界前沿技术发展报告27核力量
2
读2025世界前沿技术发展报告27核力量
1
读2025世界前沿技术发展报告27核力量
1
读2025世界前沿技术发展报告27核力量
1
读2025世界前沿技术发展报告27核力量
1
Claude 绝密模型泄露!Sora 关停、AI 工具
1
做了一个网页天气可视化 2
1
做了一个网页天气可视化 2
1
Redis命令处理机制源码探究
1
【JavaScript高级编程】拆解函数流水线 上
1
Claude 绝密模型泄露!Sora 关停、AI 工具
1
Claude 绝密模型泄露!Sora 关停、AI 工具