首页 技术 正文
技术 2022年11月23日
0 收藏 388 点赞 2,941 浏览 9894 个字

目录

1. 数组

1.1 创建数组

  • 创建数组有两种基本方式:使用Array构造函数、使用数组字面量[]
// 通过构造函数
const subjects = new Array("Chinese", "Math", "English");
// 通过字面量
const fruits = ["apple", "banana", "pear"];
  • JS的数组是对象
const subjects = new Array("Chinese", "Math", "English");const fruits = ["apple", "banana", "pear"];console.log(typeof subjects);
// object
console.log(typeof fruits);
// object// 对访问不存在的数组索引,会返回undefined
console.log(fruits[4]);
// undefined// 可以写入超出数组索引的数据项
fruits[4] = "orange";
// 但中间项会自动填充为undefined
console.log(fruits[3]);
// undefined// length属性返回数组的大小
console.log(subjects.length);
// 3
// 可以手动修改length的值
subjects.length = 4;
// 将length改为比原有值大的数,数组会被扩展,新扩展的元素均为undefined
console.log(subjects);
// ["Chinese", "Math", "English", empty]
// 将length改为比原有值小的数,数组会被裁剪,多余数据项将被抛弃
subjects.length = 2;
console.log(subjects);
// ["Chinese", "Math"]

使用数组字面量创建数组优于数组构造函数(字面量只需要2个字符)

1.2 在数组两端添加删除元素

方法 作用 返回值
push 末尾添加元素 添加元素后数组的长度
pop 末尾删除元素 被删除(弹出)的元素本身
unshift 开头添加元素 添加元素后数组的长度
shift 开头删除元素 被删除(弹出)的元素本身
const fruits = ["apple", "banana", "pear"];let len = fruits.push("orange");
console.log(len);
// 4
console.log(fruits);
// ["apple", "banana", "pear", "orange"]let lastFruit = fruits.pop();
console.log(lastFruit);
// orange
console.log(fruits);
// ["apple", "banana", "pear"]len = fruits.unshift("orange");
console.log(len);
// 4
console.log(fruits);
// ["orange", "apple", "banana", "pear"]let firstFruit = fruits.shift();
console.log(lastFruit);
// orange
console.log(fruits);
// ["apple", "banana", "pear"]

性能考虑:pop和push只影响数组最后一个元素,unshift和shift增减第一个元素,之后的每个元素的索引都需要调整。因此pop和push比unshift和shift快得多,非特殊情况下不建议使用unshift和shift。

1.3 在数组任意位置添加、删除元素

delete删除数组元素无效

const fruits = ["apple", "banana", "pear"];delete fruits[1];// 使用delete关键字并不能删除元素,只能删除对应索引的值,
console.log(fruits);
// ["apple", empty, "pear"]
// 被删除值的元素的值为undefined
console.log(fruits[1]);
// undefined

使用splice方法增、删、改元素

const fruits = ["apple", "banana", "pear"];// 删除元素
// 两个参数,表示从索引2开始(索引>= 2),删除1个元素
// 返回值为被删去的元素(以数组的格式)
let elems = fruits.splice(2, 1);
console.log(fruits);
// ["apple", "banana"]
console.log(elems);
// ["pear"]// 新增元素
// 三个以上参数,表示从索引1开始(索引>= 1),删除0个元素,新增后面的剩余参数
// 因为删除的元素个数为0,所以返回值是空数组
elems = fruits.splice(1, 0, "orange", "pear");
console.log(fruits);
// ["apple", "orange", "pear", "banana"]
console.log(elems);
// []// 两者同时使用
// 三个以上参数,表示表示从索引1开始(索引>= 1),先删除3个元素,新增后面的剩余参数
// 返回值为被删去的元素(以数组的格式)
elems = fruits.splice(1, 3, "peach", "watermelon");
console.log(fruits);
// ["apple", "peach", "watermelon"]
console.log(elems);
// ["orange", "pear", "banana"]

1.4 数组的常用操作

数组遍历(forEach)

const fruits = ["apple", "banana", "pear"];// for循环
for(let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}// forEach方法
fruits.forEach(fruit => {
console.log(fruit);
});

映射数组(map方法,对数组成员执行操作,并返回结果组成的新数组)

const students = [
{name: "Wango", age: 24},
{name: "Lily", age: 25},
{name: "Jack", age: 18},
];// 使用forEach提取
let names = [];
students.forEach(student => {
names.push(student.name);
});console.log(names);
// ["Wango", "Lily", "Jack"]// 使用map方法提取,自动将返回值装入数组并返回
let age = students.map(student => student.age);console.log(age);
// [24, 25, 18]

测试数组元素(every、some)

