__proto__指向构造函数的prototype对象而非构造函数本身;只有函数有prototype属性,所有对象(除null)有__proto__;应使用object.getprototypeof等标准api操作原型。

__proto__ 指向的是 prototype,不是实例。
具体来说:__proto__ 是实例对象身上的一个内部链接(隐式原型),它指向该实例的构造函数的 prototype 对象。
也就是说,__proto__ 的终点是某个函数的 prototype,而这个 prototype 本身是一个普通对象——它是所有该构造函数实例共享的“公共仓库”。
常见错误观念及纠正方式
-
❌ 错误:“
__proto__指向构造函数本身”
✅ 纠正:__proto__指向的是构造函数的prototype属性所引用的对象,不是构造函数本身。
例如:function Dog() {} const d = new Dog(); d.__proto__ === Dog.prototype; // true d.__proto__ === Dog; // false -
❌ 错误:“
prototype是实例的属性”
✅ 纠正:只有函数才有prototype;实例对象没有prototype,只有__proto__。d.prototype; // undefined Dog.prototype; // { constructor: Dog } -
❌ 错误:“
__proto__和prototype是同一种东西,只是写法不同”
✅ 纠正:二者归属不同、用途不同:-
prototype是函数的属性,用来设置将来实例共享的内容; -
__proto__是对象的属性,用来在运行时查找属性和方法(即原型链查找的跳板)。
-
-
❌ 错误:“所有对象都有
prototype”
✅ 纠正:只有函数对象(包括 class、箭头函数除外)才有prototype;普通对象、数组、日期等都没有prototype。({}).prototype; // undefined [].prototype; // undefined function f(){}.prototype; // { constructor: f }
快速判断口诀(帮助记忆)
- 谁有
prototype?→ 函数才有 - 谁有
__proto__?→ 所有对象(除 null)都有 -
__proto__指向谁?→ 创建它的那个函数的prototype -
prototype里有什么?→ 共享方法、属性,还自带constructor指回函数本身
推荐实践方式(避免踩坑)
-
不要直接操作
__proto__,改用标准 API:- 获取原型:
Object.getPrototypeOf(obj) - 设置原型(谨慎):
Object.setPrototypeOf(obj, proto)
- 获取原型:
定义共享方法时,统一挂到
Constructor.prototype上,而不是在构造函数内重复定义。理解
constructor的存在意义:Dog.prototype.constructor === Dog是默认关系,手动修改prototype时记得补上constructor,否则会丢失。
不复杂但容易忽略。











