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

JavaScript中类实例化顺序为何会触发ReferenceError报错?

问题核心原因

1. 你的传参写法本身存在语法误用

你写的new B(host = DEFAULT_HOST)不是JS中给函数传递参数的正确写法,这段代码的实际执行逻辑是:先执行host = DEFAULT_HOST这个赋值表达式,再把表达式的返回值(也就是DEFAULT_HOST的值)作为第一个参数传给B的构造函数。你以为这是指定参数名传参,但JS原生不支持命名参数传参,你这里本质是做了一次变量赋值操作。

2. Class默认运行在严格模式

ES6的Class内部所有代码默认运行在严格模式下,严格模式的核心规则之一就是不允许给未声明的变量直接赋值,一旦出现就会抛出ReferenceError。
你在A的constructor里写host = DEFAULT_HOST的时候,当前作用域(包括上层全局作用域)都没有声明过host变量,所以严格模式下直接触发报错。

3. 调换执行顺序不报错的原因

你把console.log(new B(host=123));放到前面执行的时候,这行代码是在全局作用域的非严格模式下运行的。非严格模式下给未声明的变量赋值,JS会自动在全局作用域创建一个名为host的全局变量,不会报错。
等后面执行A的constructor里的host = DEFAULT_HOST的时候,全局已经存在host变量了,自然不会再抛出未定义的错误。

4. 普通函数版本正常的原因

普通函数默认运行在非严格模式下,你在a函数里执行host = DEFAULT_HOST的时候,非严格模式自动创建全局host变量,所以不会触发报错。

修复方案

把错误的参数写法改成正常的传参即可,不需要写参数名:

const DEFAULT_HOST = "localhost";

class B {
    constructor(host = null) { console.log(`HOST: ${host}`); }
}

class A {
    constructor() { new B(DEFAULT_HOST) }
}

console.log(new A());
console.log(new B(123));

这样不管执行顺序是什么,都不会出现报错,也不会意外创建全局变量。

内容的提问来源于stack exchange,提问作者user48956

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 04:18:05