const students = [
{name: "Wango", age: 24},
{name: "Lily", age: 25},
{name: "Jack", age: 17},
];// 使用every验证数组内是否每个元素都满足条件
// 回调函数对每个参数执行操作,当所有元素的回调结果都为true,every方法返回true
// 只要有一个为false,则every方法不再执行并返回false
let allStudentsAreAdult = students.every(student => student.age >= 18);console.log(allStudentsAreAdult);
// fasle// 使用some验证数组内是否有部分元素都满足条件
// 回调函数对每个参数执行操作,当所有元素的回调结果都为false,some方法返回false
// 只要有一个为true,则some方法不再执行并返回true
let someStudentsAreAdult = students.some(student => student.age >= 18);console.log(someStudentsAreAdult);
// true

查找元素(find、filter、indexOf、lastIndexOf、findIndex)

const students = [
{name: "Wango", age: 24},
{name: "Lily", age: 25},
{name: "Jack", age: 17},
];// 使用find查找单一元素,返回满足条件的第一个元素
// 没找到就返回undefined
let seventeen = students.find(student => student.age === 17);
console.log(seventeen.name);
// Jack// 使用filter查找(过滤其他)元素,返回满足条件的所有元素(数组形式)
// 没找到就返回空数组
let adults = students.filter(student => student.age >= 18);
console.log(adults.map(adult => adult.name));
// ["Wango", "Lily"] const apple = ["a", "p", "p", "l", "e"]// indexOf接收一个元素值,返回顺序查找的特定元素的索引
// 没找到返回-1
let firstIndex = apple.indexOf("p");
console.log(firstIndex);
// 1// lastIndexOf接收一个元素值,返回逆序查找的特定元素的索引
// 没找到返回-1
let lastIndex = apple.lastIndexOf("p");
console.log(lastIndex);
// 2// 返回顺序查找的特定元素的索
// 接收回调函数作为参数,所以可以查找对象数组的索引
// 没找到返回-1
let idx = apple.findIndex(a => a === "l");
console.log(idx);
// 3

数组排序(sort)

// 如果回调函数的返回值小于0,第一个元素应该出现在第二个元素之前
// 如果回调函数返回0,两个元素的先后顺序保持不变
// 如果回调函数的返回值大于0,第一个元素应该出现在第二个元素之后// 如果是纯数字数组,像下面这样写就行了
const nums = [5, 6, 7, 8, 1, 3, 5, 9, 6, 2,];
nums.sort((a, b) => a - b);
console.log(nums);
// [1, 2, 3, 5, 5, 6, 6, 7, 8, 9]// 字符串没办法加减,只能比较大小,用if判断或者三元操作符判断一下然后返回
let chars = ["f", "a", "c", "u", "p"];
chars.sort((a, b) => {
return a > b ? 1 : a < b ? -1 : 0;
});
console.log(chars);
// ["a", "c", "f", "p", "u"]// 如果需要从大到小排序就换一下返回值

合计数组元素(reduce)

const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9];// reduce方法接收一个回调函数
// 回调函数有两个必需参数, 第一个为累加器,用于存储计算结果,
// 第二个为当前正在处理的元素
let sum = nums.reduce((acc, cur) => acc + cur);
console.log(sum);
// 45

1.5 复用内置的数组函数(复用已经编写的代码)

<input type="text" id="first">
<input type="button" id="second"><script>
// 创建一个可以复用数组方法的对象
const elems = {
length: 0, // 模拟数组长度
add: function(elem) {
// 复用数组代码
// 注意:原代码有返回值的,本代码也要有返回值
// 避免造成混乱
return Array.prototype.push.call(this, elem);
},
gather: function(id) {
return this.add(document.getElementById(id));
},
find: function(callback) {
return Array.prototype.find.call(this, callback);
}
}
elems.gather("first");
elems.gather("second");
// 数组代码会对length属性进行操作,
// 所以不需要再对length进行手动操作
console.log(elems.length);
// 2 const first = elems.find(elem => elem.id === "first");
console.log(first.type);
// text
</script>

2. Map

2.1 对象不是Map

访问对象未显式定义的属性,返回非预期

// 从字面看,对象符合字典的要求:键值对
// 但作为对象,其具有很多隐式属性
const student = {
wango: { id: 578, age: 24 },
lily: { id: 629, age: 25 },
jack: { id: 634, age: 22 }
}// 对于未定义的属性,期望返回undefined,但
console.log(student.constructor);
// Object() { [native code] }

将对象的key映射为HTML节点造成key重复

const elems = {};const first = document.getElementById("first");
const second = document.getElementById("second");// HTML元素对象作为key,加入对象
elems[first] = "First Element";
elems[second] = "Second Element";// 对象的key必须是字符串,非字符串类型会在后台静默调用toString方法
// 而相同类型元素的toString方法返回值相同,导致key重复
console.log(first.toString() === second.toString());
// true// 前一个数据被后者替换
console.log(elems[first]);
// Second Element
console.log(elems[second]);
// Second Element

对象的原型有额外的继承属性、key仅支持字符串,所以通常不能使用对象作为map

2.2 创建map

