'this'是Javascript中的全局对象的情况 [英] Cases where 'this' is the global Object in Javascript
问题描述
我正在玩不同的方法来调用一个函数,该函数是Javascript中Object的一个属性,并查看哪个类型的调用将'this'设置为Object,并将'this'设置为Global Object 。
I'm playing around with different ways to call a function that is an attribute of an Object in Javascript and looking at which type of calls set 'this' to be the Object and which set 'this' to be the Global Object.
这是我的测试代码:
var foo = {
bar: function(){
console.log('this:' + this);
}
}
console.log('calling foo.bar()');
foo.bar();
console.log('\ncalling (foo.bar)()');
(foo.bar)();
console.log('\ncalling f=foo; f.bar()');
f = foo; f.bar();
console.log('\ncalling f=foo.bar; f()');
f = foo.bar; f();
console.log('\ncalling (f=foo.bar)()');
(f = foo.bar)();
这就是结果:
calling foo.bar()
this:[object Object]
calling (foo.bar)()
this:[object Object]
calling f=foo; f.bar()
this:[object Object]
calling f=foo.bar; f()
this:[object global]
calling (f=foo.bar)()
this:[object global]
我的问题是,为什么 f = foo.bar; f();
和(f = foo.bar)();
将'this'指定为全局对象
My question is, why does f=foo.bar; f();
and (f=foo.bar)();
assign 'this' to be the Global Object
推荐答案
了解函数调用中 this
的隐式行为的关键,依赖于知道如何 参考类型 woks。
The key of knowing the implicit behavior of this
on function calls, relies on knowing how the Reference Type woks.
参考类型包含两个组件(在ECMAScript 3中),基础对象和属性名称 (在ECMAScript 5中,它有第三个组件 strict 标志 - 我将在稍后讨论严格模式 - (1))。
The Reference Type consists of two components (in ECMAScript 3), the base object and the property name (in ECMAScript 5, it has a third component the strict flag -I will talk about strict mode later- (1)).
调用函数时,此
值是通过获取引用的基础对象(通过内部 GetBase
操作)隐式确定的)。
When a function is invoked, the this
value is determined implicitly by getting the base object of the reference (by the internal GetBase
operation).
例如,在 foo.bar
引用中,基础对象是 foo
,属性名称是bar
:
For example, in the foo.bar
reference, the base object is foo
and the property name is "bar"
:
foo.bar(); // `this` will point to `foo`
当您执行作业时,参考将丢失,我们不再有基础对象和属性名称,我们只有值:
When you do an assignment, the reference is lost, we don't have anymore a base object and a property name, we just have a value:
(f=foo.bar)(); // `this` will point to the global object
仅在分配时不会发生,它发生在使用内部 GetValue
操作:
It doesn't happen only with assignments, it happens with other operations that use the internal GetValue
operation:
// `this` will point to the global object
(0, foo.bar)(); // The Comma Operator
(0 || foo.bar)(); // Binary Logical Operators
(1 && foo.bar)();
// etc..
例如,如果你围绕一个<带括号的em> reference (正式名称为分组运算符):
It doesn't happens for example if you surround a reference with parentheses (formally called The Grouping Operator):
(foo.bar)(); // `this` will point to `foo`
分组运算符(再次,括号;)在内部不使用 GetValue
,这是以这种方式设计的,因为 typeof
和删除
允许运算符使用带括号的表达式:
The Grouping Operator (again, the parentheses ;) doesn't use GetValue
internally, this was designed in that way because the typeof
and delete
operators are allowed to work with parenthesised expressions:
delete (foo.bar);
如果分组运算符使用 GetValue
, 删除
运算符将无法获取基础对象删除属性 bar
的位置。
If the grouping operator used GetValue
, the delete
operator would be unable to get a base object where to remove the property bar
.
返回隐含的此
值,有一些棘手的情况,例如,使用 with
声明:
Returning to the implicit this
value, there are some tricky cases, for example, using the with
statement:
with (foo) {
bar(); // `this` will refer to `foo` !
}
如您所见,调用 bar();在with块中,
仍会将此
值绑定到 foo
对象。
As you can see, invoking bar();
inside the with block, will still bind the this
value to the foo
object.
此
值未从参考设置,它来自当前环境记录(我稍后可能会写一些关于它的内容)由带有
语句引入。
The this
value isn't set from the reference, it comes from the current Environment Record (I'll maybe write something about it later) introduced by the with
statement.
另外,正如您可能注意到的,对于非引用,此
值将指向全局对象,例如:
Also, as you may note, for non-references, the this
value will point to the global object, for example:
(function () {})(); // this will point to the global object
我们只有一个值 ,而不是引用(请记住,引用是已解析的名称绑定)。
We just have a value, not a reference (Remember, a reference is a resolved name binding).
< sup>(1) 注意:在ECMAScript 5 严格模式上,此
值将为 undefined
for all 描述的情况,其中 this
值隐式设置为Global对象。
(1)NOTE: On ECMAScript 5 Strict Mode, the this
value will be undefined
for all the cases described where the this
value is set implicitly to the Global object.
这是作为安全措施而主要是因为人们经常忘记使用 new
运算符在调用构造函数时,导致不良行为和对全局范围的污染。
This was made as a security measure mostly due the fact that people often forgot to use the new
operator when invoking constructor functions, causing a bad behavior and pollution on the global scope.
例如:
function Foo () {
this.prop = 'foo';
}
Foo(); // no `new` operator, boom!
如您所知, Foo
参考没有直接基础对象,这个
将指向全局对象,它会无意中在其上创建一个属性。
As you known now, the Foo
reference doesn't have a direct base object, this
will point to the global object and it will unintentionally create a property on it.
在严格模式下,代码只会给你一个 TypeError
,因为这个
值将是 undefined
。
On Strict Mode, the code would simply give you a TypeError
, because the this
value would be undefined
.
另外您可能还记得在开始时我提到的参考类型有第三个组件,严格
标志。
Also as you may remember in the beginning I mentioned that the Reference Type has a third component, the strict
flag.
您的原始示例:
(f=foo.bar)();
甚至可能无法在严格模式下工作,因为对未声明的标识符的分配(例如 f
似乎)是不允许的,(另一种避免全球物体污染的安全措施)。
Would probably not even work on Strict Mode, because assignments to undeclared identifiers (such as f
seems) are disallowed, (another security measure to avoid global object pollution).
更多信息:
- Strict Mode
这篇关于'this'是Javascript中的全局对象的情况的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!