javascript参数和作用域

javascript参数和作用域,javascript,function,scope,Javascript,Function,Scope,有点被这个有说服力的参数和作用域Javascript弄糊涂了 它指出,在函数外部声明的变量是全局变量,在函数内部声明的变量是局部变量,在没有前面的变量的函数内部声明的变量基本上引用了一个类似命名的全局变量。好的这是有道理的。但这段代码让我陷入了一个循环 var x = "outside"; var f1 = function() { var x = "inside f1"; }; f1(); console.log(x); // → outside var f2 = function()

有点被这个有说服力的参数和作用域Javascript弄糊涂了

它指出,在函数外部声明的变量是全局变量,在函数内部声明的变量是局部变量,在没有前面的变量的函数内部声明的变量基本上引用了一个类似命名的全局变量。好的这是有道理的。但这段代码让我陷入了一个循环

var x = "outside";

var f1 = function() {
  var x = "inside f1";
};
f1();
console.log(x);
// → outside

var f2 = function() {
  x = "inside f2";
};
f2();
console.log(x);
// → inside f2
注销第一个函数中的x值将导致内部f1,因为该变量是在本地声明的。第二个函数是,它包含一个未声明var的变量,因此引用了在最顶端声明的全局变量,结果应该是外部变量。但是……这两种情况都不是

我知道应该发生什么事。但除非我读错了,否则它似乎与作者描述的相反。这不可能是打字错误

f1中的x是一个新变量,只能在f1中访问,对第一个全局x没有影响。为了清晰起见,您问题中的示例代码基本上可以按以下方式编写:

    var globalX = "outside";
    var f1 = function() {
      var localF1X = "inside f1";
    };
    f1();
    console.log(globalX); // → outside

    var f2 = function() {
      globalX = "inside f2";
    };
    f2();
    console.log(globalX); // → inside f2

在JavaScript中,如果在函数外部声明变量,则变量的作用域为函数级或全局级

您可以在此处阅读更多有关JavaScript变量的信息:

因此:

var x = 'a';
function f1() {
    var x = 1;
    console.log(x);
}

f1(); //outputs 1
console.log(x); //outputs 'a'

function f2() {
    x = 'b';
}

console.log(x); //still outputs 'a'

f2();

console.log(x); //now outputs 'b'

在函数中声明的变量只能从这些函数中访问。如果是这样,样本可能会更清晰:

function f1() {
  var x = "Inside f1"; 
}

console.log(x);
将导致

ReferenceError: x is not defined
ReferenceError: z is not defined
但是,如果函数的变量声明时没有使用var,则这是一个错误,或者是一个错误:

function f2() {
  y = "Inside f2"; 
}

console.log(y);
将按预期工作,同时声明隐式全局

值得一提的是,使用严格;,它在E中运行代码。您通常希望在函数中声明它,这会导致函数在严格模式下运行,并与其他代码一起运行

function f3() {
  "use strict";
  z = "Inside f3"; 
}

console.log(z);
将导致

ReferenceError: x is not defined
ReferenceError: z is not defined
因为严格模式不允许声明隐式全局

为了根据您的评论进行澄清,隐式全局变量将相互覆盖。更简单地使用JavaScript术语:

x=10将在环境的全局对象x上声明一个属性,浏览器环境为window.x,节点/IO环境为global.x。 x=20将重新定义上述相同的属性。 这里有一个小片段,您可以在任何环境中运行来演示这一点。我并不是说你应该使用隐式globals,而是提供了另一个例子来说明为什么你不应该使用隐式globals

function functionThatNeedsGreaterThan50(value) {
  // Skip checking the parameter because we trust the 
  // other developers on the team to make sure they call
  // this right. 
}

function f4() {
  q = 42; 
}

function f5() {
  q = 62; 
}

f4();
f5();

console.log(q);

// sometime thousands of calls later, one of which was
f4(); 

// I thought this was 62 but

functionThatNeedsGreaterThan50(q); 

我知道我昨晚接受了这个答案,但是…声明隐式全局变量有什么不对?我想这样做会让你更难找到任何潜在的错误源。因为全局变量并不像其他普通全局变量那样定义在顶部。是吗?@sabaeus我也用自己的想法补充道。所以,基本上,为了使用正确的隐式全局函数,你必须首先调用创建它的函数?有点-隐式全局函数,或者说任何全局函数都会发生变异。如果您只是想确保使用了正确的值,那么最好在对象或闭包中适当地确定其范围。