JavaScript中的变量范围是什么?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript中的变量范围是什么?相关的知识,希望对你有一定的参考价值。

javascript中的变量范围是什么?它们的内部是否与函数外部相同?或者甚至重要吗?另外,如果变量是全局定义的,那么它们存储在哪里?

答案

我认为我能做的最好的事情就是给你一些学习的例子。 Javascript程序员实际上根据他们理解范围的程度来排名。它有时可能非常违反直觉。

  1. 全局范围的变量 // global scope var a = 1; function one() { alert(a); // alerts '1' }
  2. 本地范围 // global scope var a = 1; function two(a) { // passing (a) makes it local scope alert(a); // alerts the given argument, not the global value of '1' } // local scope again function three() { var a = 3; alert(a); // alerts '3' }
  3. 中级:没有JavaScript中的块范围(ES5; ES6引入let) 一个。 var a = 1; function four() { if (true) { var a = 4; } alert(a); // alerts '4', not the global value of '1' } var a = 1; function one() { if (true) { let a = 4; } alert(a); // alerts '1' because the 'let' keyword uses block scoping }
  4. 中级:对象属性 var a = 1; function Five() { this.a = 5; } alert(new Five().a); // alerts '5'
  5. 高级:关闭 var a = 1; var six = (function() { var a = 6; return function() { // JavaScript "closure" means I have access to 'a' in here, // because it is defined in the function in which I was defined. alert(a); // alerts '6' }; })();
  6. 高级:基于原型的范围解析 var a = 1; function seven() { this.a = 7; } // [object].prototype.property loses to // [object].property in the lookup chain. For example... // Won't get reached, because 'a' is set in the constructor above. seven.prototype.a = -1; // Will get reached, even though 'b' is NOT set in the constructor. seven.prototype.b = 8; alert(new seven().a); // alerts '7' alert(new seven().b); // alerts '8'
  7. 全球+本地:一个额外复杂的案例 var x = 5; (function () { console.log(x); var x = 10; console.log(x); })(); 这将打印出undefined10而不是510,因为JavaScript总是将变量声明(不是初始化)移动到作用域的顶部,使得代码等效于: var x = 5; (function () { var x; console.log(x); x = 10; console.log(x); })();
  8. Catch子句范围的变量 var e = 5; console.log(e); try { throw 6; } catch (e) { console.log(e); } console.log(e); 这将打印出565。在catch子句中,e会影响全局变量和局部变量。但是这个特殊范围仅适用于捕获的变量。如果你在catch子句中写var f;,那么它就像你在try-catch块之前或之后定义它一样。
另一答案

我发现许多刚接触JavaScript的人很难理解默认情况下语言中的继承是可用的,到目前为止,函数范围是唯一的范围。我为去年年底写的一个名为JSPretty的美化家提供了扩展。功能颜色代码中的函数范围,并始终将颜色与该范围中声明的所有变量相关联。当在不同范围内使用具有来自一个范围的颜色的变量时,可视地演示闭合。

尝试以下功能:

观看演示:

查看以下代码:

目前,该功能支持深度为16的嵌套函数,但目前不对全局变量着色。

另一答案

JavaScript只有两种类型的范围:

  1. 全局范围:全局只不过是一个窗口级别的范围。这里,整个应用程序中存在变量。
  2. 功能范围:使用var关键字在函数内声明的变量具有功能范围。

无论何时调用函数,都会创建一个变量范围对象(并包含在范围链中),后面跟着JavaScript中的变量。

        a = "global";
         function outer(){ 
              b = "local";
              console.log(a+b); //"globallocal"
         }
outer();

范围链 - >

  1. 窗口级别 - aouter函数在范围链中处于顶层。
  2. 当外部函数称为新的variable scope object(并包含在范围链中)时,在其中添加了变量b

现在当变量a需要它时,它首先搜索最近的变量范围,如果变量不存在,则移动到变量范围链的下一个对象。在这种情况下,它是窗口级别。

另一答案

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

所以从这个角度来看,我认为一张图片可以帮助我在Kyle Simpson的Scopes and Closures电子书中找到:

image

引用他的电子书:

该建筑代表我们程序的嵌套范围规则集。无论您身在何处,建筑的第一层代表您当前执行的范围。建筑的顶层是全球范围。您可以通过查看当前楼层来解决LHS和RHS参考,如果找不到,请将电梯带到下一层,然后查看下一层,依此类推。一旦你到达顶层(全球范围),你要么找到你要找的东西,要么找不到。但你不得不停下来。

值得一提的是,“一旦找到第一场比赛,范围查找就会停止”。

这种“范围级别”的概念解释了为什么“这个”可以用新创建的范围进行更改,如果它是在嵌套函数中查找的话。这是一个链接,所有这些细节,Everything you wanted to know about javascript scope

另一答案

运行代码。希望这会给出一个关于范围界定的想法

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 + 
          "
Local Scope : " + Name + 
          "
Object Scope : " + this.Name + 
          "
Current document Scope : " + document.Name
         );
}


testFun.call(myObj);
})(window,document);
另一答案

全球范围:

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

//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    

Check this article for in-depth understanding of scope

另一答案

ALMOST只有两种类型的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范围;

所以你可以看到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 t

以上是关于JavaScript中的变量范围是什么?的主要内容,如果未能解决你的问题,请参考以下文章

通过 Javascript 中的变量范围维护变量

d3 javascript中的变量范围

地理定位功能中的 JavaScript 变量范围

JS---闭包

JavaScript函数作用域

什么是javaScript闭包