简体   繁体   English

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

[英]Why does `typeof this` return “object”?

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"

I see the same results in Chrome, Firefox, and Safari, so I assume it's per the spec , but...why? 我在Chrome,Firefox和Safari中看到相同的结果,所以我认为它符合规范 ,但是......为什么? And where in the spec is this defined? 这个规范中的定义是什么? And why not for functions? 为什么不用于功能呢?

As defined in ECMA-262 ECMAScript Language Specification 3rd edition (see footnote), It's based on the spec (Section 15.3.4.4): 如ECMA-262 ECMAScript语言规范第3版(见脚注)中所定义,它基于规范 (第15.3.4.4节):

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

Parameters 参数

thisArg

Determines the value of this inside fun. 确定这个内部乐趣的价值。 If thisArg is null or undefined, this will be the global object. 如果thisArg为null或未定义,则这将是全局对象。 Otherwise, this will be equal to Object(thisArg) (which is thisArg if thisArg is already an object, or a String, Boolean, or Number if thisArg is a primitive value of the corresponding type). 否则,这将等于Object(thisArg)(如果thisArg已经是对象,则为thisArg,如果thisArg是相应类型的原始值,则为String,Boolean或Number)。 Therefore, it is always true that typeof this == "object" when the function executes. 因此,当函数执行时,这个==“对象”的类型总是正确的。

Note in particular the last line. 特别注意最后一行。

The crucial thing is that js primitives ( string , number , boolean , null , undefined ) are immutable, so a function can not be attached to them. 关键是js primitives( stringnumberbooleannullundefined )是不可变的,因此函数不能附加到它们。 Therefore the call function wraps the primitive in an Object so that the function can be attached. 因此, call函数将原语包装在Object以便可以附加函数。

Eg: 例如:

Doesn't work: 不起作用:

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

Works: 作品:

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

(footnote) - as patrick dw noted in the comments, this will change in ECMA-262 ECMAScript Language Specification 5th edition when in strict mode: (脚注) - 正如patrick dw在评论中指出的那样,在严格模式下,这将在ECMA-262 ECMAScript语言规范第5版中发生变化:

From Section 15.3.4.4: 从第15.3.4.4节:

NOTE The thisArg value is passed without modification as the this value. 注意thisArg值未经修改即作为此值传递。 This is a change from Edition 3, where a undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value. 这是对第3版的更改,其中未定义或null thisArg将替换为全局对象,ToObject将应用于所有其他值,并且结果将作为此值传递。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM