Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/403.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript变量范围和值_Javascript_Function_Namespaces_Scope - Fatal编程技术网

Javascript变量范围和值

Javascript变量范围和值,javascript,function,namespaces,scope,Javascript,Function,Namespaces,Scope,我的问题是为什么函数alert(namepace.blog)返回5而不是我所期望的6?这里要理解的重要一点是,JavaScript中的所有名称都是对其他对象的引用 使用对象文字创建对象时,左侧名称用于引用已由右侧名称引用的对象 在这种情况下,当你 var namepace = (function () { var loca = 5; var getLocal = function () { loca += 1; return loca;

我的问题是为什么函数
alert(namepace.blog)返回
5
而不是我所期望的
6

这里要理解的重要一点是,JavaScript中的所有名称都是对其他对象的引用

使用对象文字创建对象时,左侧名称用于引用已由右侧名称引用的对象

在这种情况下,当你

var namepace = (function () {

    var loca = 5;

    var getLocal = function () {
        loca += 1;
        return loca;
    };

    return {
        glob: getLocal,
        blog: loca,
        frog: function () {
            return loca;
        }
    };
})();

alert(namepace.glob());
alert(namepace.blog);
alert(namepace.frog());
    blog: loca,
namepace.frog()
您所说的
blog
是指
loca
所指的值,即5。稍后,当您增加
loca
时,它变为
6
,这意味着它引用了一些其他值,但
blog
仍然引用值
5

这就是为什么您会得到
5

但当你这么做的时候

var namepace = (function () {

    var loca = 5;

    var getLocal = function () {
        loca += 1;
        return loca;
    };

    return {
        glob: getLocal,
        blog: loca,
        frog: function () {
            return loca;
        }
    };
})();

alert(namepace.glob());
alert(namepace.blog);
alert(namepace.frog());
    blog: loca,
namepace.frog()
您正在获取由
loca
引用的当前值。由于它是在
getLocal
中分配的
6
,因此您将获得
6

递增创建新的数字对象

更清楚地说,当你这么做的时候

var namepace = (function () {

    var loca = 5;

    var getLocal = function () {
        loca += 1;
        return loca;
    };

    return {
        glob: getLocal,
        blog: loca,
        frog: function () {
            return loca;
        }
    };
})();

alert(namepace.glob());
alert(namepace.blog);
alert(namepace.frog());
    blog: loca,
namepace.frog()

内部发生的是,类似这样的事情

loca++;
参考ECMAScript 5.1规范,用于和

由于数字是不可变对象(您可以更改
5
的值吗?您不能更改,这就是为什么它被称为不可变对象的原因),因此会创建一个新的数字对象,并在其中添加一个对象,并使名称
loca
引用新对象


可变对象

如果你考虑可变对象

oldValue = loca
newValue = oldValue + 1
loca = newValue

现在,
blog
loca
都引用相同的数组对象。在
glob
中发生的事情称为变异。您只是将一个元素添加到数组对象中,该数组对象具有两个名称
blog
loca
。这就是为什么
namepace.blog
也会打印
[1]

这是一个逻辑问题。当函数需要一些时间时。在指定的时间变量中。。看看下面的代码。试试这个

var namepace = (function () {

    var loca = [];

    return {
        glob: function () {
            loca.push(1);
            return loca;
        },
        blog: loca,
        frog: function () {
            return loca;
        }
    };
})();

console.log(namepace.glob());
// [ 1 ]
console.log(namepace.blog);
// [ 1 ]
console.log(namepace.frog());
// [ 1 ]

当分配给
namespace.blog
时,您使用的是传递给setter的值。这意味着没有关于
loca
的参考

当您通过
namespace.frog
访问该值时,您使用的是原始变量,该变量利用JavaScript的闭包作用域解析为
loca
,本地作用域链上的下一个可用定义


您可以在这里阅读有关作用域的内容:

当JavaScript程序运行时,考虑执行上下文会有所帮助。JavaScript计算引用(而不是直接计算值)

全局上下文由全局变量和对象组成。在这种情况下(JavaScript解释器读取名称空间指令时):

这意味着命名空间正在引用函数。在第一个警报时,将为命名空间创建以下执行上下文:

namespace = {f}  // namespace references a function
因此,函数glob被调用。glob引用名为getLocal的函数。glob的执行上下文如下所示:

loca = 5                // loca references the value 5
getLocal = {f}          // getLocal references a function
return {                // return object with glob, blog and frog as properties
  glob = { getLocal() } // references the function getLocal()
  blog = 5              // blog references same value as loca: 5
  frog = {f}            // references anonymous function
}
下一个调用是blog,这个调用返回值5。它不涉及loca。它仅引用loca在创建执行上下文时具有的值。创建执行上下文时,loca引用的值为5,因此博客引用的值为5。 无论你多久调用一次glob,blog都会引用5的值

在最后一条alert语句中,将调用frog。frog引用了一个现在正在执行的匿名函数。frog的执行上下文如下

loca = 6      // loca now references the value 6
return loca   // return value referenced by loca
基本上就是这样。每当你想到价值时,试着去想“参考价值”。这有助于习惯它。并尝试在程序运行时可视化执行上下文(如作为人工调试器)