"unsafe publication" 是否存在于 Javascript 中?

does "unsafe publication" exist in Javascript?

我刚刚写了下面的Java脚本代码...

class Team {
    constructor(id, eventHandler) {
        this.id = id;
        this._eventHandler = eventHandler;
        this._eventHandler.trigger("NewTeam", this); // my concerning line
    }
}

我有 Java 背景。在 Java 中,对象从其构造函数共享对自身的引用被认为是危险的(“不安全发布”)。这是因为其他线程可能会在对象处于有效状态之前对该对象进行操作。

在Java脚本中也有风险吗?这被认为是不好的做法吗?

我只能想到一个问题:如果我们想扩展 Team,那么让其他属性对 eventHandler.trigger("NewTeam",__).

可见会很棘手

由于 Javascript 是单线程的(webWorkers 除外,这里没有发挥作用),您提到的 Java 问题不适用于 Javascript。没有其他代码会与构造函数同时 运行ning。这是 Java 脚本的单线程和事件驱动特性的重大简化之一。

如果您同步触发事件或进行函数调用并将未完成的对象传递给该事件处理程序或函数调用,那么您当然是在自找麻烦,因为您会将未完成的对象引用传递给其他人在您完成构造函数之前将 运行 的代码。

只要你传递的对象在传递的时候是有效状态,这就没有问题,但是如果你传递的是一个未完成的对象,那你确实是自讨苦吃,但这真的只是常识性编程,与线程或并发无关。


在您的具体情况下:

class Team {
    constructor(id, eventHandler) {
        this.id = id;
        this._eventHandler = eventHandler;
        this._eventHandler.trigger("NewTeam", this); // my concerning line
    }
}

您创建了一个漏洞。如果 Team 是子类,那么在子类必须完成其构造函数之前,您将调用 this._eventHandler.trigger("NewTeam", this); 并传递它 this 。根据具体的实施,这可能是一个问题,因此实践并不总是安全的。如果 .trigger() 可以在下一个 tick 被调用(使用类似 setImmediate()nextTick() 的东西,那么这总是安全的,因为对象和任何子类总是在它之前完成构建被调用了。