【问题标题】:Difference between push and assignment in JavaScript arrayJavaScript数组中推送和赋值的区别
【发布时间】:2020-12-19 14:44:42
【问题描述】:
async getModifiedData() {
  let dbData = await dbdata.getData();
  
  let fileData = [];

  dbData.map(data => {
    fileData[data["uniquePropertyName"]] = data;
  });

  return fileData; // here I'm getting empty array
}

而我在使用 push() 方法时得到填充数组,

async getModifiedData() {
  let dbData = await dbdata.getData();
  
  let fileData = [];

  dbData.map(data => {
    let propertyName = data["uniquePropertyName"];
    let obj = {};
    obj[propertyName] = data;
    fileData.push(obj);
  });

  return fileData; // here I'm getting filled array
}

当数组大小较小时,两者都可以正常工作,但对于较大的数组,Array.push() 仅返回填充数组。谁能解释这里发生了什么。

【问题讨论】:

  • 请不要使用.map() 进行单次迭代。使用.forEach() 或一个简单的循环。
  • @VLAZ 在这种情况下,.map() 将是正确的工具,如果没有以错误的方式使用...fileData = dbData.map(data => /*...*/ return obj)
  • 数组是特殊的对象。所有对象都支持分配给任意属性名称。对任意属性名称的赋值不会自动将这些值插入到我们在引用数组内容时想到的特殊可迭代集合中。
  • 第一个例子在我看来不合适。 data["uniquePropertyName"] 是否返回唯一索引(= 数字)?否则fileData 应该是一个对象而不是一个数组(而map() 应该是.forEach()

标签: javascript arrays push


【解决方案1】:

您可以将某些内容分配给数组或对象,但您执行此操作的方式不同。 如果您将某些内容分配给数组,则应该使用索引(尽管@tehhowch 的回答是正确的,但我们从不以与对象相同的方式将值分配给数组)。如果你要给一个对象赋值,你应该使用键值(通常,但不总是,字符串)。

另外,正如其他人所提到的,.map 在对另一个数组中的每个元素执行某些操作后返回一个新数组。 .map 需要返回一个值。 .forEach 只是编写 for 循环的一种更短的方式;它会遍历数组(或任何可迭代对象)中的每个值并执行某些操作,但它不需要返回某些内容,也不需要返回某些内容不能

.push 只是将一些东西推入一个数组(到最后,而不是开始)

为清楚起见,以下示例。

//.map
const example = [1, 2, 3, 4];
const exampleDoubled = example.map(number => {
  return number * 2;
});
console.log(exampleDoubled);
//expected output: [2, 4, 6, 8]

//.forEach
example.forEach(number => {
  //for each number, do something
  console.log(number);

  // no return value needed
});
//expected output:
//1
//2
//3
//4

//Assigning to an array
const newArray = Array(3);
newArray[0] = 1;
newArray[1] = 2;
newArray[2] = 3;
console.log(newArray);
//expected output: [1, 2, 3]
//Notice that we're assigning using indexes because we're dealing with an array


//Assigning to an object
const newObject = {};
newObject['anyKey'] = "any value. does not have to be a string";
newObject['someOtherKey'] = function() { //do stuff };
console.log(newObject);
//expected output:
// {
// 'anyKey': "any value. does not have to be a string",
// 'someOtherKey': [Function]
//}

//.push
const myArray = [1, 2, 3];
myArray.push(4);
console.log(myArray);
//expected output: [1, 2, 3, 4]

我猜你想要的代码是什么(我不知道数据是什么样的,所以我不能给你一个确切的答案);

async getModifiedData() {
  let dbData = await dbdata.getData();
  
  let fileData = dbData.map(data => {
    return data["uniquePropertyName"];
    //assuming here that data is an object and you want an array
    //of a particular value from these objects
  });

  return fileData;
}

希望这会有所帮助!您可以随时查看 MDN 和 W3Schools 文档以获取更多信息。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push

【讨论】:

    【解决方案2】:

    为简化起见,您的代码中有几个不同的问题,但我将重点介绍为什么第一个示例实际上并未填充数组:

    在 JavaScript 中,您可以通过使用方括号中的数字索引直接分配给数组槽来将值放入数组中 - 即使之前没有使用过该索引:

    var a = [];
    a[2] = 'foo';
    console.log(a.length); // => 3
    

    您还可以通过使用方括号中的字段名称直接分配给对象字段来将值放入对象字段:

    var a = {};
    a['foo'] = 'bar';
    

    如您所见,语法是相同的。此外 - 你必须记住,在 Javascript 中 - 一切都是对象,包括数组。通过理解名称为数字的字段会影响数组长度和迭代内容,您可以说数组是专门化的对象。

    因此,您的第一个示例实际上并未将 fileData 作为数组处理 - 它将其视为巧合初始化为空数组的对象。在您设置了所有附加的非数字字段后,数组仍然是空的。 (这是假设 uniquePropertyName 字段包含文本而不是数字 - 如果它有时包含数字,那么这将解释为什么“有时它有效”)。

    【讨论】:

    • BTW,除了push()之外,向数组的和添加元素的常用方法是为比最后一个索引大一的索引分配一个值:a[a.length] = "value"
    猜你喜欢
    • 2015-01-19
    • 1970-01-01
    • 2015-01-11
    • 2021-10-06
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    • 2021-09-06
    • 1970-01-01
    相关资源
    最近更新 更多