Javascript变量范围和值

Rus*_*uss 8 javascript scope namespaces function

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());
Run Code Online (Sandbox Code Playgroud)

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

the*_*eye 6

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

使用Object literal创建Object时,左侧名称用于引用右侧名称已引用的对象.

在这种情况下,当你这样做

    blog: loca,
Run Code Online (Sandbox Code Playgroud)

你要说的blog是引用所引用的值loca,即5.随后当你递增时loca,它变为6,它意味着它引用了一些其他值,但blog仍然引用了该值5.

这就是你得到的原因5.

但是,当你这样做

namepace.frog()
Run Code Online (Sandbox Code Playgroud)

你得到的电流值loca.由于它被分配6getLocal,你得到6.

增量会创建新的数字对象

为了使它更清晰,当你这样做

loca += 1;
Run Code Online (Sandbox Code Playgroud)

要么

loca++;
Run Code Online (Sandbox Code Playgroud)

内部发生的是这样的事情

oldValue = loca
newValue = oldValue + 1
loca = newValue
Run Code Online (Sandbox Code Playgroud)

参考ECMAScript 5.1规范,for +=和for++

由于数字是不可变对象(你可以改变它的值5吗?你不能,这就是它被称为不可变对象的原因),创建一个新的数字对象,添加一个对象,并使名称loca引用新对象.


可变对象

如果你考虑可变对象,

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 ]
Run Code Online (Sandbox Code Playgroud)

现在,都blogloca参照相同的数组对象.发生的事情glob叫做变异.你只是增加一个元素与两个名字所指数组对象blogloca.这namepace.blog也是打印的原因[ 1 ].