Javascript 为什么可以';这不是原始的吗?
我在玩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正在转换为数
这个
永远不可能是一个原语。我在说什么?让我解释一下
以这个函数为例
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]“
或我需要检查的任何类型。似乎严格模式不调用对象”
(正如“我不是”指出的那样)。