简体   繁体   English

通过简单的示例了解这一点和setTimeout

[英]Understanding this and setTimeout in simple Example

In following example I have a couple of surprises: 在以下示例中,我有两个惊喜:

I am sad, people not even reading question properly before voting it down. 我很伤心,人们甚至在投票否决之前都没有正确阅读问题。 JSFiddle wraps variables to set them local . JSFiddle包装变量以将其设置为local Please, dont show it as a proof in this case! 请不要在这种情况下将其作为证明! --- And, also someone who was extra clever removed my code and wrapped it in fiddle to show his Great Stupidity to next level! ---还有一个非常聪明的人删除了我的代码,并把它包装在小提琴中,以显示他的“大愚蠢”!

Snippet: 片段:

 this.a = 100; var a = 200; function b() { this.a = 300; setTimeout(function() { console.log(this.a) }, 0); } b(); console.log("Hello"); console.log(a); 

Result: 结果:

在此处输入图片说明

Query: 查询:

  1. When setTimeout is 0, the first log must be 300. Why do I see Hello printed before? 当setTimeout为0时,第一个日志必须为300。为什么我看到以前打印的Hello? (As function b is executed before "console.log(Hello)". (由于函数b在“ console.log(Hello)”之前执行。

  2. The 3rd log must have the value "200", as this.a in both lines refers to window.a as this refers to window object in both locations. 第三个日志必须具有值“ 200”,因为这两个行中的this.a都引用window.a,因为这两个位置都引用了window对象。 variable a still hods value as 200. 将仍然保留的值可变为200。

  3. While chrome shows Hello, 300, 300 Fiddle shows Hello, 200, 300 chrome显示Hello,300,300小提琴显示Hello,200,300

Any explanations for these 2 phenomenons? 对这两种现象有什么解释?

Note: JSfiddle wraps the code in function to set them as local variables, so dont consider it for the current example. 注意:JSfiddle将代码包装在函数中以将它们设置为局部变量,因此在当前示例中不要考虑它。 Try out in Chrome! 在Chrome中试用!

As commented, 如评论所述,

What is happening is OP is calling b(). 发生了什么事,OP正在调用b()。 This internally calls setTimeout. 这在内部调用setTimeout。 In it, OP updates this.a where this is pointing to window. 在这里面,OP更新this.a其中this指向窗口。 Hence 300 因此300

Following is a sample where I have wrapped code in IIFE 以下是我在IIFE中包装代码的示例

 (function() { this.a = 100; var a = 200; function b() { this.a = 300; setTimeout(function() { console.log(this.a) }, 0); } b(); console.log("Hello"); console.log(a); })() 

Explanation 说明

 // Here this points to window this.a = 100; // variables declared outside any functions are part of global scope (window) var a = 200; function b() { // this again points to window this.a = 300; setTimeout(function() { console.log(this.a) }, 0); } b(); console.log("Hello"); console.log(a); 

When setTimeout is 0, the first log must be 300. Why do I see Hello printed before? 当setTimeout为0时,第一个日志必须为300。为什么我看到以前打印的Hello? (As function b is executed before "console.log(Hello)". (由于函数b在“ console.log(Hello)”之前执行。

No, all "timed out" function executions execute asynchronously . 不,所有“超时”功能执行均异步执行。 The execution is slotted into the next available time slot after your current snippet has finished . 当前代码段完成后 ,执行将插入下一个可用时隙。 0 simply schedules it very very soon, it doesn't make it a synchronous call. 0只是非常快地调度它,它没有使其成为同步调用。

The 3rd log must have the value "200", as this.a in both lines refers to window.a as this refers to window object in both locations. 第三个日志必须具有值“ 200”,因为这两个行中的this.a都引用window.a,因为这两个位置都引用了window对象。 variable a still hods value as 200. 将仍然保留的值可变为200。

This very much depends on what this is initially. 这在很大程度上取决于什么this是最初。 When executed in a plain Javascript environment where the initial this is window , all a s refer to the same window.a , and the expected result is 300 , because that's what it's set to before it's being logged the first time. 当一个普通的JavaScript环境下,初始执行thiswindow ,所有a s请参阅同window.a ,和预期的结果是300 ,因为这是它的一组之前它被记录的第一次。

While chrome shows Hello, 300, 300 Fiddle shows Hello, 200, 300 chrome显示Hello,300,300小提琴显示Hello,200,300

The Fiddle environment is special and the initial this is not window . 小提琴环境是特殊的,最初this不是window

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

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