typeof在处理`this`时返回"object",在其他情况下返回"number"

3

typeof 在不同的上下文中应用到相同的值时,会产生不同的字符串结果。例如,下面的代码是符合预期的:

> typeof 5
'number'

然而,通过this访问5typeof并不相同:

> Number.prototype.foo = function () { return typeof this; };
[Function]
> (5).foo()
'object'

这只是另一个(不)合理的检查,真正严格验证this一个数字:

> Number.prototype.foo = function () { return [this + 1, typeof this]; };
[Function]
> (5).foo()
[ 6, 'object' ]

我已经阅读了 MDN 文档和 ECMAScript 规范中 typeof 的相关内容,但我无法想象这与预期相符,更不用说正确性。有人能解释一下吗?


你应该阅读关于“this”变量以及它与其他你熟悉的语言的区别。在你提供的两个例子中,“this”都指代了语言原语。 - srquinn
2
与 typeof 没有关系,而是与 this 及其所代表的内容有关。 - epascarello
1
this + 1实际上是this.valueOf() + 1 - epascarello
2个回答

5
这里的诀窍是,你的测试用例将5转换为一个对象。
每当你访问原始值(布尔值、数字或字符串)上的属性时,原始值都会被转换为相应类型的对象(Boolean、Number 或 String),并在该对象上解析属性访问。
我在这个主题上写了更多内容,在这里这里
显示类型的正确方法是:
Number.prototype.foo = function () { return typeof this.valueOf(); };
(5).foo() // "number"

您的“sanity check”在执行this+1时会将Object包装器转换回原始值。
(new Number(5)) + 1 // 6

感谢您的澄清! :-) - cemerick

0

我的猜测是(5)将原始类型number转换为Number对象。

尝试添加一个像这样的函数:

Number.prototype.foo2 = function() { console.log(this); }

当你调用(5).foo2()后,你将在Chrome中得到类似以下的结果:

Number {foo: function, foo2: function}
    __proto__: Number
    [[PrimitiveValue]]: 5

不是括号将 5 转换为 Number,而是方法调用。括号存在是为了强制解析器正确地将 . 解释为属性查找,而不是十进制小数分隔符(obj.prop vs 123.456)。5.foo 是语法错误。 - Tibos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接