JavaScript基础—— 数组

简介: JavaScript基础—— 数组

1. 数组的创建方式

  // 1. 字面量创建(推荐)
  var names = ["zgc", "wf ", "wlc", "cx"];
  var products = [
    { name: "鼠标", price: 98 },
    { name: "键盘", price: 198 },
    { name: "显示器", price: 1988 },
  ];
  console.log(names[1], names["1"]); // wf wf
  // 2. 构造函数创建
  var arr1 = new Array();
  console.log(arr1); // []
  var arr2 = new Array("abc", "cba", "cab");
  console.log(arr2); // ['abc', 'cba', 'cab']
  // 传入一个数字, 他会默认当成我们要创建一个对应长度的数组, 数组中的每一项内容为undefined
  var arr3 = new Array(5);
  console.log(arr3, arr3[0]); // [empty × 5] undefined

2. 数组的增删改查

  // 1. 访问数组的元素
  var names = ["zgc", "wf ", "wlc", "cx"];
  console.log(names[2], names["2"]); // wlc wlc
  // arr.at(i): i > 0时,. 则与arr[i]完全相同, i < 0 时, 则从数组的尾部向前数
  console.log(names.at(0)); // zgc
  console.log(names.at(-1)); // cx
  // 2. 修改数组的元素
  names[0] = "zqy";
  console.log(names); // ['zqy', 'wf ', 'wlc', 'cx']
  // 3. 新增数组的元素
  // push(): push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度
  let a1 = [1, 2, 3];
  let item1 = a1.push("末尾1", "末尾2"); // 5
  console.log(a1); // [1,2,3,末尾1",'末尾2']
  // unshift(): unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度
  let a2 = [1, 2, 3];
  let item2 = a2.unshift("开头"); // 4
  console.log(a2); // ['开头',1,2,3]
  // 4. 删除数组的元素
  // shift(): shift()方法删除数组的第一个元素,并返回这个元素
  let a3 = [1, 2, 3];
  let item3 = a3.shift(); // 1
  console.log(a3); // [2,3]
  // pop(): pop() 方法删除一个数组中的最后的一个元素,并且返回这个元素
  let a4 = [1, 2, 3];
  let item4 = a4.pop(); // 3
  console.log(a4); // [1,2]
  // 5. splice(): 添加/删除/替换数组元素, 原数组会被改变
  // array.splice(index, howmany, item1,.....,itemX )
  // index:必需, 整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置
  // howmany:可选, 要删除的项目数量。如果设置为 0,则不会删除项目
  // item1, ..., itemX: 可选。向数组添加的新项目。
  // 如果有元素被删除,返回包含被删除项目的新数组
  var list = [1, 2, 3, 4, 5, 6, 7];
  var newList = list.splice(0, 2);
  console.log(newList, list); //  [1, 2]  [3, 4, 5, 6, 7]
  var list = [1, 2, 3, 4, 5, 6, 7];
  var newList = list.splice(2, 1);
  console.log(newList, list); //  [3]  [1, 2, 4, 5, 6, 7]
  var list = [1, 2, 3, 4, 5, 6, 7];
  var newList = list.splice(2, 1, "zgc", "wf");
  console.log(newList, list); //  [3]  [1, 2, 'zgc', 'wf', 4, 5, 6, 7]
  // 添加是在开始的元素前面添加的
  // [] 没有删除元素,返回空数组
  var list = [1, 2, 3, 4, 5, 6, 7];
  var newList = list.splice(2, 0, "zgc", "wf");
  console.log(newList, list); //  []  [1, 2, 'zgc', 'wf', 3, 4, 5, 6, 7]
  // 数组如果元素不够,会删除到最后一个元素为止
  var list = [1, 2, 3, 4, 5, 6, 7];
  var newList = list.splice(-1, 5);
  console.log(newList, list); //  [7]  [1, 2, 3, 4, 5, 6]


