为什么这不能是一个原语?
我正在摆弄 JavaScript,并注意到 this
永远不可能是原语。我在说什么?让我解释一下。
以这个函数为例。
function test(){
return typeof this;
}
test.call('Abc'); // 'object'
test.call(123); // 'object'
正如我所期望的那样,它们都是 'object'
,而不是 'string'
或 'number'
。
经过一番混乱(以及弄乱 instanceof
)后,我明白了发生了什么。 'Abc'
正在转换为 String
对象,123
正在转换为 Number
对象。
无论如何,我的问题是为什么会发生这种情况,以及如何将对象转换回其原始对象?
我知道我可以使用 (String)this
或 (Number)this
,但是如果我不知道类型,我该怎么做?
编辑:我试图这样做:
function element(){
var $e = $(this),
$d = $e.closest('div');
}
element.call('#myID');
但它不起作用。 this
是一个 String
对象,jQuery 只是创建了一个对象集合,而不是使用选择器来搜索 DOM。
I was messing around with JavaScript, and noticed that this
can never be a primitive. What am I talking about? Let me explain.
Take this function for example.
function test(){
return typeof this;
}
test.call('Abc'); // 'object'
test.call(123); // 'object'
They are both 'object'
, not 'string'
or 'number'
, like I'd expect.
After a bit of confusion (and messing with instanceof
), I figured out what's going on. 'Abc'
is being coverted to a String
object, and 123
is being converted to a Number
object.
Anyway, my question is why does this happen, and how do I convert an object back to its primitive?
I know I could use (String)this
or (Number)this
, but how can I do that if I don't know the type?
EDIT: I was trying to do this:
function element(){
var $e = $(this),
$d = $e.closest('div');
}
element.call('#myID');
and it wasn't working. this
is a String
object, and jQuery just made a collection of objects instead of using the selector to search the DOM.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
正如其他人指出的那样,它根据规范被强制为一个对象。
需要注意的重要一点是,如果您处于严格模式,则不会发生强制转换。
所以真正的问题是为什么不使用 strict? ;-)
正如您在评论中指出的,如果您支持不支持严格模式的实现,您应该能够使用
.valueOf()
。如果您只期望一个字符串,或者如果您也期望一个数字,但您不介意数字字符串,那么您可以这样做......
如果您想知道它的类型,请使用
Object.prototype 上提供的通用
获取内部[[Class]] 属性。toString
As others noted, it's coerced to an object as per the spec.
Important thing to note is that if you're in strict mode, the coercion doesn't happen.
So the real question is why aren't you using strict? ;-)
As you noted in your comment, you should be able to use
.valueOf()
if you're supporting implementations that don't support strict mode.If you're only expecting a String, or if you're also expecting a Number, but you don't mind a numeric String instead, you could do this...
If you want to know its type, use the generic
toString
available onObject.prototype
to get the internal [[Class]] property.我找到了,ECMAScript 5.1
Function.prototype.call
基本上它说
undefined
和null
作为第一个参数,导致this
成为全局对象(浏览器中的window
context),所有其他值都使用ToObject
。由于
typeof
的不一致,我建议使用Object.prototype.toString.call
,它在我测试过的每个浏览器中返回一致的值:您可以比较此小提琴中的输出
I found it, ECMAScript 5.1
Function.prototype.call
Basically it says
undefined
andnull
as the first parameter causethis
to be the global object (window
in a browser context), and all other values are converted to an object usingToObject
.Due to the inconsistencies of
typeof
, I recommend usingObject.prototype.toString.call
, which returns consistent values in every browser I've tested:you can compare the output in this fiddle
规范规定
this
始终是一个对象。The spec says that
this
is always an object.我的理解是,
this
在面向对象的上下文之外没有任何意义,它始终指向某个对象的实例。所以根据定义它不能是原语。另外,您的测试函数似乎返回了
test
函数本身的typeof
(在该上下文中是this
),而不是参数的你路过了。My understanding is,
this
makes no sense outside an object-oriented context, it will always be pointing to some object's instance. So by definition it cannot be a primitive.Also, it seems your test function is returning the
typeof
thetest
function itself (which isthis
in that context), and not of the parameters you're passing.