【问题标题】:Lost with the output of "constructor.name" in javascript在 javascript 中因“constructor.name”的输出而丢失
【发布时间】:2016-05-27 06:19:23
【问题描述】:

我有一个类似的条件来检查 String 类型的构造函数名称是 "String" 还是 "string"

我迷失了以下 JS 代码的输出:

(typeof([].constructor.name)).constructor.name
"String"

typeof([].constructor.name).constructor.name
"string"

但是当我测试以下代码的输出时,我会更加困惑:

(typeof([].constructor.name))
"string"

typeof([].constructor.name)
"string"

"string".constructor.name
"String"

据我了解,输出应始终为“字符串”。

任何人都可以对我缺少什么或上面的代码出了什么问题提出一些明确的建议吗?

【问题讨论】:

  • typeof 是一个运算符,而不是一个函数,所以typeof [].constructor.name 就足够了。括号没有害处,只是多余的。
  • constructor.name 在 IE 中不起作用。

标签: javascript string constructor javascript-objects


【解决方案1】:

可能的原因

在使用控制台后,我发现以下内容,似乎typeof(a).b 可能等同于typeof (a).b,所以看起来以下内容是等价的

(typeof([].constructor.name)).constructor.name
(typeof [].constructor.name).constructor.name

但是对于第二个示例,似乎执行了以下操作

typeof([].constructor.name).constructor.name
typeof ([].constructor.name).constructor.name

第一个示例中的第二个括号充当分组运算符,这可能是导致奇怪结果的原因

关于 "string""String"

您可能已经知道,我们可以通过 name 属性访问命名函数的名称

function A(){}
A.name // A

此外,当您在窗帘后面创建函数时,会创建一个对象,该对象可通过函数的 prototype 属性访问,该对象通过其 constructor 属性引用函数本身

function A(){}
A.prototype  // {constructor: A}
A.prototype.constructor === A // true

每当您创建函数的“实例”时,其隐藏的[[Prototype]] 属性(又名__proto__)都会指向构造函数的原型,所以

[].__proto__ === Array.prototype // true

由于空数组没有定义constructor 属性,JS 会查找__proto__ 指向的对象,如上所示,空数组是Array.prototype,它具有constructor 属性因此

[].constructor === Array // true

从这个地方操作数的分辨率变得微不足道

[].constructor.name // "Array"
[].constructor.name.constructor === String // true
[].constructor.name.constructor.name // "String", i.e. the name of the `function String() {}`

所以在你的例子中

(typeof [].constructor.name).constructor.name
// evaluated to
(typeof "Array").constructor.name
// evaluated to
"string".constructor.name
// evaluated to
String.name
// evaluated to
"String"

第二个例子

typeof ([].constructor.name).constructor.name
// evaluated to
typeof "String"
// evaluated to
"string"

故事的寓意:使用typeof operator 而不是typeof()

【讨论】:

  • "似乎typeof(a).b 等同于typeof (a).b"——当然,这就是标记和空格在 JS 中的工作方式。我想你真正想强调的是 typeof a.b 被解析为 typeof (a.b) 而不是 (typeof a).b
【解决方案2】:

我有类似的条件需要检查 String 类型的构造函数名称是“String”还是“string”。

String 构造函数的名称在标准中定义为“String”(ECMA-262 §4.3.19),带有大写“S”,这与 ECMAScript 中构造函数的约定相同(尽管有 Math 和 JSON 等例外)。

typeof 运算符返回的值也在标准中定义(ECMA-262 §12.5.6)。

值的类型和创建它的构造函数是两个完全不同的概念。例如。任意数量的不同名称的构造函数都可以返回类型为“object”但其构造函数名称不同(或相同)的对象。

typeof 返回的值不一定与值的类型匹配。

只是复习一些表达方式:

(typeof([].constructor.name)).constructor.name

删除不必要的内部括号并考虑外部括号,它分解为:

[]           // returns an Array instance
.constructor // returns the Array constructor object
.name        // returns the name of the constructor, "Array"

所以现在有:

(typeof 'Array') // returns the string primitive "string"

所以现在有:

'string'       // string literal
.constructor   // returns the String constructor
.name          // returns the string "String"

所以最终结果是“String”,即 String 构造函数的名称。

对于表达式:

typeof([].constructor.name).constructor.name

再次从括号开始:

[]                  // returns an Array instance
.constructor        // returns the Array constructor
.name               // returns the string "Array"

所以现在有:

'Array'             // the string 'Array'
.constructor        // the String constructor
.name               // the string 'String'

离开:

typeof 'String'     // the string 'string'

所以最终的结果是“字符串”。最后一个是 typeof 运算符为原始字符串返回的值的结果。

【讨论】:

  • 关于MathJSON,您指的是什么例外?他们不是构造函数,也没有.name
  • 因为它们是名称以大写字母开头的内置对象,但它们不是构造函数(甚至不是函数)。
  • 啊,确实是这样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-03
相关资源
最近更新 更多