3.数组的长度与遍历

  var names = ["zgc", "wf", "wlc", "cx"];
  // 1. 查看数组长度
  console.log(names.length); // 4
  // 2. 数组的长度是可写的, 即可以给数组手动扩容
  names.length = 8;
  console.log(names); // ['zgc', 'wf', 'wlc', 'cx', 空属性 × 4]
  // 3. 如果设置的长度小于数组的原长度, 那么数组会发生截取
  // 所以如果想要清空数组, 可以设置 arr.length = 0
  names.length = 2;
  console.log(names); // ['zgc', 'wf']
  // 4. 数组的遍历
  var arr = ["zgc", "wf", "wlc", "cx"];
  // 4.1 for循环
  for (var i = 0; i < arr.length; i++) {
    console.log(arr[i]); // "zgc" "wf" "wlc" "cx"
  }
  // 4.2 for...in
  for (var index in arr) {
    console.log(index); // 0 1 2 3
  }
  // 4.3 for...of
  for (var item of arr) {
    console.log(item); // // "zgc" "wf" "wlc" "cx"
  }

4.slice & concat & join

  // 1. array.slice(begin, end); 截取数组的元素, 取值范围: [begin, end)
  // begin(可选): 索引数值, 接受负值,从该索引处开始提取原数组中的元素
  // end(可选):索引数值(不包括), 接受负值,在该索引处前结束提取原数组元素
  var names = ["zgc", "wf", "wlc", "cx"];
  // 不改变原数组, 返回一个新的数组
  console.log(names.slice(2, 3), names); // ['wlc']  ['zgc', 'wf', 'wlc', 'cx']
  // 可以用来浅拷贝数组
  console.log(names.slice(), names); // ['zgc', 'wf', 'wlc', 'cx'] (4) ['zgc', 'wf', 'wlc', 'cx']
  /*
  tips:
     新数组是浅拷贝的,且元素是简单数据类型,改变之后新旧数组不会互相干扰
     如果数组元素是复杂数据类型(对象,数组)的话,改变其中一个的值,另外一个也会改变
  */
  let test = [{ name: "OBKoro1" }];
  let clone = test.slice();
  console.log(test, clone); // [{"name":"OBKoro1"}]  [{"name":"OBKoro1"}]
  test[0].name='改变原数组';
  console.log(test, clone); // [{"name":"改变原数组"}] [{"name":"改变原数组"}]
  clone[0].name='改变拷贝数组',clone[0].koro='改变拷贝数组';
  console.log(test, clone); 
  //  [{"name":"改变拷贝数组","koro":"改变拷贝数组"}] [{"name":"改变拷贝数组","koro":"改变拷贝数组"}]
  // 2. concat方法用于合并两个或多个数组,不改变原数组, 返回一个新数组
  let a = [1, 2, 3];
  let b = [4, 5, 6];
  //连接两个数组
  let newVal = a.concat(b); // [1,2,3,4,5,6]
  // 连接三个数组
  let c = [7, 8, 9];
  let newVal2 = a.concat(b, c); // [1,2,3,4,5,6,7,8,9]
  // 添加元素
  let newVal3 = a.concat("添加元素", b, c, "再加一个");
  // [1,2,3,"添加元素",4,5,6,7,8,9,"再加一个"]
  // 合并嵌套数组  会浅拷贝嵌套数组
  let d = [1, 2];
  let f = [3, [4]];
  let newVal4 = d.concat(f); // [1,2,3,[4]]
  // 3. join方法用于把数组中的所有元素通过指定的分隔符进行分隔放入一个字符串,返回生成的字符串(不改变原数组)
  let list = ["hello", "world"];
  let str1 = list.join(); // 'hello,world'
  let str2 = list.join(" "); // 'hello world'
  let str3 = list.join("+"); // 'hello+world'
  console.log(str1, str2, str3);

