Javascript中的作用域是什么

What is scope in Javascript?

本文关键字:是什么 作用域 Javascript      更新时间:2023-09-26

我不明白作用域是什么。我在某处读到作用域是访问variable的方法。但我发现,当一个变量可以通过作用域访问时,很难想出一个例子。函数中的所有变量都可以通过"全局"或"激活/变量"对象的上下文或通过闭包访问。下面是一段代码来演示我的意思:

var global_var = 7;
var f = (function() {
    var closure_var = 5;
    return function() {
        var local_var = 3;
        alert(local_var);  // alerts 3  - visible through context as Activation Object's property
        alert(closure_var); // alerts 5  - visible through closure
        alert(global_var); // alerts 7  - visible through context as Global Object's property
        alert(this.global_var); // alerts 7  - visible through context as Global Object's property
    }
})();
f();

那么范围是什么呢?以下是摘录和我的评论:

// a globally-scoped variable
var a=1;
// global scope
function one(){
    alert(a); 
}
// no, it's accessible as global object's context
// local scope
function two(a){
    alert(a);
}
// no, it's accessible as activation object's context

编辑:

感谢大家。我想我必须从变量和函数的角度来看待作用域。

Scope是变量处于活动状态的区域。像一个函数或一个页面。

global_var和f对于页面是全局的,因为它们在所有函数之外,所以它们对所有函数都可用。

local_var是函数f()的本地值,因此在函数f(()之外不可用。

我假设你知道计算机科学中的范围是什么。如果没有,请阅读wiki页面。

在javascript中,每个函数都有一个作用域。此外,还有一个全局作用域(当在任何函数之外时,定义的变量在全局作用域中定义,或者当在定义中不在var之前时,在函数中定义)。作用域是按层次划分的。如果在F中有一个函数F和一个函数G,当试图访问G中的一个变量时,它会检查该变量是否在G范围内定义。如果没有,它将在F范围内尝试。如果没有,它将在全球范围内进行尝试。

// global scope
var a = 1;
function F() {
    var a = 2;
    function G() {
        var a = 3;
        // here, a is 3
    }
    // here, a is 2
}
// here, a is 1

所有3个变量都是不同的(因为它们是用var定义的),您可以在全局范围内更改,在F或G中更改。

// global scope
var a = 1;
function F() {
    a = 2;
    function G() {
        a = 3;
        // here, a is 3
    }
    // G is called, a is changed..
    G();
    // here, a is 3
}
// F is called, a is changed..
F();
// here, a is 3

所有3个变量实际上都是一个,可以在任何地方访问(因为它在全局范围内)。更改将影响所有3个作用域。

// global scope
var a = 1;
function F() {
    a = 2;
    function G() {
       var a = 3;
        // here, a is 3
    }
    // here, a is 2
}
// here, a is 1

由于a是在G中定义的,在它的范围内,它是不同的,并且与外部隔离。也就是说,G之外的任何东西都不能访问或更改内部的变量a。他们将仅从全局范围中看到a(如果已定义)。另外,由于函数作用域的行为,G函数只存在于F内部,您不能从外部调用它。

将作用域视为容器。它们可以嵌套。你不能向内看,但他们可以向外看。

JavaScript有两个作用域:全局和本地。在函数定义之外声明的变量是全局变量,其值可以在整个程序中访问和修改。在函数定义中声明的变量是局部的。它是在每次执行函数时创建和销毁的,函数之外的任何代码都不能访问它。

取自MSDN关于变量作用域的页面。读一读!

可以直接访问任何变量的区域称为其本地作用域。在所有函数之外声明的任何变量都在全局范围内。因此,非常简单的局部作用域就是可以直接访问变量的区域。

但是局部作用域并不意味着您不能访问其作用域之外的任何变量。这里closure进入图片,这里是一个简单的闭包示例:

function a () {
    var q = 10; 
    return function () {
        alert(q++)
    }
}
var b = a();  // returns a function for which var q is local

现在,每次用b()调用b时,var q都会递增。

在JavaScript中,functionvariable的声明之间有一个区别。

您可以在函数声明的范围内的任何位置访问函数,但对于变量,只能在声明点之后访问。下面是一个例子:

function ab() { 
    t();   // alert 1
    alert(a1);    // alert undefined
    var a1 = 1000; // Now declare a1
    alert(a1);    // alert 1000
    function t() {  // define function
        alert(1);
    } 
}

我想我在这里找到了答案:

当创建执行上下文时,许多事情会按照定义的顺序发生

接下来,执行上下文被分配一个SCOPE。作用域由对象的列表(或链)组成。每个函数对象都有一个内部[[scope]]属性(我们稍后将对此进行更详细的介绍),该属性也由对象列表(或链)组成。分配给函数调用执行上下文的作用域由相应函数对象的[[scope]]属性引用的列表组成,激活对象添加在链的前面(或列表的顶部)。