我有一个类似的条件来检查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"。
任何人都可以对我所缺少的内容或以上代码出错吗?
答案 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 运算符为原始字符串返回的值的结果。