JavaScript函数的参数对于其回调函数是否不可见?

huangapple go评论51阅读模式
英文:

Does the arguments of a javascript function not visible to its callback function?

问题

Sure, here are the translated parts of your code:

let data = 1;
console.log(data);

data = 2;
setTimeout((data) => {
  console.log(data);
}, 2000);

data = 3;
console.log(data);
let data = 1;
console.log(data);

data = 2;
setTimeout((data) => {
  console.log(data);
}, 2000, data);

data = 3;
console.log(data);
let data = 1;
console.log(data);

data = 2;
setTimeout(() => {   // argument removed from the callback function
  console.log(data);
}, 2000, data);

data = 3;
console.log(data);
let data = 1;
console.log(data);

data = 2;
temp = new Promise((resolve, reject) => {
    // async code
    setTimeout(() => {
      resolve(data);
    }, 2000);
})

temp.then((temp) => {
    console.log(temp);
}).catch((err) => {
    console.log(err);
});

data = 3;
console.log(data);

The code outputs "1 3 2" for the first two examples, "1 3 3" for the third example, and "1 3 3" for the fourth example.

英文:

I want to get 1 3 2 output for this code, with and without usign promises.

let data = 1;
console.log(data);

data = 2;
setTimeout((data) => {
  console.log(data);
}, 2000);

data = 3;
console.log(data);

let data = 1;
console.log(data);

data = 2;
setTimeout((data) => {
  console.log(data);
}, 2000,data);

data = 3;
console.log(data);

this code gives output 1 3 2, as expected, but

console.log(data);

data = 2;
setTimeout(() => {   // argument removed from callback function
  console.log(data);
}, 2000,data);

data = 3;
console.log(data);

this code is giving output 1 3 3, but why?
Why this callback function is not using data agrument passed in setTimeout.

I also used promise but still getting the 1 3 3 as output.

let data=1;
console.log(data);

data=2;
temp=new Promise((resolve, reject)=>{
    // async code
    setTimeout(()=>{
      resolve(data);
    },2000);

})

temp.then((temp)=>{
    console.log(temp);
    }).catch((err)=>{console.log(err);}
);

data=3;
console.log(data);

答案1

得分: 2

这与closures有关。

在这个示例中,你在setTimeout调用时(2)将data的值传递给了它,稍后将传递给回调函数,因此你会得到期望的1,3,2输出。

(回调函数的参数虽然同名,但是它是一个独立的变量——不是在封闭作用域中声明的那个data。)

let data = 1;

console.log(data);

data = 2;
setTimeout((data) => {
  console.log(data);
}, 2000,data);

data = 3;

console.log(data);

为了澄清这两个data变量之间的区别,下面是将参数重命名后的相同实现:

let data = 1;

console.log(data);

data = 2;
setTimeout((banana) => {
  console.log(banana);
}, 2000, data);

data = 3;
console.log(data);

但在这种情况下,setTimeout调用中已经删除了data参数,因此你的回调函数引用的是外部作用域中的变量,而在回调运行时,它的值已经被更改为3。所以你会得到1,3,3

let data = 1;
console.log(data);

data = 2;
setTimeout(() => {   // 从回调函数中删除了参数
  console.log(data);
}, 2000,data);

data = 3;
console.log(data);
英文:

It has to do with closures.

In this example you're passing the value of data to setTimeout at the time of the setTimeout call (2) which will later be passed to the callback, so you get the 1,3,2 output you expect.

(The argument to the callback has the same name but it's an independent variable--it's not the same data as the one declared in the enclosing scope.)

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let data = 1;
console.log(data);

data = 2;
setTimeout((data) =&gt; {
  console.log(data);
}, 2000,data);

data = 3;
console.log(data);

<!-- end snippet -->

Just to clarify the distinction between the two data variables here's the same implementation with the argument renamed:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let data = 1;

console.log(data);

data = 2;
setTimeout((banana) =&gt; {
  console.log(banana);
}, 2000, data);

data = 3;
console.log(data);

<!-- end snippet -->

But in this case, where the data argument has been removed from the setTimeout call, your callback is referencing the variable from the outer scope, and by the time the callback runs its value has already been changed to 3. So you get 1,3,3.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let data = 1;
console.log(data);

data = 2;
setTimeout(() =&gt; {   // argument removed from callback function
  console.log(data);
}, 2000,data);

data = 3;
console.log(data);

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年5月10日 13:55:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76215278.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定