5. 查找数组中的元素(find & findIndex & indexOf)

  // 1. 数组中存放的是原始类型
  var names = ["zgc", "wf", "wlc", "cx"];
  // indexOf(): 查找数组是否存在某个元素,返回在数组中可以找到给定元素的第一个索引,如果不存在,则返回-1
  // 数组的indexOf搜索跟字符串的indexOf不一样,数组的indexOf使用严格相等===搜索元素,即数组元素要完全匹配才能搜索成功。
  // indexOf()不能识别NaN
  console.log(names.indexOf("wf")); // 1
  // 2. 数组中存放的是复杂类型
  var products = [
    { name: "鼠标", price: 98 },
    { name: "键盘", price: 198 },
    { name: "显示器", price: 1988 },
  ];
  // 2.1 for
  var pro1 = null;
  for (var i = 0; i < products.length; i++) {
    if (products[i].name === "键盘") {
      pro1 = products[i];
      break;
    }
  }
  console.log("pro1", pro1); // {name: '键盘', price: 198}
  // 2.2 find: 高阶函数
  // 用于找出第一个符合条件的数组成员,并返回该成员,如果没有符合条件的成员,则返回undefined。
  var pro2 = products.find((item, index, arr) => {
    // console.log(item, index, arr); // 数组当前元素的值, 当前元素的索引值, 数组对象本身
    // if(item.name === "键盘") return true
    return item.name === "键盘";
  });
  console.log("pro2", pro2);
  // 2.3 findIndex: 高阶函数
  // 返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。
  var pro3 = products.findIndex((item, index, arr) => item.name === "显示器");
  console.log("pro3", pro3); // 2

6. forEach的使用&手写forEach

  // 1. forEach: 遍历数组, 按升序为数组中含有效值的每一项执行一次回调函数
  // arr.forEach(function (currentValue, currentIndex, arr) {}, thisArg);
  //currentValue  必需。当前元素
  //currentIndex  可选。当前元素的索引
  //arr           可选。当前元素所属的数组对象。
  //thisArg       可选参数。当执行回调函数时,用作 this 的值。
  // 2. forEach注意事项:
  let a = [1, 2, , 3]; // 最后下标第二个元素是空的,不会遍历(undefined、null会遍历)
  let obj = { name: "OBKoro1" };
  let result = a.forEach(function (value, index, array) {
    a[3] = "改变元素";
    a.push("添加到尾端,不会被遍历");
    // console.log(value, "forEach传递的第一个参数", index, array, array.length);
    console.log(this.name); // 默认this是window,这里this绑定在obj对象上,所以OBKoro1 打印三次
    // break; // break会报错
    return value; // return只能结束本次回调 会执行下次回调
    console.log("不会执行, 因为return 会执行下一次循环回调");
  }, obj);
  console.log("result", result); // 即使return了一个值,也还是返回undefined
  //  1 'forEach传递的第一个参数' 0  [1, 2, 空白, '改变元素', '添加到尾端,不会被遍历'] 5
  // OBKoro1
  // 2 'forEach传递的第一个参数' 1  [1, 2, 空白, '改变元素', '添加到尾端,不会被遍历', '添加到尾端,不会被遍历'] 6
  // OBKoro1
  // 改变元素 forEach传递的第一个参数 3 (7) [1, 2, 空白, '改变元素', '添加到尾端,不会被遍历', '添加到尾端,不会被遍历', '添加到尾端,不会被遍历'] 7
  // OBKoro1
  // result undefined
  /*
   1. 无法中途退出循环,只能用return退出本次回调,进行下一次回调。
   2. 它总是返回 undefined值,即使你return了一个值。
   3. 对于已在迭代过程中删除的元素,或者空元素会跳过回调函数
   4. 遍历次数再第一次循环前就会确定,再添加到数组中的元素不会被遍历
   5. 如果已经存在的值被改变,则传递给 callback 的值是遍历到他们那一刻的值
  */
  // 2. 手写forEach
  var products = [
    { name: "鼠标", price: 98 },
    { name: "键盘", price: 198 },
    { name: "显示器", price: 1988 },
  ];
  var test = {
    name: "zgc",
  };
  Array.prototype._forEach = function (fn, ins) {
    if (typeof fn !== "function") throw Error("回调函数不是一个函数~");
    for (let i = 0; i < this.length; i++) {
      fn.call(ins, this[i], i, this);
    }
  };
  products._forEach(function (item, index, arr) {
    console.log(item, index, arr, this);
  }, test);  // 当指定this值时, 不要使用箭头函数的书写方式

