【问题标题】:Maximum call stack size exceeded - Object Initializer with reference to self超出最大调用堆栈大小 - 引用自身的对象初始化器
【发布时间】:2021-11-20 09:54:36
【问题描述】:

在玩一个简单的 Javascript Object Initializer 示例时,我找不到以下代码的解释:

const obj = {
  self: this
};

console.log(obj);

会领导Error: Maximum call stack size exceeded吗?

同时,一个略有不同但可能看起来相似的初始化块如下:

const obj = {
  self: obj
};

console.log(obj);

将导致Error: Cannot access uninitialized variable.,而以下使用方法初始化程序的示例可以正常工作:

const obj = {
  name: 'Bob',
  a() {
    return obj.name;
  },
  b() {
    return this.name;
  },
};

console.log(obj.a());
console.log(obj.b());

您能否详细说明对象初始化过程以及为什么该语言允许在初始化对象及其 this 引用在方法初始化程序中而不是在属性值中使用?

【问题讨论】:

  • First 不适合我,this 也不等于 obj,这可能是您的意图。其次,您只是在声明完成之前使用变量,这是不允许的。
  • 你只是在声明函数,而不是调用它们,所以它不会抛出。第二个示例是在变量完全初始化之前直接尝试访问obj
  • #1 不会导致任何错误,而只会导致意外值,请参阅 stackoverflow.com/questions/4616202/… 。您可以在 JS 中创建循环引用。对象存储在内存中,只有你在 JS 中得到的是一个引用,你甚至可以做到 const arr = []; arr[0] = arr; 没有任何问题。
  • @Teemu 你确定全局this 是未定义的行为吗?我一直看到this === globalThis
  • @Newbie 我没有说 global this 是未定义的,我说它可能是意想不到的值,当您期望它引用 obj 时(在 OP 的示例中)。

标签: javascript reference this object-initializers


【解决方案1】:

案例1this === global

这里的this 是全局javascript 上下文。通常是巨大的并且包含许多循环引用。当你 console.log() 一个带有循环引用的对象时,结果取决于实现(它不会在 Chrome 93.0.4577.63 上抛出错误)。

console.log({ self: this });

See what is globalThis.

See how to print a circular reference.

案例2obj is undefined

这是无效的语法。首先将评估表达式{ self: obj },然后执行赋值。但是当表达式被评估时,obj 不存在因此导致Error: Cannot access uninitialized variable.

const obj = { self: obj };

这会如你所愿:

const obj = {};
obj.self = obj;

案例3

最后一个示例与其他示例完全无关。

  • 您永远不会创建循环引用,也不会尝试记录循环引用。
  • 您在延迟时间从a() 访问obj,因此const obj = 已经执行。
const obj = {
    name: 'Bob',
    a() {
        // This is executed only when calling `a()`
        return obj.name;
    },
    b() {
        // `this` here is not the global context bu `obj`
        return this.name;
    },
};

// Both functions returns a string, so no circular dependency here 
console.log(obj.a());
console.log(obj.b());

这个函数会导致你在上面看到的错误:

const obj = {
    a() {
        obj.self = notExisting;
        return obj;
    },
    b() {
        this.self = this;
        return this;
    },
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-24
    • 2015-12-29
    • 2017-12-27
    • 2020-12-06
    • 2020-03-11
    • 2018-02-06
    • 2020-06-28
    • 2016-02-28
    相关资源
    最近更新 更多