javascript中变量的范围是什么?它们在函数内部的作用域与在函数外部的作用域相同吗?或者这有关系吗?此外,如果变量是全局定义的,那么变量存储在哪里?


当前回答

全局声明的变量具有全局范围。在函数中声明的变量的作用域是该函数,并隐藏同名的全局变量。

(我相信真正的JavaScript程序员可以在其他答案中指出许多微妙之处。特别是我在这个页面上看到了这到底意味着什么。不过,希望这个更为介绍性的链接足以让你开始。)

其他回答

运行代码。希望这能提供一个关于范围界定的想法

Name = 'global data';
document.Name = 'current document data';
(function(window,document){
var Name = 'local data';
var myObj = {
    Name: 'object data',
    f: function(){
        alert(this.Name);
    }
};

myObj.newFun = function(){
    alert(this.Name);
}

function testFun(){
    alert("Window Scope : " + window.Name + 
          "\nLocal Scope : " + Name + 
          "\nObject Scope : " + this.Name + 
          "\nCurrent document Scope : " + document.Name
         );
}


testFun.call(myObj);
})(window,document);

试试这个奇怪的例子。在下面的示例中,如果a是一个初始化为0的数字,您将看到0,然后是1。除了a是一个对象,javascript将向f1传递a的指针,而不是它的副本。结果是两次都得到相同的警报。

var a = new Date();
function f1(b)
{
    b.setDate(b.getDate()+1);
    alert(b.getDate());
}
f1(a);
alert(a.getDate());

ECMAScript 6引入了let和const关键字。这些关键字可以用来代替var关键字。与var关键字相反,let和const关键字支持在块语句中声明局部范围。

var x = 10
let y = 10
const z = 10
{
  x = 20
  let y = 20
  const z = 20
  {
    x = 30
    // x is in the global scope because of the 'var' keyword
    let y = 30
    // y is in the local scope because of the 'let' keyword
    const z = 30
    // z is in the local scope because of the 'const' keyword
    console.log(x) // 30
    console.log(y) // 30
    console.log(z) // 30
  }
  console.log(x) // 30
  console.log(y) // 20
  console.log(z) // 20
}

console.log(x) // 30
console.log(y) // 10
console.log(z) // 10

现代J、ES6+、“const”和“let”

您应该像大多数其他主要语言一样,为创建的每个变量使用块范围。var已过时。这使您的代码更安全,更易于维护。

95%的病例应使用常量。它使变量引用不能更改。数组、对象和DOM节点财产可以更改,并且应该是常量。

let应该用于任何期望重新分配的变量。这包括在for循环中。如果在初始化之后更改值,请使用let。

块范围意味着变量只能在声明它的括号内使用。这扩展到内部范围,包括在范围内创建的匿名函数。

为了补充其他答案,范围是所有声明的标识符(变量)的查找列表,并强制执行一组严格的规则,以确定当前执行的代码如何访问这些标识符。该查找可能用于分配变量,该变量是LHS(左侧)引用,也可能用于检索其值,该值是RHS(右侧)引用。这些查找是JavaScript引擎在编译和执行代码时在内部执行的操作。

因此,从这个角度来看,我认为我在凯尔·辛普森(Kyle Simpson)的《范围与关闭》(Scopes and Closures)电子书中找到的一张图片会有所帮助:

引用他的电子书:

该构建表示程序的嵌套范围规则集。第一个建筑物的楼层代表您当前执行的范围,无论你在哪里。建筑的顶层是全球范围。通过查看当前楼层来解析LHS和RHS参考,如果你找不到,就乘电梯到下一层,看那里,然后看下一个,以此类推。一旦你到达顶层(全球范围),你要么找到你想要的,要么不要。但你必须停止不管。

值得一提的是,“范围查找一旦找到第一个匹配项就停止”。

“作用域级别”的概念解释了如果在嵌套函数中查找“This”,为什么可以使用新创建的作用域来更改“This”。这里有一个链接,介绍了所有这些细节,您想了解的关于javascript范围的一切