<input type="text" id="first">
<input type="text" id="second">
<input type="text" id="third"><script>
// 使用Map构造函数创建空map
const elemsMap = new Map(); const first = document.getElementById("first");
const second = document.getElementById("second");
const third = document.getElementById("third"); // 使用set方法创建映射,参数分别是:key, value
elemsMap.set(first, "First Element");
elemsMap.set(second, "Second Element"); // size属性为映射数量
console.log(elemsMap.size);
// 2 // get方法通过key获取value
console.log(elemsMap.get(first));
// First Element
console.log(elemsMap.get(second));
// Second Element // has方法判断指定key是否存在
console.log(elemsMap.has(third));
// false elemsMap.set(third, "Third Element"); // delete方法通过key删除映射
// 有这个key并删除成功返回true,没有这个key返回false
let a = elemsMap.delete(first);
console.log(a);
// true console.log(elemsMap.size);
// 2 // clear方法清空map
elemsMap.clear(); console.log(elemsMap.size);
// 0
</script>

JS中两个对象的内容相同,但两个对象仍然不相等,所以可以作为map的key

const map = new Map();let currentLocation = location.href;// 创建两个相同内容的对象
const firstURL = new URL(currentLocation);
const secondURL = new URL(currentLocation);map.set(firstURL, { "description": "First" });
map.set(secondURL, { "description": "Second" });// 两个相同内容的对象都可以称为map的key
console.log(map.get(firstURL).description);
// First
console.log(map.get(secondURL).description);
// Second

2.3 遍历map(for-of)

const students = new Map();students.set("Wango", 578);
students.set("Lily", 649);
students.set("Jack", 312);// 遍历所有的students,没有元素有两个值:key和value
for(let student of students) {
console.log(student[0] + ": " + student[1]);
}
// Wango: 578
// Lily: 649
// Jack: 312// 遍历所有的key
for(let name of students.keys()) {
console.log(name);
}
// Wango
// Lily
// Jack// 遍历所有的value
for(let id of students.values()) {
console.log(id);
}
// 578
// 649
// 312

3. Set

3.1 使用对象模拟集合

// 用对象模拟集合
// 同样的问题,对象的key只能是字符串,这大大限制了模拟集合的能力// 可以提供参数预填充集合
function Set(arr) {
this.data = {};
this.size = 0;
if (Array.isArray(arr)) {
// 数组去重
for (var i = 0; i < arr.length; i++) {
if (!this.has([arr[i]])) {
this.data[arr[i]] = arr[i];
this.size++;
}
}
}
}Set.prototype.has = function (item) {
return typeof this.data[item] !== "undefined";
}Set.prototype.add = function (item) {
if (!this.has(item)) {
this.data[item] = item;
this.size++;
}
return this.values();
}Set.prototype.delete = function (item) {
if (this.has(item)) {
delete this.data[item];
this.size--;
return true;
}
return false;
}Set.prototype.clear = function() {
var keys = this.keys();
this.size = 0;
for(var i = 0; i < keys.length; i++) {
delete this.data[keys[i]];
}
}Set.prototype.keys = Set.prototype.values = function() {
return Object.getOwnPropertyNames(this.data);
}Set.prototype.forEach = function(callback) {
var props = this.values();
for(var i = 0; i < props.length; i++) {
callback(props[i], props[i]);
}
}

3.2 创建Set

const students = new Set(["Wango", "Lily", "Jack"]);console.log(students.has("Wango"));
// true
console.log(students.add("Jack"));
// Set(3) {"Wango", "Lily", "Jack"}
console.log(students.add("Tom"));
// Set(4) {"Wango", "Lily", "Jack", "Tom"}
console.log(students.delete("Wango"));
// true
console.log(students);
// Set(3) {"Lily", "Jack", "Tom"}// 为了与map API保持一致,每个key和value的值相同
students.forEach((key, val) => {
console.log(key + ": " + val);
});
// Lily: Lily
// Jack: Jack
// Tom: Tomfor(let student of students) {
console.log(student);
}
// Lily
// Jack
// Tom// 清空集合
students.clear();

3.2 并集、交集、差集

const firstGroup = new Set(["Wango", "Lily", "Tom"]);
const secondGroup = new Set(["Wango", "Lily", "Jack", "Mike"]);// 并集,使用延展运算符打散两个集合,再合并成一个新的数组作为参数
// Set构造函数自动去重
const allStudents = new Set([...firstGroup, ...secondGroup]);console.log(allStudents);
// {"Wango", "Lily", "Tom", "Jack", "Mike"}// 交集,打散成数组后使用filter方法过滤掉secondGroup没有的元素
const sameStudents = new Set([...firstGroup].filter(stu => secondGroup.has(stu)));console.log(sameStudents);
// {"Wango", "Lily"}// 差集,只包含于集合A,不包含于集合B的元素,从A中过滤掉B中有的元素
const onlyInFirstGroup = new Set([...firstGroup].filter(stu => !secondGroup.has(stu)));console.log(onlyInFirstGroup);
// {"Tom"}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,903
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,429
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,245
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,057
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,689
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,726