Javascript 在数组中存储对项的引用

Javascript 在数组中存储对项的引用,javascript,reference,Javascript,Reference,我希望变量'item'不仅在数组中存储项的值,而且还存储对数组的引用,因此当我更改它时,它也会在原始数组中更改 arr=['a','b','c','d','e'] 项目=arr[2]/'c' 项目='f' console.logarr我真的不建议这样做,但为了科学起见,您可以将字符串包装到对象。然后,您可以自动检索对象并修改其值: 常数arr=[ { “值”:“a” } ] const item=arr[0]/{'value':'a'} item.value='c' console.loga

我希望变量'item'不仅在数组中存储项的值,而且还存储对数组的引用,因此当我更改它时,它也会在原始数组中更改

arr=['a','b','c','d','e'] 项目=arr[2]/'c' 项目='f'
console.logarr我真的不建议这样做,但为了科学起见,您可以将字符串包装到对象。然后,您可以自动检索对象并修改其值:

常数arr=[ { “值”:“a” } ] const item=arr[0]/{'value':'a'} item.value='c' console.logarr
//{'value':'c'}我真的不建议这样做,但为了科学起见,您可以将字符串包装到对象。然后,您可以自动检索对象并修改其值:

常数arr=[ { “值”:“a” } ] const item=arr[0]/{'value':'a'} item.value='c' console.logarr
//{'value':'c'}这是一个可怕想法的可怕例子——它只在根全局范围内有效。它利用了这样一个事实,即顶级变量也是web浏览器中全局对象的属性,窗口对象也是全局对象:


但是你永远不应该这样做。

这里有一个可怕想法的可怕例子——它只在根全局范围内起作用。它利用了这样一个事实,即顶级变量也是web浏览器中全局对象的属性,窗口对象也是全局对象:


但是你永远不应该这样做。

正如其他人所说,这不是JS处理原语的方式

但是,我不认识你,你这样做可能有完全正当的理由

如果您想这样做,我建议您过于明确,这样其他开发人员就不会在与您的代码交互时攻击自己

在这里,我创建了一个可变类,其中包含对值的引用。然后您可以使用

您可以使用valueOf方法,然后允许将类用作原语。请参见示例的最后一行,您可以从数组中提取值,然后将其当作数字使用,而无需通过数组[0]展开。值

更新-根据@Dai的建议,添加了基本检查:

类可变{ 构造函数值{ 这个。强制原始值; 这个值=值; } setValuevalue{ 这个。强制原始值; 这个值=值; } 价值{ 返回此.value; } 强制执行原语值{ if!this.isPrimitivevalue{ 抛出新错误`传递给可变的非原语值:${JSON.stringifyvalue}`; } } 异基性试验{ 返回测试!==Objecttest; } } 常量数组=[ 新可变1, 新可变2, 新可变3, ]; console.logarray[0];//日志1 const first=数组[0]; 第一,设置值2; console.logarray[0];//日志2 console.logarray[0]+3;//日志5
正如其他人所说,这不是JS处理原语的方式

但是,我不认识你,你这样做可能有完全正当的理由

如果您想这样做,我建议您过于明确,这样其他开发人员就不会在与您的代码交互时攻击自己

在这里,我创建了一个可变类,其中包含对值的引用。然后您可以使用

您可以使用valueOf方法,然后允许将类用作原语。请参见示例的最后一行,您可以从数组中提取值,然后将其当作数字使用,而无需通过数组[0]展开。值

更新-根据@Dai的建议,添加了基本检查:

类可变{ 构造函数值{ 这个。强制原始值; 这个值=值; } setValuevalue{ 这个。强制原始值; 这个值=值; } 价值{ 返回此.value; } 强制执行原语值{ if!this.isPrimitivevalue{ 抛出新错误`传递给可变的非原语值:${JSON.stringifyvalue}`; } } 异基性试验{ 返回测试!==Objecttest; } } 常量数组=[ 新可变1, 新可变2, 新可变3, ]; console.logarray[0];//日志1 const first=数组[0]; 第一,设置值2; console.logarray[0];//日志2 console.logarray[0]+3;//日志5
为了扩展@Dai修改窗口属性的可怕想法,我建议更可怕的解决方案是使用代理动态地进行修改

