为什么`typeof this`返回“对象”?

时间:2010-12-08 17:54:14

标签: javascript call ecma262

var f = function(o){ return this+":"+o+"::"+(typeof this)+":"+(typeof o) };
f.call( "2", "2" );
// "2:2::object:string"

var f = function(o){ return this+":"+(typeof this)+":"+(typeof o); };
var x = [1,/foo/,"bar",function(){},true,[],{}];
for (var i=0;i<x.length;++i) console.log(f.call(x[i],x[i]));
// "1:object:number"
// "/foo/:object:object"
// "bar:object:string"
// "function () {\n}:function:function"
// "true:object:boolean"
// ":object:object"
// "[object Object]:object:object"

我在Chrome,Firefox和Safari中看到相同的结果,所以我假设它是the spec,但是......为什么?这个规范中的定义是什么?为什么不用于功能?

1 个答案:

答案 0 :(得分:11)

如ECMA-262 ECMAScript语言规范第3版(见脚注)中所定义,它基于the spec(第15.3.4.4节):

var result = fun.call(thisArg[, arg1[, arg2[, ...]]]);  

参数

thisArg

  

确定此内部的值   乐趣。如果thisArg为null或未定义,   这将是全球对象。   否则,这将等于   对象(thisArg)(这是thisArg如果   thisArg已经是一个对象,或者一个   如果thisArg,则为String,Boolean或Number   是一个原始的价值   相应的类型)。因此它是   总是这个==的类型   函数执行时的“对象”。

特别注意最后一行。

关键是js原语(stringnumberbooleannullundefined)是不可变的,所以函数不能是附在他们身上。因此,call函数将基元包装在Object中,以便可以附加函数。

E.g:

不起作用:

var test = "string";
//the next 2 lines are invalid, as `test` is a primitive 
test.someFun = function () { alert(this); }; 
test.someFun();

作品:

var test = "string";
//wrap test up to give it a mutable wrapper
var temp = Object(test);
temp.someFun = function () { alert(this); };
temp.someFun();

(脚注) - 在评论中注明patrick dw,在严格模式下,ECMA-262 ECMAScript Language Specification 5th edition会发生变化:

  

从第15.3.4.4节开始:

     
    

注意     thisArg值没有传递     修改为此值。这个     是版本3的变化,其中a     undefined或null thisArg被替换     与全局对象和ToObject是     适用于所有其他价值观     结果作为此值传递。