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


当前回答

在“Javascript 1.7”(Mozilla对Javascript的扩展)中,还可以使用let语句声明块范围变量:

 var a = 4;
 let (a = 3) {
   alert(a); // 3
 }
 alert(a);   // 4

其他回答

全球范围:

全球变量就像全球明星(成龙、纳尔逊·曼德拉)。您可以从应用程序的任何部分访问它们(获取或设置值)。全球功能就像全球活动(新年、圣诞节)。您可以从应用程序的任何部分执行(调用)它们。

//global variable
var a = 2;

//global function
function b(){
   console.log(a);  //access global variable
}

本地范围:

如果你在美国,你可能会认识金·卡戴珊(Kim Kardashian),她是臭名昭著的名人(她以某种方式制作了小报)。但美国以外的人不会认出她。她是当地的明星,与她的领地息息相关。

局部变量就像局部恒星。您只能在范围内访问它们(获取或设置值)。本地函数就像本地事件一样,只能在该范围内执行(庆祝)。如果您想从作用域之外访问它们,将出现引用错误

function b(){
   var d = 21; //local variable
   console.log(d);

   function dog(){  console.log(a); }
     dog(); //execute local function
}

 console.log(d); //ReferenceError: dddddd is not defined    

查看本文以深入了解范围

几乎只有两种类型的JavaScript作用域:

每个var声明的范围都与最直接的封闭函数相关联如果var声明没有封闭函数,则为全局范围

因此,除函数之外的任何块都不会创建新的作用域。这解释了for循环覆盖外部范围变量的原因:

var i = 10, v = 10;
for (var i = 0; i < 5; i++) { var v = 5; }
console.log(i, v);
// output 5 5

改用函数:

var i = 10, v = 10;
$.each([0, 1, 2, 3, 4], function(i) { var v = 5; });
console.log(i,v);
// output 10 10

在第一个示例中,没有块范围,因此最初声明的变量被覆盖。在第二个示例中,由于函数的原因,出现了一个新的作用域,因此最初声明的变量是SHADOWED,而不是重写。

就JavaScript范围而言,这几乎是您需要了解的全部内容,除了:

try/catch仅为异常变量本身引入新范围,其他变量没有新范围with子句显然是另一个例外,但不鼓励使用with子句(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with)

因此,您可以看到JavaScript作用域实际上非常简单,尽管并不总是直观的。需要注意的几点:

var声明被提到了范围的顶端。这意味着无论var声明发生在哪里,对于编译器来说,就像var本身发生在顶部一样同一范围内的多个var声明组合在一起

因此,此代码:

var i = 1;
function abc() {
  i = 2;
  var i = 3;
}
console.log(i);     // outputs 1

相当于:

var i = 1;
function abc() {
  var i;     // var declaration moved to the top of the scope
  i = 2;
  i = 3;     // the assignment stays where it is
}
console.log(i);

这似乎与直觉相悖,但从命令式语言设计者的角度来看,这是有道理的。

在JavaScript中,有两种类型的作用域:

本地范围全局范围

Below函数有一个局部范围变量carName。这个变量不能从函数外部访问。

function myFunction() {
    var carName = "Volvo";
    alert(carName);
    // code here can use carName
}

Below Class有一个全局范围变量carName。这个变量可以从类中的任何地方访问。

class {

    var carName = " Volvo";

    // code here can use carName

    function myFunction() {
        alert(carName);
        // code here can use carName 
    }
}

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

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

Javascript使用作用域链为给定函数建立作用域。通常有一个全局范围,每个定义的函数都有自己的嵌套范围。在另一个函数中定义的任何函数都具有与外部函数链接的局部作用域。定义范围的始终是源代码中的位置。

作用域链中的元素基本上是一个带有指向其父作用域指针的Map。

解析变量时,javascript从最内部的范围开始并向外搜索。