Javascript 基础知识:变量范围

Javascript basics: variable scope

本文关键字:范围 变量 基础知识 Javascript      更新时间:2023-09-26

我正在学习javascript,有人可以为我解释以下代码片段吗?


var state=true;
function bob(){ var state=false; }
bob() 

状态值应该是什么,为什么?

非常感谢,L

在执行结束时,state将被true,因为函数bob()定义了一个名为 state 的局部变量,而不是分配给同名的全局变量。 但是,在以下示例中,state为 false:

var state=true;
function bob(){ state=false; }
bob();

通过省略var关键字,JavaScript引擎将在作用域链中向上移动,寻找一个名为state的变量,直到找到一个变量或到达全局作用域。 这可以通过嵌套函数进一步证明:

var state = true; // global
function bob() {
    var state = true; // local to `bob()` 
    function jim() {
        state = false;
    }
    jim();
    alert(state); //-> false, `jim()` modifies `bob()`'s variable
}
bob();
alert(state); //-> true, `jim()` and `bob()` don't touch the global variable

关于ECMA-/Javascript的一个非常重要的事实是,只有函数作用域

这是我教给任何正在学习它的人的第一件事。Javascript的另一个概念是作用域链。简而言之,这是保存在上下文中的内部属性。每个函数创建一个(执行)上下文,并将所有父上下文存储在其内部 [[Scope]] 属性中。现在,当您访问函数中的变量名称时,Javascript 解释器会尝试解析该变量。搜索从它自己的激活对象开始(另一件事,我将跳过这里的解释),如果找到它,搜索就会停止。如果找不到变量,Javascript 将访问其 [[Scope]] 属性,并按词法(词法作用域...)从所有父作用域中搜索激活对象。

然后采用该变量的第一个匹配项。如果在作用域链中的任何位置都找不到变量名,则返回undefined

现在,在您的代码段中,我们将创建变量state两次。第一次,全局上下文将变量存储在其变量对象中(与激活对象相同,但用于非函数上下文)。

第二次,我们在bob()的执行上下文中创建state,Javascript将其存储在它的激活对象中。因此,当我们在上下文中访问stateBob ,它总是false ,因为我们的分辨率查找过程始于我们自己的激活对象。

如果我们访问Bob之外的state,我们只会在 Variable 对象中找到变量state从全局上下文(实际上是全局对象本身)中,它true在那里。


关于整个主题的更多和更准确的信息:
http://dmitrysoshnikov.com/ecmascript/javascript-the-core/

var state=true; //global scope variable called 'state' => true
function bob(){ 
  var state=false; //local scope variable called 'state' => false, no global 'state' overwritten
  //state = false; would overwrite global 'state'
}
bob(); //call function
//global 'state' remains true
如果要

将全局"state"值更改为false,请执行以下操作(无需(重新)声明bob()函数的局部变量):

var state=true;
function bob(){ state=false; }
bob()

状态将为:

false

如果将其更改为以下内容:

var state=true;
function bob(){ state=false; }
bob();

然后在执行结束时,state将被false.这是因为 bob() 中的执行上下文将查找一个名为 state 的局部变量,它不会找到该变量(在state声明新的局部变量之前没有var),如果找不到,它将移动到下一个词法上下文,在那里它将看到您的全局变量scope, 它修改为false.

当我们声明状态 = true 时。它是全球范围。在函数内部,我们正在更改状态的值。因此,我们正在改变全球范围的价值。因此,更改后,全局值将始终为假。