JavaScript如何访问在使用函数之外声明的变量?

时间:2018-09-01 11:42:33

标签: javascript

假设我们在for循环中有一个简单的print语句,例如

for (var i = 0; i < 2; i++){
    setTimeout(() => console.log(i));
}

两个问题。

setTimeout是一种浏览器API方法,但是它如何访问ii在for循环中声明,即使没有通过i,我也在方法setTimeout中访问i,怎么办?

为什么要打印2,2,而不是0.1?

1 个答案:

答案 0 :(得分:2)

  

setTimeout是一种浏览器API方法,但是它如何访问i?我是   在for循环内声明,并且我正在方法内访问i   setTimeout即使我没有通过,怎么办?

在javascript中,嵌套函数可以访问高阶变量和函数。

//global context - any variable declared here will be availabe within any nested function
var someVariable = 0;
var someSecondVariable = 1;

const someFunc = () => {
  //someVariable and someSecondVariable are accessible here
  console.log("someFunc", someVariable, someSecondVariable);
  
  var someThirdVariable = 2;
  for(let i = 0; i < 5; i++){
    
    const temp = i;
    
    //all higher order variables are still accessible
    setTimeout(()=>{
      //all higher order variableds are still accessible
      console.log("settimeout", i, temp);
    }, 4000);
  }
  
}

const someFunc2 = () => {
  //cant access someThirdVariable
  try {
    console.log("someFunc2", someThirdVariable);
  }catch(e){
    console.warn(e.message);
  }
}

someFunc();
someFunc2();

  

为什么要打印2,2而不是0,1?

setTimeout是一种异步方法,不会立即被调用。在第一个超时事件开始之前,循环结束。这意味着,在调用setTimeout回调时,我已经等于2。

  1. i = 0->继续循环
  2. i = 1->继续循环
  3. i = 2->停止循环,因为2 <2 = false

然后调用setTimeout回调

console.log(i) //where i = 2
console.log(i) //where i = 2

在这里您可以拥有0,1

for (var i = 0; i < 2; i++){
    //temp won't get increased in the next iteration
    const temp = i;
    setTimeout(() => console.log(temp));
}


例如,与相比,它有所不同,我们必须明确告诉它使用更高阶的变量,以便能够在函数范围内访问它。

<?php

  $i = 0;
  $func = function() use ($i){
    echo $i;
  };
  $func();