JavaScript闭包外部访问内部变量及数组数据获取问题
Hey there! Let's break down your questions and fix that code issue step by step.
先解答你的两个核心疑问
1. 如何在JavaScript闭包外部访问数组变量?
闭包内部的变量默认对外隐藏,但你可以通过**闭包暴露的公共方法(比如你代码里的setVar、getVar这类函数)**间接访问内部数组。这是闭包封装私有数据的标准做法——通过提供getter/setter接口,实现对内部数据的可控操作。
2. 能否访问JavaScript闭包内部声明的变量?
直接访问是做不到的,闭包的核心特性就是将内部变量私有化,外部作用域无法直接引用privateVar这类闭包内的局部变量。但你可以通过闭包返回的公共方法间接获取或修改这些内部变量,这也是你代码里getPrivateVar方法的设计目的。
你的代码为什么返回空值?
现在来看你的代码问题:你在privateVar里定义的arr是一个数组,但你却用了对象的键值对方式赋值(privateVar['arr'][name] = name2)。JavaScript数组本质是特殊对象,但它的"有效"元素基于数字索引,非数字的键会变成数组的附加属性,不会被计入数组的length,也不会在直接转成字符串时显示出来。
比如执行CLOSURE_VAR.setVar('abc', 'y')后,arr的length还是0,当你用console.log(CLOSURE_VAR.getPrivateVar('arr')+"--------------------")时,数组会被转成字符串,空数组的字符串就是"",所以看起来像是得到了空值。但实际上arr上已经有abc和def这两个属性了——你可以试试用console.dir(CLOSURE_VAR.getPrivateVar('arr')),就能看到这些隐藏的属性。
修复方案
根据你的需求(存储abc: "y"、def: "z"这类键值对),更合理的做法是把arr改成普通对象,因为你要的是键值映射,不是有序的数组元素:
var CLOSURE_VAR = (function() { var privateVar = { arr: {} }; // 将[]改为{},用对象存储键值对 return { setVar: function(name,name2) { privateVar['arr'][name] = name2; }, getVar: function(name) { return privateVar['arr'][name]; }, getPrivateVar: function(name) { return privateVar[name]; } }; }());
修改后,点击链接时console.log(CLOSURE_VAR.getPrivateVar('arr')+"--------------------")会输出[object Object]--------------------,如果想看到具体的键值内容,可以用JSON.stringify格式化:
console.log(JSON.stringify(CLOSURE_VAR.getPrivateVar('arr')) + "--------------------");
这样就会显示{"abc":"y","def":"z"}--------------------,完全符合你的预期。
如果你确实需要用数组(比如存储有序元素),那要调整setVar方法使用数字索引或push:
setVar: function(value) { privateVar['arr'].push(value); // 向数组添加元素 },
然后在initializeArr里调用CLOSURE_VAR.setVar({abc: "y"})来存储对象元素。
额外小提示
你提到的笔误MODULE.getPrivateVar('arr')改成CLOSURE_VAR.getPrivateVar('arr')是正确的,你的代码里已经修正了这一点,没问题。
内容的提问来源于stack exchange,提问作者Manas B

