js基础问题--作用域?导致两次结果不一样的原因是什么?

为什么调用y的时候,x的值没有改变

  function f1(
    x,
    y = function () {
      x = 2;
    }
  ) {
    console.log(x); //5

    y();
    console.log(x); //5
    var x = 3;
    console.log(x); //3
    y();
    console.log(x); //3
  }
  f1(5);

当函数中没有声明x的时候,调用y,x就改变了

      function f2(
        x,
        y = function () {
          x = 2;
        }
      ) {
        console.log(x); //5
        y();
        console.log(x); //2
      }
      f2(5);
阅读 1.8k
2 个回答

因为你用了var声明变量。

var是会提升声明(注意是提升声明不是提升初始化)的。

function f1(
    x,
    y = function () {
        console.log('y中的x=', x) // 内存为实参内存,值为实参值=5
        x = 2;
        console.log('y中的x=', x) // 内存为实参内存,值为新赋的值=2
    }
) {
    console.log(x); // 内存为var x = 3的内存,值为实参值=5

    y();
    console.log(x); // 内存为var x = 3的内存,值为实参值=5
    var x = 3; // 内存为var x = 3的内存,值为新赋的值=3
    console.log(x); // 内存为var x = 3的内存,值为新赋的值=3
    y(); // 注意此时实参内存的x的值=2,所以本次执行将输出【y中的x= 2 y中的x= 2】
    console.log(x); // 内存为var x = 3的内存,值为新赋的值=3
}

f1(5)
function f2(
    x,
    y = function () {
        console.log('y中的x=', x) // 内存为实参内存,值为实参值=5
        x = 2;
        console.log('y中的x=', x) // 内存为实参内存,值为新赋的值=2
    }
) {
    console.log(x); // 内存为实参内存,值为实参值=5
    y();
    console.log(x); // 内存为实参内存,值为实参值=2
}

f2(5);

实践中尽量避免使用var,建议使用let

var 声明了一个新的变量。

有了 var 声明,函数中的所有 x 都是函数局部的 x ,而不是参数 x 。而 y = function () { x = 2; } 中的 x 还是参数 x

由于变量提升,这个新的 x 已进入函数就存在(而不是等到 var x = 3 才存在)。它与函数参数重名,所以会以函数参数的值进行初始化(而不是 var x = 3 中的 3)。

var x = 3; 的位置,实际执行的只是一个 x = 3; 的赋值。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