new调用构造函数时,引擎自动创建空对象、设置其[[prototype]]指向构造函数prototype、绑定this并返回对象;prototype是函数属性,__proto__是实例内部引用,二者内容相同但角色不同。

当你用 new 调用构造函数时,JavaScript 引擎会自动完成四件事:创建空对象、把该对象的 [[Prototype]] 指向构造函数的 prototype、将 this 绑定到这个新对象、最后返回该对象(除非显式返回其他对象)。关键就在第二步——this 与原型的关联,是通过内部属性 [[Prototype]] 实现的,不是靠赋值或手动挂载。
new 过程中 this 的原型链被自动设置
构造函数本身没有“拥有”原型对象,而是它的 prototype 属性是一个普通对象,这个对象会被赋给新实例的内部原型链。也就是说,this.__proto__ === Constructor.prototype 是 new 的副作用,不是代码里写的。
- 引擎在创建新对象后,立即执行类似
obj.[[Prototype]] = Constructor.prototype的操作 - 这个链接只发生在
new调用时,和构造函数体内是否使用this无关 - 即使构造函数里没给
this添加任何属性,实例依然能访问Constructor.prototype上的方法
prototype 属性和实例的 __proto__ 不是同一个东西
Constructor.prototype 是函数的一个可写属性,用于定义所有实例共享的原型;而每个实例的 __proto__(即 [[Prototype]])是内部引用,指向那个 prototype 对象。它们内容相同,但角色不同。
-
F.prototype是你定义方法的地方,比如F.prototype.say = function(){} -
new F().__proto__是运行时生成的,不可枚举,且通常不建议直接修改 - 现代写法推荐用
Object.getPrototypeOf(instance)替代instance.__proto__
手动模拟 new 的行为有助于理解 this 和原型的关系
你可以用普通函数大致还原 new 的逻辑,就能看清 this 是怎么连上原型的:
function myNew(Constructor, ...args) {
const obj = {};
Object.setPrototypeOf(obj, Constructor.prototype); // 关键:设置原型链
const result = Constructor.apply(obj, args);
return (result !== null && typeof result === 'object') ? result : obj;
}
这里 Object.setPrototypeOf(obj, Constructor.prototype) 就对应了原生 new 中那一步隐式设置 [[Prototype]] 的动作——正是这行让 this(即 obj)能顺着原型链找到方法。
箭头函数不能当构造函数,因为它没有 prototype
箭头函数没有 prototype 属性,也没有 [[Construct]] 内部方法,所以无法用 new 调用。试图这么做会直接报错:TypeError: xxx is not a constructor。这也反向说明:能否被 new,取决于函数是否有可访问的 prototype 并支持构造调用协议。
- 普通函数声明/表达式默认有
prototype,且prototype.constructor === 函数自身 - 类(class)本质也是函数,它的
prototype同样被用于实例原型链 - 如果删除了函数的
prototype(如F.prototype = null),再用new F()仍会成功,但实例的__proto__会变成null,失去原型继承
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











