前端开发者学习JavaScript原型链时,常困惑于复杂的链条关系,但只要抓住核心逻辑,就能轻松理解并绘制出完整的原型链。原型链的绘制过程其实很简单,关键在于不断追问一个问题——“对象是哪来的”,所有对象的起源都能通过这个问题串联起来。
所有对象都是通过new操作符产生的。比如用函数A通过new可以创建对象a,就算是直接写{}这样的对象字面量,背后也是new Object生成的,本质上没有区别。理解这一点,就能开始构建原型链的基础关系。
接下来要明确三个核心概念的三角关系:函数、通过new函数产生的对象、函数的原型对象(prototype)。函数有一个prototype属性,指向一个原型对象;用new函数产生的对象,其__proto__属性(隐式原型)会指向函数的prototype;函数通过new操作符产生对象,这三者形成稳定的三角结构。比如函数A的prototype是原型对象A_prototype,new A()得到对象a,a的__proto__指向A_prototype,而函数A通过new能生成a,这就是最基础的三角关系。
基于这个三角关系,可以不断扩展链条。比如对象a的__proto__指向A_prototype,而A_prototype本身也是一个对象,它的__proto__指向谁?因为A_prototype是对象,所以它也是new Object产生的,因此A_prototype的__proto__指向Object的prototype(Object_prototype)。同样,Object_prototype作为对象,它的__proto__会指向null——这是原型链的终点,否则会陷入无限递归。

还要注意,函数本身也是对象。比如函数A,它是通过new Function产生的,所以函数A的__proto__指向Function的prototype(Function_prototype)。而Function_prototype作为对象,它的__proto__指向Object_prototype,这样函数和对象的链条就连接起来了。比如函数A的__proto__是Function_prototype,Function_prototype的__proto__是Object_prototype,Object_prototype的__proto__是null,形成完整的链条。
原型链的作用在于对象属性的查找机制。当访问对象的某个属性时,先查对象自身有没有;如果没有,就沿着__proto__形成的链条向上找,依次检查原型对象、原型的原型,直到找到null。如果全程没找到,就会返回undefined。比如对象a要找toString方法,自身没有就找A_prototype,还没有就找Object_prototype,因为Object_prototype上有toString方法,所以能找到并使用。
只要掌握这个核心逻辑,不管链条多复杂,都能一步步绘制出来。比如从任意对象出发,沿着__proto__向上追,直到null,就是该对象的原型链。比如对象a的原型链是a → A_prototype → Object_prototype → null;函数A的原型链是A → Function_prototype → Object_prototype → null。
理解原型链的关键不是记复杂的最终图形,而是掌握“对象由new产生”的核心逻辑和三角关系。只要抓住这两点,再复杂的原型链都能轻松拆解,所有原型相关的问题也能迎刃而解。