OO Javascript:变量范围的确切解释 [英] OO Javascript : Definitive explanation of variable scope

查看:134
本文介绍了OO Javascript:变量范围的确切解释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以在JS中提供变量范围的解释,因为它适用于对象,函数和闭包吗?

Can someone provide an explanation of variable scope in JS as it applies to objects, functions and closures?

推荐答案

全局变量



Javascript中的每个变量都是命名属性一个对象。例如: -

Global variables

Every variable in Javascript is a named attribute of an object. For example:-

var x = 1;

x被添加到全局对象。全局对象由脚本上下文提供,并且可能已经具有一组属性。例如,在浏览器中,全局对象是窗口。与浏览器中的上述行相同的是: -

x is added to the global object. The global object is provided by the script context and may already have a set of attributes. For example in a browser the global object is window. An equivalent to the above line in a browser would be:-

window.x = 1;



本地变量



现在如果我们怎么办?将此更改为: -

Local variables

Now what if we change this to:-

function fn()
{
    var x = 1;
}

fn 是称为新对象,称为执行上下文,也称为范围(我可以互换使用这些术语)。 x 作为属性添加到此范围对象。因此,对 fn 的每次调用都将获得自己的范围对象实例,因此它自己的x属性实例附加到该范围对象。

When fn is called a new object is created called the execution context also referred to as the scope (I use these terms interchangeably). x is added as an attribute to this scope object. Hence each call to fn will get its own instance of a scope object and therefore its own instance of the x attribute attached to that scope object.

现在让我们进一步: -

Now lets take this further:-

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())

注意:替换 WScript.Echo 在您的上下文中写入stdout的任何内容。

Note: Replace WScript.Echo with whatever writes to stdout in your context.

您应该得到的序列是: -

The sequence you should get is :-

1 1 2 2 3 4 3 4

1 1 2 2 3 4 3 4

那么这里发生了什么?我们有 fnSequence ,它将变量 x 初始化为1并返回一个匿名函数,该函数将返回<$ c的值$ c> x 然后递增它。

So what has happened here? We have fnSequence which initialises a variable x to 1 and returns an anonymous function which will return the value of x and then increment it.

首次执行此函数时,会创建一个范围对象并且属性 x 被添加到该范围对象中,值为1.还在同一执行对象中创建了一个匿名函数。每个函数对象都有一个scope属性,该属性指向创建它的执行上下文。这会创建一个我们将在稍后介绍的范围链 fnSequence 返回对此函数的引用,并存储在 fn1 中。

When this function is first executed a scope object is created and an attribute x is added to that scope object with the value of 1. Also created in the same execution object is an anonymous function. Each function object will have a scope attribute which points to the execution context in which it is created. This creates what is know as a scope chain which we will come to later. A reference to this function is returned by fnSequence and stored in fn1.

注意 fn1 现在指向匿名函数,并且匿名函数的scope属性指向仍然具有<$ c $的范围对象附加c> x 属性。这称为 closure ,其中执行上下文的内容在创建的函数完成执行后仍然可以访问。

Note that fn1 is now pointing at the anonymous function and that the anonymous function has a scope attribute pointing at a scope object that still has an x attribute attached. This is known as closure where the contents of an execution context is still reachable after the function it was created for has completed execution.

现在,当分配给 fn2 时会发生同样的序列。 fn2 将指向在调用 fnSequence 时创建的不同执行上下文中创建的不同匿名函数第二次。

Now this same sequence happens when assigning to fn2. fn2 will be pointing at a different anonymous function that was created in a different execution context that was create when fnSequence was called this second time.

fn1持有的函数时会发生什么是第一次执行?为执行匿名函数创建新的执行上下文。可以从标识符 x 中找到返回值。检查函数的范围对象是否为 x 属性,但未找到任何属性。这就是范围链的用武之地。在当前执行上下文中找不到 x ,JavaScript获取了函数的scope属性所持有的对象,在那里寻找 x 。它找到它,因为函数范围是在 fnSequence 的执行中创建的,检索它的值并递增它。因此输出1并且此范围中的 x 增加到2.

What happens when the function held by fn1 is executed the first time? A new execution context is created for the execution of the anonymous function. A return value is to be found from the identifier x. The function's scope object is inspected for an x attribute but none is found. This is where the scope chain comes in. Having failed to find x in the current execution context JavaScript takes the object held by the function's scope attribute and looks for x there. It finds it since the functions scope was created inside an execution of fnSequence, retrieves its value and increments it. Hence 1 is output and the x in this scope is incremented to 2.

现在 fn2 被执行它最终附加到一个不同的执行上下文,其 x 属性仍为1.因此执行 fn2 也会产生1。

Now when fn2 is executed it is ultimately attached to a different execution context whose x attribute is still 1. Hence executing fn2 also results in 1.

如你所见 fn1 fn2 每个都生成自己独立的数字序列。

As you can see fn1 and fn2 each generate their own independent sequence of numbers.

这篇关于OO Javascript:变量范围的确切解释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