为什么这不是原始的?

时间:2012-01-27 19:46:02

标签: javascript jquery object primitive

我正在搞乱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。

4 个答案:

答案 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

Function.prototype.call

  

注意thisArg值未经修改即作为this值传递。这是对第3版的更改,其中undefinednull thisArg将替换为全局对象,ToObject将应用于所有其他值,并且结果将作为{{1价值。

基本上它说thisundefined作为第一个参数导致null成为全局对象(浏览器上下文中的this),并且所有其他值都被转换使用ToObject到对象。


由于window的不一致,我建议使用typeof,它会在我测试过的每个浏览器中返回一致的值:

Object.prototype.toString.call

you can compare the output in this fiddle

答案 2 :(得分:2)

this {{1}}始终是一个对象。

  

否则如果Type(thisArg)不是Object,则将ThisBinding设置为ToObject(thisArg)。

答案 3 :(得分:0)

我的理解是,this在面向对象的上下文之外没有意义,它总是指向某个对象的实例。所以根据定义,它不可能是原始的。

此外,您的测试函数似乎正在返回typeof test函数本身(在该上下文中为this),而不是您传递的参数。< / p>