我正在搞乱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。
答案 0 :(得分:5)
正如其他人所指出的那样,它根据规范被强制转换为对象。
需要注意的重要一点是,如果您处于严格模式,则不会发生强制行为。
"use strict";
function test(){
return typeof this;
}
test.call('Abc'); // 'string'
test.call(123); // 'number'
所以真正的问题是 你为什么不使用严格的 ? ; - )
正如您在评论中指出的那样,如果您支持不支持严格模式的实施,则应该可以使用.valueOf()
。
如果你只是期待一个字符串,或者你也期待一个数字,但你不介意数字字符串,你可以这样做......
(this + '') // "Abc"
(this + '') // "123"
“但如果我不知道类型”
,我怎么能这样做
如果您想知道其类型,请使用toString
上提供的通用Object.prototype
来获取内部 [[Class]] 属性。
Object.prototype.toString.call( this ); "[object String]"
Object.prototype.toString.call( this ); "[object Number]"
答案 1 :(得分:3)
我找到了,ECMAScript 5.1
注意thisArg值未经修改即作为
this
值传递。这是对第3版的更改,其中undefined
或null
thisArg将替换为全局对象,ToObject
将应用于所有其他值,并且结果将作为{{1价值。
基本上它说this
和undefined
作为第一个参数导致null
成为全局对象(浏览器上下文中的this
),并且所有其他值都被转换使用ToObject
到对象。
由于window
的不一致,我建议使用typeof
,它会在我测试过的每个浏览器中返回一致的值:
Object.prototype.toString.call
答案 2 :(得分:2)
this
{{1}}始终是一个对象。
否则如果Type(thisArg)不是Object,则将ThisBinding设置为ToObject(thisArg)。
答案 3 :(得分:0)
我的理解是,this
在面向对象的上下文之外没有意义,它总是指向某个对象的实例。所以根据定义,它不可能是原始的。
此外,您的测试函数似乎正在返回typeof
test
函数本身(在该上下文中为this
),而不是您传递的参数。< / p>