【问题标题】:How to explain the result of using tostring() on an object如何解释在对象上使用 tostring() 的结果
【发布时间】:2020-10-03 10:22:38
【问题描述】:

根据 MDN,

默认情况下,toString() 方法由 Object 的每个派生对象继承。如果自定义对象中没有重写此方法,则 toString() 返回“ [object type] ”,其中 type 是对象类型。

我的第一个问题是对象类型是什么意思?它是指数组、函数、对象、日期吗?我在谷歌搜索过对象类型,但找不到全面的解释。 考虑下面的例子

const toString = Object.prototype.toString; toString.call(new Date);
toString; toString.call(new Date);    // [object Date]
toString.call(new String);  // [object String]
toString.call(Math);        // [object Math]

我不明白为什么 toString.call(new String) 返回 [object String] 从 MDN,它应该返回 [object type],在这种情况下类型应该是 object 因为 console.log (new String) 打印出 {" "} 这是一个对象。 [object String] 似乎也很矛盾,因为 String 不是 Object 的类型,String 是 Primitive

【问题讨论】:

  • 不是toString是用来把数字转成字符串的吗? 3.toString(); // 返回“3”

标签: javascript tostring


【解决方案1】:

String 不是 Object 类型,String 是 Primitive

在某种意义上,JavaScript 中的一切都是object。甚至像String 这样的原语,因为except for null and undefined, all primitive values have object equivalents that wrap around the primitive values

【讨论】:

    【解决方案2】:

    "我不明白为什么 toString.call(new String) 返回 [object String] 从 MDN,它应该返回 [object type] 其中类型 在这种情况下应该是对象,因为 console.log (new String) 打印 out {" "} 这是一个对象。 [object String] 似乎也很矛盾 因为 String 不是 Object 的类型,所以 String 是 Primitive"

    你好像读错了。

    这是一个 String literal "" 而这个 new String 是一个 String object 。 然而,两者(文字和对象)都将从其对应的 Object 构造函数中读取,因此结果将是通用的,即两种实例的 [object String] :: 是 ""new String

    我认为您混淆了使用的术语;也就是:有点多余。 JavaScript 有 7 个类型,其中一些是对象(注意名称中使用了小写字母)其中一个是对象 Object** .那是 type 对象的 object

    不管怎样,你可以有一个primitive\literal,也可以有一个对应typeobject,但是它们不一样! Number 5 literal 与 Number object new Number(5) 的行为非常不同。

    【讨论】:

      【解决方案3】:

      从 ECMAScript 5 开始,可以咨询 "8.6.2 Object Internal Properties and Methods" 以深入了解这个问题。

      但为了更全面的阅读,我推荐 Axel Rauschmayer 的文章 "Improving the JavaScript typeof operator",尤其是 2.1 获取类型名称:[[Class]] 属性部分


      无论如何...从第一个来源开始,以下段落是最重要的...

      [[Class]] 内部属性的值由本规范为每种内置对象定义。宿主对象的 [[Class]] 内部属性的值可以是除 "Arguments""Array""Boolean 之一之外的任何字符串值"“日期”“错误”“函数”“JSON”"Math""Number""Object""RegExp""String "。 [[Class]] 内部属性的值在内部用于区分不同种类的对象。请注意,除了通过 Object.prototype.toString (see 15.2.4.2) 之外,本规范没有为程序提供任何访问该值的方法。

      ...最后一个引用然后声明...

      15.2.4.2 Object.prototype.toString()

      当调用toString方法时,会采取以下步骤:

      1. 如果 this 值为 undefined,则返回 "[object Undefined]"
      2. 如果 this 值为 null,则返回 "[object Null]"
      3. O 成为调用 ToObject 并传递 this 值作为参数的结果。
      4. classO 的 [[Class]] 内部属性的值。
      5. 返回三个字符串 "[object "class"]" 连接的字符串值。

      ...现在,考虑到以上所有情况,如果确实提供了new String,它是一种对象类型而不是原始值,通过call 作为@987654329 的toString 方法的上下文@,确实会检索 String 作为 [[Class]] 内部属性。

      但是,并且 @GirkovArpa 已经指向它,如果确实使用字符串值运行相同的过程,则此原语在处理期间将被提升到/包装成相关的对象类型(步骤 3 ...ToObject),这里是String,它再次对应于 [[Class]] 内部属性。

      因此,'[object String]' 将是最后提到的两种情况的返回值...

      function exposeInternalClassSignature(type) {
        return Object.prototype.toString.call(type);
      }
      
      console.log(
        '"internal class signature for" ...',
        '"foo"',
        ' ... ',
        `"${ exposeInternalClassSignature('foo') }"`
      );
      
      console.log(
        '"internal class signature for" ...',
        (new String('bar')),
        ' ... ',
        `"${ exposeInternalClassSignature(new String('bar')) }"`
      );
      .as-console-wrapper { min-height: 100%!important; top: 0; }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-10
        • 2017-05-02
        • 2017-04-25
        • 1970-01-01
        • 1970-01-01
        • 2018-06-14
        相关资源
        最近更新 更多