常数arr=[a,b,c,d,e] 常量处理程序={ get:target,prop=>{ Object.DefineProperties窗口{ 项目:{ 获取:=>target[prop], set:val=>target[prop]=val, 可枚举:正确, 可配置:true } } 返回窗口项; }, 设置:target,prop,val=>target[prop]=val } const arrayProxy=新代理,处理程序; item=arrayProxy[0]; 控制台。登录项:,项; 项目=f; log{item,arrayProxy,arr}; item=arrayProxy[1 ]; 项目=g
log{item,arrayProxy,arr} 为了扩展@Dai修改窗口属性的可怕想法,我建议更可怕的解决方案是使用代理动态地进行修改

常数arr=[a,b,c,d,e] 常量处理程序={ get:target,prop=>{ Object.DefineProperties窗口{ 项目:{ 获取:=>target[prop], set:val=>target[prop]=val, 可枚举:正确, 可配置:true } } 返回窗口项; }, 设置:target,prop,val=>target[prop]=val } const arrayProxy=新代理,处理程序; item=arrayProxy[0]; 控制台。登录项:,项; 项目=f; log{item,arrayProxy,arr}; 项目=arrayProxy[1]; 项目=g

log{item,arrayProxy,arr};JavaScript不支持对标量值的引用。您可能可以通过隐式转换来破解某些东西,但并不容易;然后项='f'。。。现在,您认为item的值是什么?这不起作用,因为arr[2]是c,它是一个基本值。为什么要这样做?我想读取和更改数组中的值,但不每次调用引用。JavaScript不支持对标量值的引用。您可能可以通过隐式转换来破解某些东西,但并不容易;然后项='f'。。。现在,你认为item的值是什么?这不起作用,因为arr[2]是c,它是一个原始值。为什么要这样做?我想读取和更改数组中的值,但不每次调用引用。这会让程序员噩梦:p这是一个非常好的方法,我希望我不会在生产中看到它……所以简而言之,用户必须为每个数组索引定义多个getter和setter。@sandeepjoshi不一定。这完全取决于他们想做什么。还有其他快捷方式和技巧可用于别名数组元素。这是一个很疯狂的方法+1对于开箱即用的思考,-1因为我希望没有人这样做这会让程序员噩梦:p这是一个非常好的方法,我希望我不会在生产中看到它…所以简而言之,用户必须为每个数组索引定义多个getter和setter。@sandeepjoshi不一定。这完全取决于他们想做什么。还有其他快捷方式和技巧可用于别名数组元素。这是一个很疯狂的方法+1对于开箱即用的思考,-1因为我希望没有人会这样做,valueOf必须返回一个原始值。我建议您在构造函数中添加typeof检查,并在提供非原语值时将setValue设置为fast fail。@Dai有趣,不知道这一点。你知道如果你不提供一个原语的话,这会不会引发错误吗?老实说,不会,因为我从来没有犯过错误:注意valueOf必须返回一个原语值。我建议您在构造函数中添加typeof检查,并在提供非原语值时将setValue设置为fast fail。@Dai有趣,不知道这一点。你知道如果你不提供一个原语,这会不会出现错误吗?老实说,不会,因为我从来没有犯过错误:哇,这太糟糕了:我非常喜欢这个。而且也讨厌它哇,这太糟糕了:我非常喜欢这个。而且也讨厌它
Object.defineProperty( window, 'item', {
    get: function() { return window.arr[2]; },
    set: function( v ) { window.arr[2] = v; }
} );

var arr = ['a', 'b', 'c', 'd', 'e'];

console.log( arr ); // ["a", "b", "c", "d", "e"]
console.log( item ); // 'c'

item = 'f';

console.log( arr ); // ["a", "b", "f", "d", "e"]
console.log( item ); // 'f'

arr[2] = 'life is short and love is always over in the morning';

console.log( arr ); // ["a", "b", "life is short and love is always over in the morning", "d", "e"]
console.log( item ); // 'life is short and love is always over in the morning'