如何在 Javascript 中获取此关键字的类型?
How to get type of this keyword in Javascript?
我正在操纵 Object
的原型,以便我可以添加一些扩展方法。
我发现 typeof
运算符总是 returns object
如果操作数是 this
:
Object.prototype.logType = function () { console.log(typeof this); }
"Hello".logType()
上面代码的输出是 object
而不是 string
。我知道 JavaScript 中的所有内容确实都是 object
,但是我需要知道 this
值的确切类型。我怎样才能做到这一点?
当你在一个原语上调用一个方法时,JS 会自动将该原语包装在它的关联对象包装器中,所以:
"Hello".logType()
变成:
new String("Hello").logType()
因此,this
在您的 logType 函数内部引用包装的原始值,为您提供一个对象。你可以调用.valueOf()
来获取包裹在对象中的原始值:
Object.prototype.logType = function () { console.log(typeof this.valueOf()); }
"Hello".logType(); // string
(1).logType(); // number
true.logType(); // boolean
1n.logType(); // bigint
Symbol().logType(); // symbol
(() => {}).logType(); // function
({}).logType(); // object
或者,您可以按照评论中的建议使用严格模式,因为这会将 this
保留为原始原始值:
Object.prototype.logType = function () { "use strict"; console.log(typeof this); }
"Hello".logType(); // string
(1).logType(); // number
true.logType(); // boolean
1n.logType(); // bigint
Symbol().logType(); // symbol
(() => {}).logType(); // function
({}).logType(); // object
当在严格模式 之外作为 this
传递时,您会遇到一种非常罕见的情况,即您会遇到包装对象形式的原语(“盒装”),作为 String
的实例:
因此,您可以使用 this instanceof String
而不是 typeof this === 'string'
检查是否在字符串上调用了您的方法。如果你想区分继承自 String
的字符串和对象,你可以使用 this.constructor === String
。
要返回“常规”字符串(或 Number
的数字,或 Boolean
的布尔值等),您可以调用 this.valueOf()
(这意味着您也可以编写 typeof this.valueOf()
- 但请注意,这可能会产生误导,因为任何对象都可以 return,比方说,来自其 valueOf
方法的字符串实际上没有最初是一个字符串。)
注意:您无法通过这种方式区分 'abc'.yourMethod()
和 new String('abc').yourMethod()
,因为无论哪种方式您都会得到 String
的实例。
(同样有趣:似乎对于像 BigInt
或 Symbol
这样的新类型,您不能手动创建这样的包装器实例,new BigInt(1n)
会失败。但是 (function () { return this }).call(1n)
会达到同样的效果,虽然我不知道为什么有人会想要那个...)
综上所述:最简单 获得您想要的确切行为(this
是实际字符串)的方法是在上下文中定义您的函数严格模式:
(function {
'use strict'
Object.prototype.logType = function () { console.log(typeof this); }
})()
现在它将按预期工作。
我正在操纵 Object
的原型,以便我可以添加一些扩展方法。
我发现 typeof
运算符总是 returns object
如果操作数是 this
:
Object.prototype.logType = function () { console.log(typeof this); }
"Hello".logType()
上面代码的输出是 object
而不是 string
。我知道 JavaScript 中的所有内容确实都是 object
,但是我需要知道 this
值的确切类型。我怎样才能做到这一点?
当你在一个原语上调用一个方法时,JS 会自动将该原语包装在它的关联对象包装器中,所以:
"Hello".logType()
变成:
new String("Hello").logType()
因此,this
在您的 logType 函数内部引用包装的原始值,为您提供一个对象。你可以调用.valueOf()
来获取包裹在对象中的原始值:
Object.prototype.logType = function () { console.log(typeof this.valueOf()); }
"Hello".logType(); // string
(1).logType(); // number
true.logType(); // boolean
1n.logType(); // bigint
Symbol().logType(); // symbol
(() => {}).logType(); // function
({}).logType(); // object
或者,您可以按照评论中的建议使用严格模式,因为这会将 this
保留为原始原始值:
Object.prototype.logType = function () { "use strict"; console.log(typeof this); }
"Hello".logType(); // string
(1).logType(); // number
true.logType(); // boolean
1n.logType(); // bigint
Symbol().logType(); // symbol
(() => {}).logType(); // function
({}).logType(); // object
当在严格模式 之外作为 this
传递时,您会遇到一种非常罕见的情况,即您会遇到包装对象形式的原语(“盒装”),作为 String
的实例:
因此,您可以使用 this instanceof String
而不是 typeof this === 'string'
检查是否在字符串上调用了您的方法。如果你想区分继承自 String
的字符串和对象,你可以使用 this.constructor === String
。
要返回“常规”字符串(或 Number
的数字,或 Boolean
的布尔值等),您可以调用 this.valueOf()
(这意味着您也可以编写 typeof this.valueOf()
- 但请注意,这可能会产生误导,因为任何对象都可以 return,比方说,来自其 valueOf
方法的字符串实际上没有最初是一个字符串。)
注意:您无法通过这种方式区分 'abc'.yourMethod()
和 new String('abc').yourMethod()
,因为无论哪种方式您都会得到 String
的实例。
(同样有趣:似乎对于像 BigInt
或 Symbol
这样的新类型,您不能手动创建这样的包装器实例,new BigInt(1n)
会失败。但是 (function () { return this }).call(1n)
会达到同样的效果,虽然我不知道为什么有人会想要那个...)
综上所述:最简单 获得您想要的确切行为(this
是实际字符串)的方法是在上下文中定义您的函数严格模式:
(function {
'use strict'
Object.prototype.logType = function () { console.log(typeof this); }
})()
现在它将按预期工作。