javascript中“万物皆对象”是基于原型机制的近似概括,核心在于能否通过原型链访问属性;原型链终点为object.prototype→null,基本类型通过临时包装对象实现属性访问,但null、undefined不参与原型链。

“万物皆对象”在 JavaScript 中不是字面意义上的绝对断言,而是一种**基于运行时行为与原型机制的近似概括**。它的真正落脚点不在“是不是对象”,而在“**能否通过原型链访问属性、是否参与原型继承体系**”。理解这一点,关键要抓住原型链末端的具体表现和技术边界。
原型链终点:Object.prototype 与 null
所有普通对象(包括数组、函数、正则等)的原型链最终都会抵达 Object.prototype,而它的 __proto__ 是 null——这是整个原型链的终止符。
例如:
-
{}→Object.prototype→null -
[]→Array.prototype→Object.prototype→null -
function() {}→Function.prototype→Object.prototype→null
这个终点决定了:任何对象都能调用 toString()、hasOwnProperty() 等方法,因为它们定义在 Object.prototype 上;一旦链走到 null 还没找到属性,就返回 undefined。
“万物”不包括基本类型值,但有自动包装机制
字符串、数字、布尔值("abc"、42、true)本身是原始值(primitive),没有 __proto__,也不直接参与原型链查找。
但当你写 "abc".length 或 42.toString() 时,JS 会**临时创建对应的包装对象**(String、Number 实例),在该包装对象上查找属性,用完即弃。这不是“它们是对象”,而是“语言为你做了隐式转换”。
验证方式:
-
typeof "abc"→"string"(不是"object") -
"abc" instanceof String→false(原始值不是实例) -
Object.getPrototypeOf("abc")→ 报错(原始值无原型)
函数既是对象,又自带 prototype 属性
函数是特殊的对象:它既是可执行代码,又是构造器(可被 new 调用)。因此它同时具备:
- 作为对象的
__proto__:指向Function.prototype(说明“函数是 Function 的实例”) - 作为构造器的
prototype属性:一个普通对象,供其实例共享方法(如Person.prototype.sayHi)
这导致函数的原型链更长:function f(){} → Function.prototype → Object.prototype → null
注意:Function.prototype 本身是个函数(空函数),但它自己的 __proto__ 仍是 Object.prototype,保持统一终点。
技术边界:null、undefined、symbol、bigint 不进入原型链
以下值明确游离于原型链体系之外:
-
null和undefined:没有__proto__,不能调用任何方法,Object.getPrototypeOf(null)直接报错 -
Symbol和BigInt:虽是原始值,但不会触发自动包装(Symbol("a").toString()可行,是因为 Symbol 原型上有该方法;但Symbol("a").xxx查找仍走 Symbol.prototype 链,而非 Object.prototype) - 箭头函数、class 声明的类:本质仍是函数对象,原型链结构一致,无特殊断裂
真正的边界在于——只有能被 Object.getPrototypeOf() 安全接收的值,才属于这个“万物皆对象”的原型体系。而 null 和 undefined 是唯二连这个 API 都无法处理的例外。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











