在javascript中正确重置全局变量?
因此,在中,人们正在讨论这样一个事实:在javascript中正确重置全局变量?,javascript,arrays,variables,scope,Javascript,Arrays,Variables,Scope,因此,在中,人们正在讨论这样一个事实: A = [1,2,3]; 然后做什么 A = []; 不会重置阵列,但会创建一个新阵列 如果我使用全局对象变量,我的问题是 myglobals = { A : [] } 我可以安全地使用重置阵列吗 myglobals.A = []; 对吧??因为它引用了相同的对象属性,所以我实际上并没有创建一个新数组,是吗 由于以下评论而更新问题 由于人们普遍认为,splice(0)是一条可行之路,而且由于一个非常类似的问题的答案解释了浏览器释放内存的影响,我想知
A = [1,2,3];
然后做什么
A = [];
不会重置阵列,但会创建一个新阵列
如果我使用全局对象变量,我的问题是
myglobals = { A : [] }
我可以安全地使用重置阵列吗
myglobals.A = [];
对吧??因为它引用了相同的对象属性,所以我实际上并没有创建一个新数组,是吗
由于以下评论而更新问题
由于人们普遍认为,
splice(0)
是一条可行之路,而且由于一个非常类似的问题的答案解释了浏览器释放内存的影响,我想知道设置任何定义的对象(无论是数组、函数还是字符串等)是否通常是安全和合适的要在保留其引用的同时重置其值,请执行null
?否,这仍然会创建一个新数组。重要的因素是赋值,而不是“A”变量所附加的范围。只要你做一些看起来像something=[]
的事情,JavaScript引擎就会制造一个新的数组对象([]
部分),然后给它分配一个引用给某物你正在创建一个新数组。如果要截断数组,只需将其长度设置为零:
var a = [1,2,3];
a.length = 0;
// a is now []
在您的对象属性示例中,情况完全相同。JavaScript中没有指针,只有引用值。因此,myglobals.A
的值是对数组的引用。当您为其分配一个新数组时,该值将成为另一个数组的新引用。实际上不是
// make a global variable
var a = [1,2,3];
// Assign it to something
var someObj = { value: a };
someObj.value; // [1,2,3];
// set a new value for the global
a = [];
a; // []
someObj.value; // [1,2,3];
这是您提到的初始代码。可以更改全局变量指向的对象,但不能更改要替换的对象的其他引用
第二个例子也存在同样的问题:
// make a global variable
var globals = { a: [1,2,3] };
// Assign it to something
var someObj = { value: globals.a };
someObj.value; // [1,2,3];
// set a new value for the global
globals.a = [];
globals.a; // []
someObj.value; // [1,2,3];
如果希望更新引用,则必须引用globals
容器对象。也就是说,另一个对象持有对容器的引用,然后您可以更改该容器的内容
// make a global variable
var globals = { a: [1,2,3] };
// assign a reference to the container in another object.
var someObj = { globals: globals };
someObj.globals.a; // [1,2,3];
// set a new value for the global
globals.a = [];
globals.a; // []
someObj.globals.a; // [];
这种想法可能会变得有点笨拙
您还可以通过全局更改对象引用,而不是替换它
var a = [1,2,3];
var b = a; // a and b now reference the same object.
a.splice(0); // remove all items from this array, without replace the array object.
a; // [];
b; // [];
// a and b now still point to the same array, which is now empty.
为什么删除会更好?如果你希望.length
告诉你真相的话,它真的会杀死手柄上的A
,下面的操作可能会让你在处理更大的对象时感到困惑
handle.A=[null];
handle.B=undefined;
handle.C=null;
handle.A.length=10;
console.log(handle, handle.length, handle.A.length);
在编码方面不是很节省,因为我将其设置为=10
,并且
您的脚本可能会假设有错误的东西要循环通过10个元素。
因此,handle.A=null
会有所帮助,但不会真正改变对象的结构。
但是它也不能破坏您的脚本,因为您有类似于var A
的东西,并且您可以使用它防止循环通过不存在的元素。同样适用于设置为未定义的,如下所示
要清除数组,需要删除对象上的所有元素(设置arr.length=0
实际上不会从数组中删除引用),合理清除数组的简明方法是:arr.splice(0)
@zzzzBov是否确定?因为var a=[1,2,3];a、 长度=0;a[1];//未定义的
arr.splice(0)
会影响当前数组引用(可能您认为类似的是arr.slice
),但清除数组项似乎是正确的。我的印象是,它只是掩盖了数组实例上属性的存在。因此,如果它应该是myglobals.A.splice(0)
,如果我的变量是对象,我该怎么做?我是否myglobals.A=未定义?正如下面所建议的那样?@zzzzBov是的,我读了“拼接”并想到了“切片”,然后意识到了错误。关于将长度设置为零,规范包括一个特殊的数组内部方法来处理长度变化,请参见我认为它应该是a.splice(0)
,在最后。一个对象仍然可以有它的原型,而且它必须!这就是javascript。原型对象,是否为空!因为即使null
是某种东西,它也不是什么,所以[]
也是某种东西,但是var A=undefined
是未定义的,但是存在某种原型/类型的as对象@亚历克斯23,谢谢你提到另一篇文章。似乎myglobals.A.splice(0)
实际上并不是最好的方法。从接受的答案中,我推断应该将其设置为null
,以便允许浏览器收集内存,对吗?@codelio,也许我不是在问我的问题,如果是这样的话,很抱歉。你下面的答案听起来不对:如果我设置A=undefined
,那么typeof(A)
返回undefined
,但是我希望得到对象null
并没有准备A
释放它占用的内存,因为它是null。查看var A=1;A=void(A)
,这也许就是你的意思,但它仍然是有效的,正如此刻的var A一样。如果将对象/值的父对象/值设置为不再具有该子对象,javascript将释放内存。console.log(a.constructor.name,typeof a)代码>/“Array”,“object”好吧,这只是现在将数组更改为空,而不是将其重置为Array
类型的变量。我想这样我可以做两个陈述:A=undefined;A=[]
但这是否确实删除了分配,还是仅仅添加了一个新的引用?那么A=null
呢?变量的任何重写都会起作用。A.length=0在任何时候都不起作用,这取决于A的类型。换句话说,它是由什么样的原型制成的。但是用低级类型重写总是会清空其中的所有内容,特别是在用它更改类型时,null
和undefined
会做什么!换句话说,一旦给定了变量,它就有了作用域!在什么地方
var handle={};
handle.A=[1,2,3,4,5,{x:2,y:3}];
console.log(handle);
delete handle.A;
console.log(handle); //A is gone!
handle.A=[null];
handle.B=undefined;
handle.C=null;
handle.A.length=10;
console.log(handle, handle.length, handle.A.length);