为何返回非原始类型的构造函数无法不使用new调用?
问题解析
示例代码
function MyAnimation(duration) { this.duration = duration; requestAnimationFrame(this.tick.bind(this)); return new Promise((resolve)=>{resolve()}); // 返回原始类型时会返回实例 } MyAnimation.prototype.tick = function (time) { start_stamp=(!start_stamp)?time:start_stamp; elapsed=time-start_stamp; range=(elapsed>this.duration)?this.duration:elapsed; test_elem2.style.transform="rotateY("+0.09*range+"deg)"; return (elapsed<=this.duration)?requestAnimationFrame(this.tick.bind(this)):'done'; } const anim_obj=new MyAnimation; anim_obj.constructor(1000);
问题描述
已知ES6类必须通过new关键字调用,但当构造函数返回原始类型时不会报错,而返回Promise时却出现错误提示:“Promise constructor cannot be invoked without 'new'”,请问这是为什么?
原因解释
这里的核心是JS构造函数返回值的规则,以及实例constructor属性的指向变化:
- 构造函数返回值的优先级:
- 用
new调用构造函数时,如果构造函数返回原始类型(数字、字符串、布尔等),JS会忽略这个返回值,最终返回new创建的构造函数实例。 - 如果构造函数返回对象类型(包括Promise这种内置对象),JS会直接把这个对象作为
new操作的结果返回,原本创建的构造函数实例会被丢弃。
- 用
- 错误触发的具体逻辑:
- 当构造函数返回原始类型时,
anim_obj是MyAnimation的实例,它的constructor属性指向MyAnimation函数。调用anim_obj.constructor(1000)等同于直接执行MyAnimation(1000)——这虽然不符合构造函数的调用规范,但不会触发Promise相关错误。 - 当构造函数返回
new Promise(...)时,anim_obj实际上是一个Promise实例,它的constructor属性指向Promise构造函数。而Promise是ES6类,其构造函数必须用new调用,直接执行Promise(1000)就会抛出你看到的错误提示。
- 当构造函数返回原始类型时,
内容的提问来源于stack exchange,提问作者brittle_spirit
相关产品推荐
相关产品推荐

