'this'是Javascript中的全局对象的情况 [英] Cases where 'this' is the global Object in Javascript

查看:105
本文介绍了'this'是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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