了解thison 函数调用的隐式行为的关键在于了解引用类型如何工作。
的参考类型由两个部分组成(在ECMAScript中3),所述的基础对象和属性名称(在ECMAScript中5,它有一个第三部件的严格标志-I将谈论严格模式later- (1) )。
当被调用的功能,该this值是通过获取参考的基础对象(由内部隐含地确定GetBase操作)。
例如,在foo.bar引用中,基础对象是foo,属性名称是"bar":
foo.bar(); // `this` will point to `foo`
当您进行赋值时,引用丢失了,我们不再有基础对象和属性名称,我们只有一个值:
(f=foo.bar)(); // `this` will point to the global object
它不仅发生在赋值中,还会发生在使用内部GetValue操作的其他操作中:
// `this` will point to the global object
(0, foo.bar)(); // The Comma Operator
(0 || foo.bar)(); // Binary Logical Operators
(1 && foo.bar)();
// etc..
例如,如果您用括号将引用括起来(正式称为The Grouping Operator),则不会发生这种情况:
(foo.bar)(); // `this` will point to `foo`
分组运算符(同样,括号 ;)不在GetValue内部使用,这是以这种方式设计的,因为允许typeof和delete运算符与括号表达式一起使用:
delete (foo.bar);
如果使用分组运算符GetValue,则delete运算符将无法获取要删除属性的基础对象bar。
回到隐含this值,有一些棘手的情况,例如,使用with语句:
with (foo) {
bar(); // `this` will refer to `foo` !
}
如您所见,bar();在 with 块内部调用,仍会将this值绑定到foo对象。
该this值不是从reference设置的,它来自语句引入的当前环境记录(我可能稍后会写一些关于它的内容)with。
此外,您可能会注意到,对于non-references,该this值将指向全局对象,例如:
(function () {})(); // this will point to the global object
我们只有一个值,而不是引用(请记住,引用是解析的名称绑定)。
(1)注意:在 ECMAScript 5 Strict Mode 上,该this值将undefined适用于所描述的所有情况,其中该this值被隐式设置为 Global 对象。
之所以这样做是作为一种安全措施,主要是因为人们new在调用构造函数时经常忘记使用运算符,从而导致不良行为和对全局范围的污染。
例如:
function Foo () {
this.prop = 'foo';
}
Foo(); // no `new` operator, boom!
正如您现在所知,Foo引用没有直接的基础对象,this它将指向全局对象,并且会无意中在其上创建一个属性。
在严格模式下,代码只会给你一个TypeError,因为this值是undefined。
同样,您可能还记得一开始我提到引用类型有第三个组件,即strict标志。
您的原始示例:
(f=foo.bar)();
甚至可能不适用于严格模式,因为不允许分配给未声明的标识符(例如f 似乎),(另一种避免全局对象污染的安全措施)。
更多信息: