JavaScript05-数组和常用工具类
1.数组
- 数组的常用操作。
// 1 数组的定义。
// 1) 数组也是一个对象。
// 2) 数组用来存储一组有序的数据。
// 3) 数组中存储的数据称为 元素(element)
// 2 数组的创建
let arr = new Array();
console.log(arr); // []
// 3 向数组中添加元素
arr[0] = 10;
console.log(arr); // [10]
// 4 获取数组中的元素
console.log(arr[0]); // 10
// 5 获取数组中没有的元素
console.log(arr[1]); // undefined
// 6 数组的类型
console.log(typeof arr); // object
// 7 获取数组的长度
console.log(arr.length); // 1
// 8 非连续数组,数组中间的值为空,但是长度依然为10,不建议使用非连续数组。
arr[10] = 20;
console.log(arr.length); // 11
console.log(arr); // (11) [10, empty × 9, 20]
- 向数组中添加元素。
// 1 向数组中添加元素
let b = new Array();
b[b.length] = 0;
b[b.length] = 1;
console.log(b); // (2) [0, 1]
// 2 数组长度的修改
// 数组长度改大,多余的元素为空。
b.length = 10;
console.log(b); // (10) [0, 1, empty × 8]
// 2 数组长度改小,则后边的元素被删除。
b.length = 1;
console.log(b); // [0]
- 数组的字面量。
// 创建空数组
let c = [];
console.log(c); // []
// 创建一个数组,数组中含有数字10
let d = [10];
console.log(d); // [10]
// 创建一个长度为10的数组,数组的元素为空。
let e = new Array(10);
console.log(e); // (10) [empty × 10]
// 创建可以存储任意类型数据的数组,但是建议数组中存储的元素保持一致。
let f = ['tom', 10, true, null, {name: 'tom'}, function () {
return 'f';
}];
console.log(f); // (6) ['tom', 10, true, null, {…}, ƒ]
console.log(f[5]()); // f,调用数组中的函数
- 二维数组。
let g = [[1, 2, 3], [4, 5, 6]];
console.log(g); // (2) [Array(3), Array(3)]
console.log(g[0]); // (3) [1, 2, 3]
2.数组的遍历
let h = ['a', 'b', 'c', 'd'];
for (let i = 0;i < h.length;i++) {
console.log(h[i]);
}
for (let i = h.length - 1;i >= 0;i--) {
console.log(h[i]);
}
// for...in 获取索引
for (let index in h) {
console.log(h[index]);
}
// for...of 获取值。
for (let value of h) {
console.log(value);
}
3.数组的方法
- 数组中常用的四个方法。
// push() 想数组的尾部添加一个或者多个元素,并返回添加元素后数组的长度。
let l = ['a', 'b'];
let r1 = l.push('c', 'd');
console.log(l); // (3) ['a', 'b', 'c', 'd']
console.log(r1); // 4
// pop() 删除数组中最后一个元素,返回返回删除的元素
let r2 = l.pop();
console.log(l); // (3) ['a', 'b', 'c']
console.log(r2); // d
// unshift() 向数组头部添加元素,并返回添加元素后数组的长度
let r3 = l.unshift('1', '2');
console.log(l); // (5) ['1', '2', 'a', 'b', 'c']
console.log(r3); // 5
// shift() 删除数组头部的元素,并返回删除的元素。
let r4 = l.shift();
console.log(l); // (4) ['2', 'a', 'b', 'c']
console.log(r4); // 1
- 数组方法-slice()。
let m = ['a', 'b', 'c', 'd', 'e', 'f'];
// slice()数组截取,不会改变原有的数据。
// slice() 第一个参数是要截取数组的开始索引。
// slice() 第二个参数是要截取数据的结束索引(结束索引不包含自己);如果没有第二个元素,则截取到数组尾部;
// 如果第二个元素是负数,如-1,则截取到倒数第一个元素,不包含倒数第一个元素。
let m1 = m.slice(1, 2);
console.log(m); // ['a', 'b', 'c', 'd', 'e', 'f']
console.log(m1); // ['b']
// 传递一个参数,会截取到最后一个元素。
console.log(m.slice(1)); // ['b', 'c', 'd', 'e', 'f']
console.log(m.slice(10)); // []
// 如果第二个参数是负数,如-1,则表示截取到倒数第一个元素。
console.log(m.slice(1, -1)); // ['b', 'c', 'd', 'e']
// -2,则截取到倒数第二个元素。
console.log(m.slice(1, -2)); // ['b', 'c', 'd']
- 数组方法-splice()。
// splice(),可以从数组中删除、添加和替换数组中的元素。
let n = ['a', 'b', 'c', 'd'];
// 将原属于0和1索引处的元素删除,并返回删除的元素。
// splice() 第一个参数是要删除元素的开始索引。
// splice() 第二个参数是要删除元素的个数。
let n1 = n.splice(0, 2);
console.log(n); // ['c', 'd']
console.log(n1); // ['a', 'b']
// splice() 替换元素
n = ['a', 'b', 'c', 'd'];
// 将索引0出的一个元素替换为两个元素,'hh' 'tt'
n.splice(0, 1, 'hh', 'tt');
console.log(n); // ['hh', 'tt', 'b', 'c', 'd']
// splice() 插入元素。
n = ['a', 'b', 'c', 'd'];
// 0表示不会删除元素,所以会在索引1处插入两个元素,'hh' 'tt'
n.splice(1, 0, 'hh', 'tt');
console.log(n); // ['a', 'hh', 'tt', 'c', 'd']
- 判断是否是一个数组。
let n = ['a', 'b', 'c', 'd'];
// 判断是否是一个数组
console.log(Array.isArray(n)); // true
4.数组foreach遍历
// foreach() 专门用来对数组进行遍历。
// foreach需要一个参数,这个参数是一个回调函数,
// 然后由浏览器调用,数组有几个元素就调用几次。
// 回调函数可以定义三个参数,浏览器在调用回调函数时会传入这三个参数。
// 第一个是数组中的元素;第二个参数是元素在数组中的索引;第三个参数是原数组。
let a = ['a', 'b', 'c', 'd'];
a.forEach(function (element, index, array) {
console.log(element, index, array);
});
5.数组的其他方法
- concat(),连接数组。
// concat() 连接两个或者多个数组。
// concat() 不会影响原数组,会将连接之后的数字返回。
let a01 = ['a', 'b', 'c', 'd'];
let a02 = ['1', '2'];
let a03 = a01.concat(a02);
console.log(a03); // 6) ['a', 'b', 'c', 'd', '1', '2']
- indexOf()和lastIndexOf(),数组中元素查找。
let a04 = ['a', 'b', 'c', 'd', 'a'];
// 判断a是否在数组a04中,但是不会返回元素在数组中的索引。
console.log('a' in a04); // true
console.log(a04.indexOf('a')); // 0
// 数组中没有则返回-1
console.log(a04.indexOf('z')); // -1
// indexOf()第二个参数表示开始查找的索引。
console.log(a04.indexOf('a', 1)); // 4
// lastIndexOf(),从最后开始查找元素,返回元素的索引。
console.log(a04.lastIndexOf('a')); // 4
console.log(a04.lastIndexOf('a', 1)); // 0
- join(),数组转换为特定格式的字符串。
let a05 = ['a', 'b', 'c', 'd', 'a'];
console.log(a05.join()); // a,b,c,d,a
console.log(a05.join('-')); // a-b-c-d-a
- reverse(),翻转数组。
let a06 = [1, 2, 3, 4];
// reverse() 翻转数组,会改变原有的数据。
a06.reverse();
console.log(a06); // (4) [4, 3, 2, 1]
- sort(),数组排序。
// sort() 数组排序,会改变原有的数组。
let a07 = [2, 1, 10, 6];
a07.sort();
console.log(a07); // (4) [1, 10, 2, 6]
// 定义排序的规则
// 升序排列。
let a08 = [2, 1, 10, 6];
a08.sort(function (a, b) {
return a - b;
});
console.log(a08); // [1, 2, 6, 10]
6.函数的参数arguments
// 函数除了this外,还有一个额外的参数arguments。
// arguments 是一个类数组对象,类数组和数组的操作方式一样,只是不能使用数组的方法。
// 在函数执行时,所有的实参都会存储在arguments中。
function sum() {
console.log(Array.isArray(arguments)); // false
let sum = 0;
for (let i = 0;i < arguments.length;i++) {
sum += arguments[i];
}
return sum;
}
console.log(sum(1, 2)); // 3
7.函数的调用call和apply
- 函数中的this。
function f1() {
console.log(this);
}
// 调用函数的方式不同,this的值也不同。
// 1) 以函数的形式调用this就是window
f1(); // Window {window: Window, self: Window, document: document, name: '', location: Location, …}
let o1 = {fn: f1};
// 2) 以对象的形式调用,this就是调用的对象。
o1.fn(); // {fn: ƒ}
// 3) 以构造函数的形式调用,this就是新创建的对象。
new f1(); // f1 {}
// 4) 使用call()和apply()函数调用,this就是传递的第一个参数,如果没有传递参数this就是window。
f1.call(); // Window {window: Window, self: Window, document: document, name: '', location: Location, …}
f1.apply(); // Window {window: Window, self: Window, document: document, name: '', location: Location, …}
f1.call('hello'); // String {'hello'}
f1.apply('hello'); // String {'hello'}
- call和apply的区别。
// 1) call和apply都是函数对象的方法。
// 2) 当我们调用call和apply时,实际上和直接调用函数的作用类似,
// 只不过call和apply可以指定this,this为call和apply传递的第一个参数。
function f2(name, age) {
console.log(name, age);
}
// call 传递参数时,从第二个参数开始依次传递匹配。
f2.call('hello', 'tom', 10); // tom 10
// f2.apply('hello', 'alice', 20); // 报错 Uncaught TypeError: CreateListFromArrayLike called on non-object
// apply 传递的参数需要保存到类数组对象中统一传递,否则报错。
f2.apply('hello', ['alice', 20]); // alice 20
8.函数的参数-剩余参数
// ... 表示剩余参数,剩余参数和arguments功能类似。
// 剩余参数和arguments的区别。
// 1) 剩余参数是一个数组对象,可以使用数组的方法;
// 2) 剩余参数只会保存没有形参对象的参数。
// 3) 剩余参数只能写在函数参数列表的最后。
function f3(a, ...args) {
console.log(args);
console.log(Array.isArray(args));
}
// (4) [2, 3, 4, 5]
// true
f3(1, 2, 3, 4, 5);
9.函数的bind方法
// 1) 调用bind()会返回一个新的函数对象。
// 新函数对象和原来函数对象的功能是一样的,区别是新函数对象的this是bing()的第一个参数。
function f4() {
console.log(this);
}
let l = f4.bind('hello');
/*
ƒ f4() {
console.log(this);
}
*/
console.log(l);
// 调用bind()返回的函数对象,this是bind()的参数hello。
l(); // String {'hello'}
10.常用工具类-Math
// Math
// 1) Math不是一个构造函数,不能用来创建对象。
// 2) Math中包含了一些常用的数学计算的工具类。
// 1 属性,圆周率IP,Math.PI。
console.log(Math.PI); // 3.141592653589793
// 2 Math.abs() 计算一个数的绝对值。
console.log(Math.abs(-10)); // 10
// 3 Math.ceil() 向上取整
// Math.floor() 向下取整
// Math.round() 四舍五入
console.log(Math.ceil(3.4)); // 4
console.log(Math.floor(3.9)); // 3
console.log(Math.round(3.5)); // 4
// 4 Math.max() 计算最大值。
// Math.min() 计算最小值。
console.log(Math.max(1, 2)); // 2
console.log(Math.min(1, 2)); // 1
// 5 Math.pow(x, y),计算x的y次方
// Math.sqrt(),开方。
console.log(Math.pow(2, 4)); // 16
console.log(Math.sqrt(9)); // 3
// 6 生成一个0-1之间的随机数,不包含0和1。
console.log(Math.random()); // 0.8476161214768936
// 生成0-10之间的随机数
console.log(Math.round(Math.random() * 10)); // 0
// 生成3-10之间的随机数
// 生成x-y之间的随机数。Math.round(Math.random() * (y-x)) + x)
console.log(Math.round(Math.random() * 3) + 7); // 5
11.常用工具类-Date
// 1 JS中所有和日期相关的数据都是通过Date来表示。
// 直接创建Date对象,则表示当前时间
let d1 = new Date();
console.log(d1); // Sat Jul 09 2022 13:24:04 GMT+0800 (中国标准时间)
// 创建指定日期的时间对象。
// 时间的格式为 月/日/年 时:分:秒
let d2 = new Date('6/1/2020 10:11:12');
console.log(d2); // Mon Jun 01 2020 10:11:12 GMT+0800 (中国标准时间)
// Date常用的方法。
let d3 = new Date();
console.log(d3); // Sat Jul 09 2022 13:26:04 GMT+0800 (中国标准时间)
// getDay(),获取当前日期是周几。
// 返回0-6;0-周天;1-周一。
console.log(d3.getDay()); // 6
// getDate(),获取当前日期是这个月的几号
console.log(d3.getDate()); // 9
// getMonth(),获取当前对应的月份。
// 返回0-11,0-1月;1-2月...
console.log(d3.getMonth()); // 6
// getFullYear(),获取日期对应的年份
console.log(d3.getFullYear()); // 2022
// 获取日期的时间戳,即获取从1970年1月1月 0点0分0秒到当前时间的毫秒数。
console.log(d3.getTime()); // 1657344743238
// 直接获取当前的时间戳
console.log(Date.now()); // 1657344823110
12.常用工具类-包装类
// 包装类
// 1 JS中提供了三种包装类,String Number和Boolean。
// 2 通过包装类型我们可以创建String、Number和Boolean类型的对象。
// 3 包装类型并不是用来让开发中创建对象的,而是留给浏览器使用的。
// 这种创建基本类型数据的方式,建议不在开发中使用。
let a1 = new Number(10);
let a2 = new Number(10);
let a3 = new String('10');
let a4 = new Boolean();
// 使用包装类创建对象,在对象比较时,会比较对象的地址,会有问题。
console.log(a1 === a2); // false
// 当调用基本数据类型的属性和方法时,浏览器会通过包装类型临时将其转换为对象,然后调用包装类型的方法。
let a5 = 10;
// a5.name = 'tom';转换为临时的包装类型的对象,使用完成后临时就不存在了。
a5.name = 'tom';
// a5.name再次转换为临时的包装类型,而不是使用a5.name = 'tom';
// 转换为包装类型的是临时对象,所以undefined
console.log(a5.name); // undefined
let a6 = 10;
// a6临时转换为Number包装类型,然后调用Number的toString()。
console.log(a6.toString()); // 10
// null没有对应的包装类型,所以报错。
//console.log(null.toString()); // Uncaught TypeError: Cannot read properties of null (reading 'toString')
13.常用工具类-String
// 字符串,字符串本质是一个字符数组。
let a1 = 'a';
// 1 获取字符串的长度
console.log(a1.length); // 1
// 可以像使用数组一样使用字符串。
console.log(a1[0]); // a
// 2 concat() 连接一个或者多个字符串
let a2 = 'a';
let a3 = a2.concat('b');
console.log(a2); // a
console.log(a3); // ab
// 3 charAt() 获取指定索引处的字符
console.log('ab'.charAt(1)); // b
// 4 charCodeAt() 获取指定索引处的字符的编码
console.log('ab'.charCodeAt(1)); // 98
// 5 String.fromCharCode() 根据字符编码获取字符
console.log(String.fromCharCode(98)); // b
// 6 indexOf() 查找指定字符的索引
// lastIndexOf() 从后往前查找指定字符的索引
console.log('12'.indexOf('1')); // 0
// 7 splice() 字符串截取
let a4 = 'abcdef';
// 截取之后原字符不改变。
let a5 = a4.slice(1, 2);
console.log(a4); // abcdef
console.log(a5); // b
// 8 split() 将字符串拆分为数组
console.log('1,2,3,4'.split(',')); // (4) ['1', '2', '3', '4']
// 9 toLowerCase() 转小写
console.log('abcD'.toLowerCase()); // abcd
// 10 toUpperCase 转大写
console.log('abc'.toUpperCase()); // ABC
// 11 trim() 取掉前后的空格
console.log(' ab '.trim()); // ab
// trimEnd() 取掉后空格
console.log(' ab '.trimEnd()); // ab
// trimStart() 去掉前空格
console.log(' ab '.trimStart()); // ab
// 12 endsWith() 检查是否以指定字符结尾
// startsWith() 检查是否以指定字符开头
console.log('abc'.endsWith('c')); // true
console.log('abc'.startsWith('a')); // true
// 13 repeat() 将一个字符串重复指定次数。
console.log('ab'.repeat(2)); // abab
14.解构数组
// 1 解构数组,将数组中的第一个和第二个元素直接赋值给变量n1和n2
let a = [1, 2, 3];
let [n1, n2] = a;
console.log(n1, n2); // 1 2
let b= [1, 2, 3, 4, 5];
// ...m3 将剩余的元素赋值给m3,m3就会成为一个数组。
let [m1, m2, ...m3] = b;
console.log(m3); // (3) [3, 4, 5]
// 2 解构数组可以用来进行元素交换。
let c = 10, d = 5;
[c, d] = [d, c];
console.log(c, d); // 5 10
// 3 将数组解构后作为赋值给函数的参数
function f1(a, b, c) {
return a + b + c;
}
let e = [1, 2, 3];
console.log(f1(...e)); // 6
15.解构对象
let o = {
name: 'tom',
age: 10,
address: 'A001'
};
// 解构对象时变量名必须是对象的属性名。
let {name, age} = o;
console.log(name, age); // tom 10
16.箭头函数
// 1) 箭头返回
let a1 = (a, b) => a + b;
console.log(a1(1, 2)); // 3
let a2 = (a, b) => {
console.log(a, b);
return a + b;
};
console.log(a2(1, 2)); // 3
// 2 箭头函数返回对象
// 需要将对象写在()中
let a3 = () => {name:'tom'};
console.log(a3()); // undefined
let a4 = () => ({name: 'tom'});
console.log(a4()); // {name: 'tom'}
// 3 可以使用箭头函数的地方
let arr1 = [1, 2, 3, 4, 5];
arr1.forEach((element) => console.log(element)); // 1 2 3 4 5
let arr2 = [1, 2, 3, 4, 5];
arr2.sort((a, b) => b - a);
console.log(arr2); // (5) [5, 4, 3, 2, 1]
// 4 箭头函数的this,箭头函数的this在创建时就已经确定,
// 箭头函数的this由外层函数的this来决定。
let a5 = () => console.log(this);
a5(); // window
let o1 = {
f1:function () {
function f() {
console.log(this);
}
// f() 以函数的形式调用,所以this是window。
f();
}
};
o1.f1(); // window
let o2 = {
f1: function () {
let o = () => console.log(this);
// 箭头函数的this由外层函数的调用方式确定,所以this是obj。
o();
}
};
o2.f1(); // obj
17.闭包
// 1 闭包 闭包就是可以访问外部函数中变量的内部函数。
// 2 闭包的生命周期。当外部函数调用时闭包就产生了,外部函数每调用一次,
// 就会产生一个闭包。当内部函数被垃圾回收时,闭包就销毁了。
// 3 闭包的用途。闭包用来隐藏一下变量。
function out() {
let count = 0;
function inner() {
count++;
console.log(count);
}
return inner;
}
// out()函数的返回值inner()函数就是一个闭包。
let a1 = out();
a1(); // 1
a1(); // 2
// a1 = null,当被垃圾回收时,闭包销毁。
a1 = null;
// 如果希望记录函数的调用次数,并且闭包只被获取到一次,可以使用立即函数。
let a2 = (() => {
let count = 0;
function f1() {
count++;
console.log(count);
}
return f1;
})();
a2(); // 1
a2(); // 2