JavaScript原型是函数的prototype属性,用于实例共享属性方法;原型链是通过__proto__向上查找的机制,终点为null。
JavaScript 原型是每个函数对象自带的 prototype 属性,它是一个普通对象,用来存放将来被该函数作为构造器创建的实例所共享的属性和方法。原型链则是对象在访问属性或方法时,沿着 __proto__ 链向上逐级查找的机制。
prototype,但只有「被当构造器调用」的对象才继承它你定义一个函数:
function Person(name) { this.name = name; }它立刻拥有 Person.prototype,这个对象默认带一个 constructor 属性指向 Person。但此时 Person.prototype 和 Person 本身毫无关系——直到你用 new Person()。
这时发生三件事:
__proto__ 指向 Person.prototype
Person 函数体,this 绑定到这个新对象所以不是“函数有原型所以能继承”,而是“new
操作符把实例的 __proto__ 指向了函数的 prototype”。
__proto__ 不是标准写法,但浏览器普遍支持;Object.getPrototypeOf() 才是正解__proto__ 是历史遗留属性,ECMAScript 规范并未强制要求其实现(尽管所有主流引擎都支持)。直接读写它容易引发混淆,尤其在类继承或 Proxy 场景下行为不一致。
正确方式是:
Object.getPrototypeOf(obj)
Object.setPrototypeOf(obj, proto)
Object.create(proto)
比如:
const parent = { say() { return 'hi'; } };
const child = Object.create(parent);
console.log(Object.getPrototypeOf(child) === parent); // true
Object.prototype,再往上是 null
所有普通对象最终都继承自 Object.prototype,而它的 __proto__ 是 null。这就是查找终止条件。
你可以验证:
console.log(Object.getPrototypeOf({}) === Object.prototype); // true
console.log(Object.getPrototypeOf(Object.prototype) === null); // true
注意几个常见陷阱:
Array.prototype 和 Function.prototype 都是 Object.prototype 的直接子对象,不是平级关系typeof null 返回 "object",但它没有原型(Object.getPrototypeOf(null) 报错)prototype 属性,不能用 new 调用真正容易被忽略的是:原型链只在「读取属性」时触发,赋值操作永远作用于对象自身。哪怕 obj.x = 1 的 x 原本在原型上,这次赋值也会在 obj 上新建一个同名自有属性——原型上的那个不会被修改,也不会被屏蔽以外的方式绕过。