7. 手写find&findIndex方法

  // array.find(function(item, index, arr), ins)
  // 回符合测试条件的第一个数组元素值,如果没有符合条件的则返回 undefined
  // array.findIndex(function(item, index, arr), ins)
  // 返回符合测试条件的第一个数组元素索引,如果没有符合条件的则返回 -1
  // 参数1:回调函数(必需)
  // 参数2:传递给回调函数的this指针(可选), 如果这个参数为空,this指针为window
  // 注:当回调函数是箭头函数时,参数2无效,始终指向全局window变量
  var products = [
    { name: "鼠标", price: 98 },
    { name: "键盘", price: 198 },
    { name: "显示器", price: 1988 },
  ];
  var test = {
    name: "zgc",
  };
  Array.prototype._find = function (fn, ins) {
    let res;
    for (let i = 0; i < this.length; i++) {
      if (fn.call(ins, this[i], i, this)) {
        res = this[i];
        break;
      }
    }
    return res;
  };
  Array.prototype._findIndex = function (fn, ins) {
    let res = -1;
    for (let i = 0; i < this.length; i++) {
      if (fn.call(ins, this[i], i, this)) {
        res = i;
        break;
      }
    }
    return res;
  };
  var pro1 = products._find(function (item, index, arr) {
    // console.log(item, index, arr, this);
    return item.name === "键盘";
  }, test);
  console.log(pro1); // {name: '键盘', price: 198}
  var pro2 = products._findIndex(function (item, index, arr) {
    // console.log(item, index, arr, this);
    return item.name === "键盘";
  }, test);
  console.log(pro2); // 1
相关文章
|
1月前
|
自然语言处理 前端开发 JavaScript
🛠️ JavaScript数组操作指南:20个精通必备技巧🚀
本文详细介绍了 JavaScript 中的 20 个高效数组操作技巧,涵盖了从基本的添加、移除元素,到数组转换和去重等高级操作。强调了不可变性的重要性,提供了清晰的代码示例,帮助开发者编写更整洁和高效的代码。无论是新手还是经验丰富的开发者,这些技巧都将显著提升您的编码能力,使您在项目中更具竞争力。
23 2
|
1月前
|
JavaScript 前端开发 测试技术
JS都有哪些操作数组的方法
JS都有哪些操作数组的方法
20 3
|
1月前
|
JavaScript
js删除数组中已知下标的元素
js删除数组中已知下标的元素
35 4
|
1月前
|
缓存 JavaScript 前端开发
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
31 1
|
1月前
|
JavaScript 前端开发 Java
【javaScript数组,函数】的基础知识点
【javaScript数组,函数】的基础知识点
23 5
|
1月前
|
JavaScript 前端开发 索引
探索JavaScript数组:基础
探索JavaScript数组:基础
17 3
|
1月前
|
JavaScript 前端开发 索引
JS 删除数组元素( 5种方法 )
JS 删除数组元素( 5种方法 )
37 1
|
1月前
|
JavaScript 前端开发
如何在JS中声明一个数组
如何在JS中声明一个数组
18 0
|
1月前
|
存储 JavaScript 前端开发
JavaScript Array(数组) 对象
JavaScript Array(数组) 对象
27 3
|
1月前
|
JavaScript 前端开发 API
JS中数组的方法flat()怎么用
JS中数组的方法flat()怎么用
13 0