迷失了" constructor.name"的输出在javascript中

时间:2016-05-27 06:19:23

标签: javascript string constructor javascript-objects

我有一个类似的条件来检查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"

根据我的理解,输出应始终为" String"。

任何人都可以对我所缺少的内容或以上代码出错吗?

2 个答案:

答案 0 :(得分: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__所指向的对象,如上所示为空数组{{1}因此具有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 operator代替typeof ([].constructor.name).constructor.name // evaluated to typeof "String" // evaluated to "string"

答案 1 :(得分:1)

  

我有一个类似的条件来检查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 运算符为原始字符串返回的值的结果。