You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何返回非原始类型的构造函数无法不使用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属性的指向变化:

  1. 构造函数返回值的优先级:
    • 用new调用构造函数时,如果构造函数返回原始类型(数字、字符串、布尔等),JS会忽略这个返回值,最终返回new创建的构造函数实例。
    • 如果构造函数返回对象类型(包括Promise这种内置对象),JS会直接把这个对象作为new操作的结果返回,原本创建的构造函数实例会被丢弃。
  2. 错误触发的具体逻辑:
    • 当构造函数返回原始类型时,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 13:15:16