OO Javascript:变量范围的明确解释
有人可以提供JS中变量范围的解释,因为它适用于对象,函数和闭包?
解决方案
未使用var声明的变量在作用域内是全局的。
函数引入作用域,但请注意,如果块和其他块未引入作用域。
通过Googling Javascript范围,我还可以看到很多有关此的信息。那真的是我所建议的。
http://www.digital-web.com/articles/scope_in_javascript/
全局变量
Javascript中的每个变量都是对象的命名属性。例如:-
var x = 1;
x被添加到全局对象。全局对象由脚本上下文提供,并且可能已经具有一组属性。例如,在浏览器中,全局对象是窗口。在浏览器中,等同于以上一行的内容是:-
window.x = 1;
局部变量
现在,如果我们将其更改为:-
function fn() { var x = 1; }
当调用" fn"时,将创建一个称为执行上下文的新对象,该执行上下文也称为范围(我可以互换使用这些术语)。 x被添加为该范围对象的属性。因此,每次对" fn"的调用都将获得其自己的范围对象实例,并因此获得其自身的x属性实例,该属性添加到该范围对象。
关闭
现在让我们进一步:
function fnSequence() { var x = 1; return function() { return x++; } } var fn1 = fnSequence(); var fn2 = fnSequence(); WScript.Echo(fn1()) WScript.Echo(fn2()) WScript.Echo(fn1()) WScript.Echo(fn2()) WScript.Echo(fn1()) WScript.Echo(fn1()) WScript.Echo(fn2()) WScript.Echo(fn2())
注意:在上下文中,用对stdout的任何写入替换WScript.Echo
。
我们应该获得的顺序是:-
1 1 2 2 3 4 3 4
那么这里发生了什么?我们有一个fnSequence,它将变量x初始化为1并返回一个匿名函数,该函数将返回x的值然后递增它。
第一次执行此函数时,将创建一个范围对象,并向该范围对象添加属性x,其值为1. 匿名函数也在同一个执行对象中创建。每个函数对象都有一个scope属性,该属性指向创建它的执行上下文。这将创建称为作用域链的内容,我们将在后面介绍。 fnSequence返回该函数的引用,并将其存储在fn1中。
注意,fn1
现在指向匿名函数,并且匿名函数具有一个scope属性,该scope属性指向一个仍然添加了x
属性的作用域对象。这称为"关闭",在该上下文中,为执行创建的功能完成执行后,仍然可以访问执行上下文的内容。
现在,当分配给fn2
时,也会发生相同的序列。 fn2将指向另一个匿名函数,该匿名函数是在第二次调用fnSequence时创建的不同执行上下文中创建的。
范围链
第一次执行" fn1"所拥有的功能时会发生什么?为执行匿名函数创建了一个新的执行上下文。从标识符" x"中可以找到一个返回值。检查该函数的范围对象的x属性,但没有找到。这就是作用域链的所在。在当前执行上下文中未能找到" x"时,JavaScript会将函数的scope属性所持有的对象带到那里,并在其中寻找" x"。由于函数范围是在fnSequence执行中创建的,因此会找到它,并检索其值并对其进行递增。因此,输出1,并且此范围内的`x'递增为2.
现在,当执行" fn2"时,它最终会添加到另一个" x"属性仍为1的执行上下文中。因此,执行" fn2"也会得到1.
如我们所见,fn1
和fn2
各自生成各自独立的数字序列。
函数引入作用域。我们可以在其他函数中声明函数,从而创建嵌套作用域。内部范围可以访问外部范围,但是外部范围不能访问内部范围。
使用var关键字将变量绑定到作用域。所有变量都隐式绑定到顶级范围。因此,如果省略var关键字,则隐式地引用绑定到顶级的变量。在浏览器中,顶层是窗口对象。注意window是它自身的变量,所以window == window.window