数组过滤器更改主数组

内达斯

我注意到在node.js的数组过滤器中有一些奇怪的行为。有一个简单的数组和一个循环:

var array = [
{
    name:"bob",
    planet:"earth"
},
{
    name:"mike",
    planet:"mars"
},
{
    name:"vlad",
    planet:"jupiter"
}];

var filtered = array.filter(function(x){
    return x.name !== "mike";
});

console.log(array); //lets print how normal array looks like
console.log("---");
console.log(filtered); //lets print how filtered one looks like

for(var i = 0; i < filtered.length; i++)
{
    delete filtered[i].planet; //remove planet
    filtered[i].name = filtered[i].name + "[NEW]"; //add NEW to the name
}

console.log("After replacement:");
console.log(array);//lets print how normal array looks like now
console.log("-----------");
console.log(filtered);//lets print how filtered array looks like now

从理论上讲,array不应更改数组,因为我没有以任何方式对其进行操作。Hovewer,这是我在控制台中得到的:

[ { name: 'bob', planet: 'earth' },
  { name: 'mike', planet: 'mars' },
  { name: 'vlad', planet: 'jupiter' } ] //this array is normal
---
[ { name: 'bob', planet: 'earth' },
  { name: 'vlad', planet: 'jupiter' } ] //this is good behavior, since I don't need "mike"

After replacement:

[ { name: 'bob[NEW]' },
  { name: 'mike', planet: 'mars' },
  { name: 'vlad[NEW]' } ] //this should not be changed in any way
-----------
[ { name: 'bob[NEW]' }, { name: 'vlad[NEW]' } ] //this is correct

为什么会这样?我需要array保持一开始就一样。

谢谢。

TJ人群

您的代码在这里:

for(var i = 0; i < filtered.length; i++)
{
    delete filtered[i].planet; //remove planet
    filtered[i].name = filtered[i].name + "[NEW]"; //add NEW to the name
}

...没有改变任何一个数组。它正在改变两个数组所引用的对象的状态。

比较简单的例子:

var a = [{answer:null}];
var b = a.filter(function() { return true; }); // Just a copy, but using `filter` for emphasis
a[0].answer = 42;
console.log(b[0].answer); // 42

这行:

a[0].answer = 42;

不会更改ab,它会更改所a[0]引用对象(b[0] 就是引用对象)的状态

让我们扔一些ASCII-art Unicode -art:

在此行之后:

var a = [{answer:null}];

这就是我们记忆中的内容(忽略了一些无关紧要的细节);

+------------+
| 变量“ a” |
+------------+ +-----------
| Ref11542 | ---- >> 数组|
+------------+ +-------------+
                     | 0:Ref88464 | ---- >> 对象
                     +------------+ +-----------
                                          | 答案:null |
                                          +------------+

a引用具有0属性的数组对象,引用具有该answer属性的对象我使用“Ref11542”和“Ref88494”来表示的对象引用aa[0]包含,但当然我们从来没有真正看到这些参考值; 它们是JavaScript引擎专用的。

然后我们这样做:

var b = a.filter(function() { return true; }); // Just a copy, but using `filter` for emphasis

现在我们有:

+------------+
| 变量“ a” |
+------------+ +-----------
| Ref11542 | ---- >> 数组|
+------------+ +-----------   
                     | 0:Ref88464 |-+
                     +-----------
                                       |
                                       | +------------+
+------------+ +-> | 对象
| 变量“ b” | | +------------+
+------------+ | | 答案:null |
| Ref66854 | ---- >> 数组| | +------------+
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------年年级
                     | 0:Ref88464 |-+
                     +------------+

请注意,两个数组都包含相同的对象引用(此处显示为“ Ref88464”);他们指向同一个对象。

现在我们这样做:

a[0].answer = 42;

所要做的就是改变对象的状态。它有没有影响ab或阵列它们指的是:

+------------+
| 变量“ a” |
+------------+ +-----------
| Ref11542 | ---- >> 数组|
+------------+ +-----------   
                     | 0:Ref88464 |-+
                     +-----------
                                       |
                                       | +------------+
+------------+ +-> | 对象
| 变量“ b” | | +------------+
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------年年级 | 答案:42 |
| Ref66854 | ---- >> 数组| | +------------+
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------年年级 ^
                     | 0:Ref88464 | − + + −−−−−−−只有变化在这里
                     +------------+

很自然

console.log(b[0].answer);

...输出42。


在评论中,您要求:

但是,如何设置过滤对象而不是主要对象的状态?

请记住,两个数组中对象相同。您尚未复制对象,只是创建了一个仅包含其中一些对象的新数组。

如果希望能够更改那些对象的属性而又不影响第一个数组中的对象,则需要制作这些对象的副本

如果对象仅包含简单的原始值,那很容易;否则,这很简单。一般情况很难。:-)

但是,就您的情况而言,由于您的对象仅具有nameplanet属性,并且接下来要做的就是删除该planet属性并更改名称,因此我们可以轻松地创建对象。看评论:

var array = [
{
    name:"bob",
    planet:"earth"
},
{
    name:"mike",
    planet:"mars"
},
{
    name:"vlad",
    planet:"jupiter"
}];

var filtered = array.filter(function(x){
    return x.name !== "mike";
}).map(function(x) {
    // Create a *new* object, setting its `name` to the `name`
    // of the original object plus [NEW], and ignoring its
    // `planet` property entirely
    return {name: x.name + "[NEW]"};
});

console.log(array);
console.log("---");
console.log(filtered);

或者,您可能只想对数组进行一次遍历:

var filtered = [];
array.forEach(function(x){
    if (x.name !== "mike") {
        filtered.push({name: x.name + "[NEW]"});
    }
});

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

部分数组过滤器

来自分类Dev

MuleSoft JSON 数组过滤器

来自分类Dev

数组过滤器,使用键过滤数据

来自分类Dev

如何使用Javascript数组过滤器过滤0?

来自分类Dev

使用数组过滤器方法更改对象序列(Javascript)

来自分类Dev

通过检查多个条件的Javascript数组过滤器

来自分类Dev

javascript在数组过滤器内嵌套for循环

来自分类Dev

Knockout.Js数组过滤器语法

来自分类Dev

数组过滤器的异步或承诺条件

来自分类Dev

数组过滤器返回奇怪的结果

来自分类Dev

具有JSON数组过滤器的Filterpredicate

来自分类Dev

数组过滤器未返回正确的值

来自分类Dev

PHP数组过滤器有多个条件

来自分类Dev

循环内部数组过滤器方法

来自分类Dev

使用keep_if的数组过滤器

来自分类Dev

数组过滤器的异步或承诺条件

来自分类Dev

基于多列的数组过滤器

来自分类Dev

具有绑定值的数组过滤器

来自分类Dev

javascript在数组过滤器内嵌套for循环

来自分类Dev

通过数组过滤器长度查询ElasticSearch

来自分类Dev

Elasticsearch - 数组过滤器中的值

来自分类Dev

php数组过滤器函数问题与变量

来自分类Dev

用于执行函数的 Javascript 数组过滤器

来自分类Dev

反应多维数组过滤器/查找

来自分类Dev

数组过滤器不适用于状态

来自分类Dev

Angular 2 - 比较数组过滤器中的日期

来自分类Dev

数组过滤器方法不起作用

来自分类Dev

如何使用数组过滤器在数组内的对象内查找值,然后更改/编辑该值?

来自分类Dev

使用组合的嵌套数组过滤器过滤 JSON 数组