Javascript 为什么可以';这不是原始的吗?

Javascript 为什么可以';这不是原始的吗?,javascript,jquery,object,primitive,Javascript,Jquery,Object,Primitive,我在玩JavaScript,注意到这个永远不可能是一个原语。我在说什么?让我解释一下 以这个函数为例 function test(){ return typeof this; } test.call('Abc'); // 'object' test.call(123); // 'object' 它们都是'object',而不是我所期望的'string'或'number' 在经历了一点混乱之后(和的实例混在一起),我明白了到底发生了什么“Abc”正在转换为字符串对象,而123正在转换为数

我在玩JavaScript,注意到
这个
永远不可能是一个原语。我在说什么?让我解释一下

以这个函数为例

function test(){
    return typeof this;
}
test.call('Abc'); // 'object'
test.call(123); // 'object'
它们都是
'object'
,而不是我所期望的
'string'
'number'

在经历了一点混乱之后(和的实例混在一起),我明白了到底发生了什么<代码>“Abc”正在转换为
字符串
对象,而
123
正在转换为
数字
对象

无论如何,我的问题是为什么会发生这种情况,以及如何将一个对象转换回其原语

我知道我可以使用
(String)this
(Number)this
,但是如果我不知道类型,我该怎么做呢

编辑:我正试图这样做:

function element(){
    var $e = $(this),
    $d = $e.closest('div');
}
element.call('#myID');
但它不起作用
this
是一个
String
对象,jQuery只是创建了一个对象集合,而不是使用选择器来搜索DOM。

this始终是一个对象

否则,如果类型(thisArg)不是对象,请将ThisBinding设置为ToObject(thisArg)

我找到了

Function.prototype.call 注意:thisArg值作为
this
值传递,无需修改。这是对第3版的更改,其中
未定义
thisArg被替换为全局对象,
对象
应用于所有其他值,结果作为
值传递

基本上,它表示
undefined
null
作为第一个参数,导致
this
成为全局对象(
window
在浏览器上下文中),所有其他值都使用转换为对象


由于
typeof
的不一致性,我建议使用
Object.prototype.toString.call
,它在我测试过的每个浏览器中返回一致的值:

Object.prototype.toString.call('foo') //[object String]
Object.prototype.toString.call(10000) //[object Number]
Object.prototype.toString.call(someFunc) //[object Function]
...etc

我的理解是,
这在面向对象的上下文之外没有任何意义,它总是指向某个对象的实例。因此,根据定义,它不能是一个原语


此外,您的测试函数似乎正在返回
测试
函数本身的
类型(在该上下文中是
),而不是您要传递的参数。

正如其他人所指出的,它是根据规范强制到对象的

需要注意的重要一点是,如果处于严格模式,则不会发生强制

"use strict";

function test(){
    return typeof this;
}
test.call('Abc'); // 'string'
test.call(123); // 'number'
所以真正的问题是,你为什么不使用strict


正如您在评论中指出的,如果您支持不支持严格模式的实现,则应该能够使用
.valueOf()

如果您只需要一个字符串,或者您也需要一个数字,但您不介意使用数字字符串,那么您可以这样做

(this + '') // "Abc"
(this + '') // "123"
“但如果我不知道类型,我怎么能这样做呢”

如果您想知道其类型,请使用
对象.prototype
上提供的泛型
toString
获取内部[[Class]]属性

Object.prototype.toString.call( this ); "[object String]"
Object.prototype.toString.call( this ); "[object Number]"

它可能在某个地方的规范中,哇,这不是我所期望的。顺便说一句,你的
元素
函数完全不需要使用
这个
。这太狡猾了,不利于自己<代码>函数元素(选择器)
显然可以避免整个事情。@AlexWayne:我可能应该这样做:-我正在使用
call
在函数内部设置
这个
。呃,对不起,你说得对,我没有注意到。然而,我仍然认为为
这个
指定一个原语是非常奇怪的(因为我在回答的第一句话中说过)。@Rocket:可能是为了给用户预期的值。严格模式并没有太多地模仿
。如果您刚刚执行了
test()
,那么
将是
未定义的
而不是全局对象。@zzzzBov:这一点很好@Rocket的
.valueOf()
解决方案应该可以工作。。。或者,如果总是需要字符串,请执行
(此+'')
是的,在IE中测试(不支持
“使用严格”
)不会产生预期的结果。@Rocket:我建议您仍然使用严格,但不要依赖仅在严格中有效的技术。换句话说,使用strict,但要保持兼容。@amnotiam:我只需要
this
作为字符串,因为我使用的是
$(this)
。如果
this
是一个对象,jQuery将返回一组对象(即使它是
String
对象),它也不会执行DOM查找<代码>$(此+'')
工作正常。再次感谢:-)至少这是有文档记录的,不是什么奇怪的行为:-)感谢
Object.prototype.toString.call
typeof
只返回
'Object'
。这稍微有用一点:-)有没有方法只获取类型(不使用
[object…
),或者我应该只执行
object.prototype.toString.call('foo').match(/\[object(.*\]/)[1]
?您可以使用散列来存储所需的值转换:我通常只检查
类型=='[object Array]“
或我需要检查的任何类型。似乎严格模式不调用
对象”
(正如“我不是”指出的那样)。