【问题标题】:How to add instance of a class into a JavaScript object?如何将类的实例添加到 JavaScript 对象中?
【发布时间】:2020-06-19 10:57:51
【问题描述】:

我有一个如下所示的类

class test{
    constructor(x){
        this.x = x;
    }
}

我已经创建了这个类的一个实例并存储到一个变量temp中。

let temp = new test(10);

我也有一个对象,我希望将temp 放在其中。

let obj = {};
obj[temp] = true;

但是当我看到obj,它不包含我所期望的,它包含

{[object Object]: true}
[object Object]: true
__proto__: Object

我无法弄清楚我哪里出错了,object Object 代表什么,我们将不胜感激。

更新:

如果我创建对象let temp2 = new test(10); 的另一个实例并检查temp2 in obj,它会返回truetemp in obj 也会返回true

【问题讨论】:

    标签: javascript javascript-objects


    【解决方案1】:

    [object Object] 是 JavaScript 中对象的文本表示,某些打印机函数将打印出来而不是遍历对象。

    也就是说,你不能指望能够使用一个对象(例如“{ foo: 123 }”作为另一个对象的键(例如“foo”是前面示例中的键)。它会变平如您所见,到带有键“object Object”的字符串,就像打印机功能一样。

    【讨论】:

    • @SomShekharMukherjee 为我之前的回答道歉。检查我的更新
    • 是的,我还发现使用对象作为键是错误的,因为它是可变的。
    【解决方案2】:

    类实例在 JS 中由具有类函数和属性的对象表示。进一步阅读Classes by MDN我创建了一个代码框来简要说明https://codesandbox.io/s/cocky-wood-9fk4x?file=/src/index.js

    【讨论】:

      【解决方案3】:

      你返回的数据类型是一个对象

      【讨论】:

        【解决方案4】:

        当你这样做时:

        obj[temp] = true;
        

        您实际上是将一个布尔值放入一个属性中,其 key 是一个对象,该对象被转换为一个字符串。考虑一下你真正想要的是:

        obj['embeddedObject'] = temp;
        

        console.log(obj) 下更有意义。

        【讨论】:

          【解决方案5】:

          仅供参考,对象存储属性(键值对),其中:属性键必须是字符串或符号(通常是字符串),可以是任何类型.欲了解更多信息,您可以通过此discussion

          在您将temp 放入obj 作为属性键名称的情况下,temp.toString() 被隐式调用,默认情况下实现返回"[object Object]"。由于您的类 test 没有覆盖 toString() 方法,并且您创建的实例也 temptemp2 没有覆盖它,所以您总是获取 toString() 的默认实现返回值。因此,temp2 in objtemp in obj 的输出相同。

          【讨论】:

            【解决方案6】:

            带有{} 的对象声明是隐藏object prototype 的简写语法:

            let obj = {}; // what you wrote
            let obj = new Object() // what your JS interpreter sees
            obj.prototype.object // what your JS interpreter creates
            

            这与使用class 速记语法非常相似。 But class is a double abstraction,隐藏了它实际上是在创建一个函数并且它正在使用 function prototype 这样做的事实:

            // what you wrote
            class test{
                constructor(x){
                    this.x = x;
                }
            }
            
            // what your JS interpreter creates
            test.prototype.constructor
            

            所以当你记录obj 并得到[object Object] 时,你的JS 解释器告诉你你已经创建了一个原型对象。您对test 感到困惑,请停下来-它们在不同的范围内,并不意味着同一件事。先学习原型。

            引擎盖下的 JS

            要记住的是,Javascript 是一种面向对象的语言,但不像大多数其他 OOP 那样使用基于类的继承。 Javascript 使用prototype inheritance。当您instantiate a class in JS 时,它并不是经典编程意义上的真正类。

            重申一下,您的 JS class 实际上被定义为一个函数。试试看:

            console.log(typeof test) //output: function
            

            还有更多。假设我们用另一种方法进一步扩展了您的示例:

            class test{
              constructor(x){
                this.x = x;
              }
            
              // Custom method
              outputX() {
                console.log(this.x)
              }
            }
            

            我们实际上做了什么?如上所述,JS 解释器将读取您的类并利用function prototype 来创建它。那么这与仅仅定义一个函数有何不同呢?

            因为你使用了class,所以函数原型会自动为你的新test原型分配一个构造方法。所有其他自定义方法——比如我添加的outputX——都被添加到test原型中。

            // All valid
            test.prototype.constructor
            test.prototype.outputX
            test.prototype.whateverMethodYouMake
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-12-18
              • 1970-01-01
              • 2010-12-17
              • 2020-08-05
              • 2021-03-15
              • 1970-01-01
              相关资源
              最近更新 更多