🚀 个人简介:某大型测绘遥感企业资深Webgis开发工程师,软件设计师(中级)、优快云优质创作者
💟 作 者:柳晓黑胡椒❣️
📝 专 栏:js基础
🌈 若有帮助,还请关注 ➕ 点赞➕收藏,不行的话我再努努力💪💪💪
JavaScript 是一门基于**原型继承(Prototype Inheritance) 的语言。
原型机制是 JS 实现面向对象编程(OOP)**的核心基础。
理解它,不仅能更好地掌握继承与对象机制,也能更深入理解框架底层设计(如 Vue、React、Cesium 等)。
一、设计初衷:JS 的面向对象与原型思想
在没有传统类(Class)的早期 JavaScript 中,语言设计者引入了「原型链」来模拟类继承。
它的思想源自**单链表(Single Linked List)**结构,通过对象间的引用关系,实现属性与方法的逐层查找。
核心概念可以这样理解:
| 名称 | 含义 | 特点 |
|---|---|---|
| 构造函数(Constructor) | 创建对象的函数(例如:function Person() {}) | 类的定义方式 |
| 原型对象(Prototype) | 构造函数的共享属性与方法存储处 | 所有实例共享 |
| 原型链(Prototype Chain) | 实例对象通过 __proto__ 指向其所属类的原型对象 | 实现继承机制 |
二、三大核心概念

原型(prototype)
每个函数都有一个属性:prototype
它指向一个对象(Object),该对象存放所有共享属性与方法。
function Person(name) {
this.name = name
}
Person.prototype.sayHi = function() {
console.log(`Hi, I'm ${this.name}`)
}
📌 说明:
Person.prototype 就是“Person类”的公共区域,实例都会通过原型链访问到这里。
构造函数(constructor)
每个原型对象中,都有一个属性 constructor,指向该原型所属的函数本身。
console.log(Person.prototype.constructor === Person) // true
✅ constructor 的作用:记录原型的“归属关系”,在原型重定向时尤其重要。
原型链(proto)
每个对象都有一个隐藏属性:__proto__,
它指向当前实例所属类的 prototype 原型对象。
const p1 = new Person("Alice")
console.log(p1.__proto__ === Person.prototype) // true
console.log(Person.prototype.__proto__ === Object.prototype) // true
console.log(Object.prototype.__proto__) // null
这就是原型链的本质:一个逐层向上的引用关系。

三、原型链的查找机制
当访问一个对象的属性时,JavaScript 引擎会遵循以下查找规则:
- 首先找自己的
私有属性,私有属性有,则调取私有属性 - 若不存在,默认基于
__proto__原型链,找所属类prototype原型对象上的公共属性和方法 - 如果没有,则沿着prototype原型对象的__proto__原型链继续往上找
- 若仍未找到,则继续向上查找,直到
Object.prototype - 若到达顶层仍未找到,则返回
undefined

四、万物皆对象
在 JS 中,几乎所有的值(除 undefined、null 外)都能通过 proto 追溯到 Object.prototype。
因此我们说 —— 万物皆对象(Everything is Object)。
console.log([] instanceof Object) // true
console.log(() => {} instanceof Object) // true
console.log(/abc/ instanceof Object) // true
即使是数组、函数、正则、日期,它们的原型链最终都指向 Object.prototype。
五、Object.prototype.proto === null
Object.prototype 是所有对象的基类(所有对象的顶层原型)。
其 __proto__ 值为 null,标志着原型链的终点。
console.log(Object.prototype.__proto__) // null
这也是防止无限循环查找的机制:原型链在此处“断开”。
六、Object.create():创建带原型的对象
Object.create(proto, [propertiesObject])
🧩 作用:用于创建一个以指定原型对象为原型的新对象。
💡 说明:
第一个参数定义原型
第二个参数定义新对象的属性描述符(类似 Object.defineProperty),默认为undefined
var obj = Object.create({ a: 1 }, {
// foo会成为所创建对象的数据属性
b: {
writable: true,//是否可重写
configurable: true,//是否可枚举
enumerable: true,//是否可删除和修改特征
value: "hello"//属性的值
},
// bar会成为所创建对象的访问器属性
c: {
get: function () { return 10 },// 取值器
set: function (value) { // 赋值器
console.log("设置的值为", value);
}
}
})
Object.create(null)
🧩 作用:创建一个没有原型链的纯净对象(所属类的prototype原型对象为null的空对象)
📘 场景:
这种对象常用于实现 纯字典(Map-like) 结构,不会继承任何默认方法(如 toString())。
var obj = Object.create(null);
console.log(obj.prototype);//undefined 对象没有pototype这个属性
console.log(obj.__proto__);// undefined
七、给类的原型上扩展属性方法的4种方法
| 序号 | 扩展方式 | 示例代码 | 说明 |
|---|---|---|---|
| ① | 直接扩展类原型 | Fn.prototype.xxx = ... | 最常见方式,向类的原型对象中追加方法或属性(向默认开辟的堆内存中扩展属性方法) |
| ② | 扩展内置类原型 | Object.prototype.xxx = ... | 慎用!会影响所有对象(全局污染风险) |
| ③ | 基于实例原型扩展 | obj.__proto__.xxx = ... | 会修改实例的原型链,不推荐(IE 不支持) |
| ④ | 原型重定向 | Fn.prototype = { constructor: Fn, ... } | 重建原型对象时需手动修复 constructor 指向(手动开辟一个堆内存赋值) |
八、ES6 新方法:取代__proto__
ES6 引入以下两种标准方法来安全操作原型:
Object.getPrototypeOf(obj) // 取代 obj.__proto__
Object.setPrototypeOf(obj, proto) // 取代 obj.__proto__ = proto
示例:
const p = {}
const proto = { a: 1 }
Object.setPrototypeOf(p, proto)
console.log(Object.getPrototypeOf(p)) // { a: 1 }
🔍 建议始终使用这两种方法,而非直接访问 proto,以保持代码的兼容性与可维护性。
Takeaways
- 原型机制是 JavaScript 面向对象的根基;
- proto 链接实例与类原型;
- prototype 是构造函数的共享区域;
- constructor 建立类与原型的对应关系;
- ES6 提供 Object.getPrototypeOf / Object.setPrototypeOf 安全替代方案。
835

被折叠的 条评论
为什么被折叠?



