JavaScript笔记-系列
JavaScript基础笔记(1)
JavaScript基础笔记(2)
JavaScript基础笔记(3)
JavaScript笔记DOM操作
JavaScript—DOM案例
QX-AI
GPT-4
QX-AI初始化中...
暂无预设简介,请点击下方生成AI简介按钮。
介绍自己
生成预设简介
推荐相关文章
生成AI简介

JS对象简介

尽管JavaScript里没有Java,但两者都是面向对象语言,按顺序学过java这部分也是大差不差。

在JavaScript中,对象是一组无序的相关属性方法的集合。
对象中的属性均是键值对,属性名是键,属性值是值。

new关键字可以创建对象的实例。

1
2
3
4
5
6
7
8
9
10
11
var chuckle = ['轻笑', 19, '男'];
//虽然数组也是个对象,这js中是引用类型,但这样定义chuckle,值的表示不直观
//使用对象来表示,结构会更清晰
var chuckle = {};//也可以new Object()来创建一个对象
chuckle.name = '轻笑';
chuckle.age = 19;
chuckle.sex = '男';

console.log(chuckle);
//{name: '轻笑', age: 19, sex: '男'}
console.log(chuckle.name);//轻笑

对象的属性值可以是任何的数据类型,也可以是个函数

1
2
3
4
5
6
var obj = new Object();
obj.fun = function(){
console.log('这是一个函数');
};
console.log(obj.fun);//获取而不执行函数
console.log(obj.fun());//执行函数,这是一个函数

对象的属性也可以是另一个对象

1
2
3
4
5
6
var obj1 = new Object(); obj1.inObj;
var obj2 = new Object(); obj2.name = "一个对象";
//将整个obj2对象,设置为obj1的属性,保存的是对象的地址
obj1.inObj = obj2;
console.log(obj1.inObj);//{name: '一个对象'}
console.log(obj1.inObj.name);//一个对象

对象变量保存的是对象的地址,当两个变量指向同一个对象时,两个变量都可以修改对象中的属性。

对象的分类:

  1. 内置对象: 由ES标准中定义的对象,如:Object、Math、Date、String、Array、Number、Boolean、Function等。
  2. 宿主对象: 由JS的运行环境提供的对象,如浏览器提供了BOM、DOM,console、document。
  3. 自定义对象: 开发者创建的对象。

基本包装类型

基本数据类型string无法绑定属性和方法,但将其转换为基本包装类型,就可以。

1
2
3
var str = '';
str.name = '一个字符串';//不会报错,但无法绑定
console.log(str.name);//输出undefined

实际上,当我们对基本数据类型调用属性和方法(如str.length)时,js会自动将其临时转换为对应的基本包装类型(隐式类型转换),再调用内置方法。

基本包装类型包括:NumberBooleanString,它们都属于引用数据类型,可以绑定属性和方法。

1
2
3
var strObj = new String('');
strObj.name = '一个字符串';
console.log(strObj.name);//一个字符串
  1. String():将基本数据类型字符串,转换为 String 对象。
  2. Number():将基本数据类型的数字,转换为 Number 对象。
  3. Boolean():将基本数据类型的布尔值,转换为 Boolean 对象。

注意,在实际应用中一般不会使用基本数据类型的对象

在底层,字符串以字符数组的形式保存

1
2
3
var str = 'chuckle';//保存方式["c", "h", "u", "c", "k", "l", "e"]
console.log(str.length);//7
console.log(str[2]); //因为是数组,可以直接访问下标,字符串中的第3个字符,u

内置对象

内置对象是语言自带的一些对象,提供了最基本最常用的属性方法

Arguments(函数参数集合),Array(数组),Boolean(布尔对象),Math(数学对象),Date(日期时间),Error(异常对象),Function(函数构造器),Number(数值对象),Object(基础对象),RegExp(正则表达式对象),String(字符串对象)

字符串对象String

String字符串—JavaScript基础笔记(1)

字符串的所有方法,都不会改变原字符串

  1. indexOf()/lastIndexOf():获取字符串中指定内容的索引
  2. search():获取字符串中指定内容的索引(参数里一般是正则)
  3. includes():字符串中是否包含指定的内容
  4. startsWith():字符串是否以指定的内容开头
  5. endsWith():字符串是否以指定的内容结尾
  6. charAt()str[index]:返回字符串指定位置(下标)的字符
  7. charCodeAt(index):返回字符串指定位置的字符的 Unicode 编码
  8. slice():截取指定范围的字符串,可传入负值,代表倒数第几个字符(截取时包括该字符)
  9. substring():截取指定范围的字符串不可**传入负值,传入负值转为0,自动调整参数的位置,如果第二个参数小于第一个,则自动交换
  10. substr():从起始位置截取指定长度的字符串,两个参数,起始位置,截取指定长度**
  11. String.fromCharCode():据字符的 Unicode 编码获取字符
  12. concat():拼接两个字符串,不如直接用+号
  13. split():字符串转换为数组 【重要】
  14. replace():替换字符串内容
  15. repeat():重复该字符串指定次数
  16. toUpperCase()toLowerCase():大小写转换
  17. trim():去除字符串头尾的空格

查找字符

1、indexOf()/lastIndexOf():获取字符串中指定内容的索引

indexOf()从前向后查找,lastIndexOf()从后向前,用法一致。

功能:检索一个字符串中是否含有指定内容。如果字符串中含有该内容,则会返回其第一次出现的字符串底层数组下标(0代表在开头);如果没有找到指定的内容,则返回 -1。

1
2
3
4
5
6
var str = 'abc cba';
console.log(str.indexOf('c'));//2
console.log(str.lastIndexOf('c'));//4

console.log(str.indexOf('a'));//0
console.log(str.lastIndexOf('a'));//6
1
2
var str = 'chuckle';
console.log(str.indexOf('uc'));//2,代表uc第一个字符u是字符串中第三个字符

添加起始位置参数,指定查找的起始位置

1
2
3
var str = 'chuckle';
console.log(str.indexOf('uc',2));//从下标2即字符串第三个字符开始找起,输出2
console.log(str.indexOf('uc',3));//从下标3即字符串第四个字符开始找起,输出-1

案例:查找字符串”abcabcabc”中,所有 a 出现的位置以及次数

1
2
3
4
5
6
7
8
9
var str = "abcabcabc";
var num = 0;//记录次数
var index = -1;//记录位置下标,从-1开始
do{
index = str.indexOf('a', index + 1);//找到一个就从下一个字符下标开始找
if(index !== -1){
console.log(index);//输出下标0,3,6
}
}while(index !== -1);//找到了就接着去找,直到找不到

2、search():获取字符串中指定内容的索引(参数里一般是正则)

功能:检索一个字符串中是否含有指定内容。如果字符串中含有该内容,则会返回其第一次出现的字符串底层数组下标(0代表在开头);如果没有找到指定的内容,则返回 -1。

1
2
3
var str = 'CHUCKLE';
console.log(str.search('uc')); //-1
console.log(str.search(/uc/i)); //2 正则写法,忽略大小写

3、includes():字符串中是否包含指定的内容

功能:判断字符串中是否含有指定内容。有返回 true;否则返回 false。可以传入起始位置参数。

1
2
3
4
var str = "chuckle";
console.log(str.includes('uc')); //true
console.log(str.includes('ab')); //false
console.log(str.includes('ab',5)); //false

4、startsWith():字符串是否以指定的内容开头

功能:判断字符串是否以指定的字符串开头。是返回 true;否则返回 false。可以指定起始位置下标,指定的位置则当做字符串开头。

1
2
3
4
var str = "chuckle";
console.log(str.startsWith('uc')); //false
console.log(str.startsWith('c')); //true
console.log(str.startsWith('uc',2)); //true

5、endsWith():字符串是否以指定的内容结尾

功能:判断字符串是否以指定的字符串结尾。是返回 true;否则返回 false。可以指定检索的字符串长度(检索到第几个字符)。

1
2
3
4
var str = "chuckle"
console.log(str.endsWith('uc')); //false
console.log(str.endsWith('e')); //true
console.log(str.endsWith('uc',4)); //true

获取指定位置的字符

1、charAt()str[index]:返回字符串指定位置(下标)的字符

1
2
3
var str = "chuckle";
console.log(str.charAt(2));//u
console.log(str[2]);//u

2、charCodeAt(index):返回字符串指定位置的字符的 Unicode 编码

判断字符串中是否有非英文字符
1
2
3
4
5
6
7
var str = "chuckle轻笑";
for(let i = 0; i < str.length; i++){
let char = str.charCodeAt(i);//保存该字符的Unicode编码
if(!(char >= 0 && char <= 127)){//英文字符的Unicode编码在0~127
console.log(`存在非英文,在第${i+1}个字符`);//存在非英文,在第8个字符,存在非英文,在第9个字符
}
}

字符串截取

1、slice():截取指定范围的字符串,可传入负值,代表倒数第几个字符(截取时包括该字符)

两个参数都是索引值。正数时包左不包右
1
新字符串 = str.slice(开始索引, 结束索引);
1
2
3
4
5
var str = "qxchuckle";
console.log(str.slice(2));//chuckle,从下标2开始截取到最后
console.log(str.slice(2,str.length));//chuckle
console.log(str.slice(2, -1));//chuckl,从下标2开始截取到倒数第一个字符,包括,-0无效
console.log(str.slice(5, 2));//无效范围,返回空字符串

2、substring():截取指定范围的字符串不可传入负值,传入负值转为0,自动调整参数的位置,如果第二个参数小于第一个,则自动交换。

两个参数都是索引值。包左不包右
1
新字符串 = str.substring(开始索引, 结束索引);
1
2
3
4
5
var str = "qxchuckle";
console.log(str.substring(2)); //chuckle,从下标2开始截取到最后
console.log(str.substring(2,str.length)); //chuckle
console.log(str.substring(5, 2)); //chu,自动交换位置,相当于截取下标2到5
console.log(str.substring(2, -1)); //qx,-1看作0,然后自动交换位置

3、substr():从起始位置截取指定长度的字符串,两个参数,起始位置,截取指定长度

1
新字符串 = str.substr(开始索引, 截取的长度);
1
2
3
4
var str = "qxchuckle";
console.log(str.substr(2)); //chuckle,从下标2开始截取到最后
console.log(str.substr(2,100)); //chuckle,截取长度超过剩余长度时,只会截取剩余的字符
console.log(str.substr(100, 10)); //空字符串,截取不到任何字符

其它方法

String.fromCharCode():据字符的 Unicode 编码获取字符

1
2
var a = String.fromCharCode(97);
console.log(a);//a

concat():拼接两个字符串,不如直接用+号,数组中也有此方法,用于两个数组的拼接,那边常用

1
2
3
var str1 = "qx";
var str2 = "chuckle";
str2 = str1.concat(str2);//qxchuckle

split():字符串转换为数组 【重要】

功能:通过指定的分隔符,将字符串拆分成数组,分隔符不会出现在数组中。不传入参数则将整个字符串作为数组的一个元素存入。

1
2
3
4
var str = "qx,chuckle,轻笑";
console.log(str.split(',')); //['qx', 'chuckle', '轻笑']
console.log(str.split('')); //['q', 'x', ',', 'c', 'h', 'u', 'c', 'k', 'l', 'e', ',', '轻', '笑']
console.log(str.split()); //['qx,chuckle,轻笑']

replace():替换字符串内容

功能:将字符串中的指定内容,替换为一段字符串,默认只会替换第一个被匹配到的字符。如果要全局替换,需要使用正则。

1
新的字符串 = str.replace(被替换的子串,新的子串);
1
2
3
var str = "生活就像海洋,只有咕噜咕噜";
str = str.replace('咕噜咕噜','意志坚强的人才能到达彼岸');
console.log(str);//生活就像海洋,只有意志坚强的人才能到达彼岸

repeat():重复该字符串指定次数

1
2
3
var str = "chuckle!"
str = str.repeat(2);//重复两次
console.log(str);//'chuckle!chuckle!'

trim():去除字符串头尾的空格

1
2
3
4
5
6
var str = '   a   b   c   ';
console.log(str);//' a b c '
console.log(str.length);//15

console.log(str.trim());//'a b c'
console.log(str.trim().length);//9

toUpperCase()toLowerCase():大小写转换

1
2
3
4
5
var str = 'abcdEFG';
//转换成小写
console.log(str.toLowerCase()); //abcdefg
//转换成大写
console.log(str.toUpperCase()); //ABCDEFG

html方法:不常用,多数是拼接成模板字符串返回

1
2
3
4
5
6
7
var str = "chuckle";
console.log(str.anchor('chuckle'));//<a name="chuckle">chuckle</a>
console.log(str.big());//<big>chuckle</big>
console.log(str.sub());//<sub>chuckle</sub>
console.log(str.sup());//<sup>chuckle</sup>
console.log(str.link('https://www.qcqx.cn/'));//<a href="https://www.qcqx.cn/">chuckle</a>
console.log(str.bold());//<b>chuckle</b>

数值对象Number

Number数值型介绍—JavaScript基础笔记(1)

  1. Number.isInteger():判断是否为整数
  2. toFixed(num):保留小数点后num位(四舍五入),返回字符串

Number.isInteger():判断是否为整数

1
布尔值 = Number.isInteger(数字);
1
2
3
4
5
6
7
8
var a = 10;
console.log(Number.isInteger(a));//true
a = -10;
console.log(Number.isInteger(a));//true
a = 1.00;
console.log(Number.isInteger(a));//true,虽然有小数点,但后面都是0,所以会被当做整数
a = 3.14;
console.log(Number.isInteger(a));//false

toFixed(num):保留小数点后num位(四舍五入),返回字符串,将字符串转为整数可用Number(),详见数据类型转换—JavaScript基础笔记(1)

注意返回字符串!
1
字符串 = nb.toFixed(num);
1
2
3
4
var nb = 3.1415926;
console.log(nb.toFixed(1));//3.1
console.log(nb.toFixed(3));//3.142
console.log(nb.toFixed(4));//3.1416

数学对象Math

Math不是一个构造函数,无需创建对象即可直接使用其属性和方法,它是一个工具类,里面封装了数学运算相关的属性和方法。

  1. Math.PI:圆周率
  2. Math.abs():获取绝对值
  3. Math.random():生成0-1之间的随机浮点数,[0,1)
  4. Math.floor():向下取整(往小取值)
  5. Math.ceil():向上取整(往大取值)
  6. Math.round():四舍五入取整(正数四舍五入,负数五舍六入)
  7. Math.max(x, y, z):返回多个数中的最大值
  8. Math.min(x, y, z):返回多个数中的最小值
  9. Math.pow(x,y):乘方:返回 x 的 y 次幂
  10. Math.sqrt():开方:对一个数进行开方运算

Math.abs():获取绝对值,可传入字符串,自动做隐式转换。

1
2
3
4
5
console.log(Math.abs(10));//10
console.log(Math.abs(-10));//10
console.log(Math.abs('-10'));//10
console.log(Math.abs(-3.14));//3.14
console.log(Math.abs('123abc'));//NaN

Math.random():生成0-1之间的随机浮点数,[0,1)

一些技巧
1
2
3
4
5
6
//生成 [0, x) 之间的随机整数
Math.round(Math.random()*x);
//生成 [x, y) 之间的随机整数
Math.round(Math.random()*(y-x)+x)
//生成 [x, y]之间的随机整数
Math.floor(Math.random()*(y-x+1))+x;

时间对象Date

Date用于处理日期和时间,Date是一个构造函数,需要new实例化后才能使用。

无参时获取系统时间

1
2
3
var date = new Date();
console.log(date);//Wed Mar 29 2023 15:08:02 GMT+0800 (中国标准时间)
console.log(typeof date);//object

传递参数,意思是给时间对象Date设定一个具体的时间,基准时间为1970年1月1日 00:00:00,具体小时差别要看时区,东八区+8小时。

使用方法
1
2
3
4
5
6
var date = new Date(传入毫秒数(时间戳));//表示基准时间加上这个毫秒数
//至少要两个参数,不能缺少年,会自动进位,其余默认都是首时间
var date = new Date(年,月,日,时,分,秒,毫秒);//月份是0到11之间的整数值,表示从一月到十二月
//传入时间字符串,有格式要求,星期 月 日 年 时:分:秒
var date = new Date(时间字符串);
//Thu Jan 01 1970 08:00:00 GMT+0800 (中国标准时间)
1
2
3
4
5
6
7
//传入2000毫秒,表示基准时间过2s
var date = new Date(2000);//Thu Jan 01 1970 08:00:02 GMT+0800 (中国标准时间)
//设定日期为2023年3月,传入2代表3月
var date = new Date(2023,2);//Wed Mar 01 2023 00:00:00 GMT+0800 (中国标准时间)
//传入时间字符串,有格式要求,分隔符任意,可以看到,星期不对会自动修正
var date = new Date('Wed Apr 21 2023');//Fri Apr 21 2023 00:00:00 GMT+0800 (中国标准时间)
var date = new Date("2023/3/29 11:11:11");//Wed Mar 29 2023 11:11:11 GMT+0800 (中国标准时间)

常用方法

  1. getFullYear():获取年份
  2. getMonth():获取月,0到11之间的整数值,表示从一月到十二月
  3. getDate():获取日:1-31
  4. getDay():获取星期:0-6,0代表星期日
  5. getHours():获取小时:0-23
  6. getMinutes():获取分钟:0-59
  7. getSeconds():获取秒:0-59
  8. getMilliseconds():获取毫秒
  9. setFullYear():修改日期,参数:年,月,日,时,分,秒,毫秒。返回时间戳
  10. toUTCString():将当日的日期(根据 UTC)转换为字符串
  11. toJSON():将日期转为json格式
  12. getTime():获取时间戳
  13. toLocaleString() 格式化输出 2023/4/12 09:39:49
举例:
1
2
3
4
5
6
7
8
9
10
var date = new Date(1680076326495);//Wed Mar 29 2023 15:52:06 GMT+0800 (中国标准时间)
console.log(date.getFullYear());//2023
console.log(date.getMonth());//2
console.log(date.getDate());//29
console.log(date.getDay());//3
console.log(date.getHours());//15
console.log(date.getMinutes());//52
console.log(date.getSeconds());//6
console.log(date.getMilliseconds());//495

toUTCString():将当日的日期(根据 UTC)转换为字符串

1
2
var d = new Date();//Wed Mar 29 2023 16:11:02 GMT+0800 (中国标准时间)
d.toUTCString()//'Wed, 29 Mar 2023 08:11:02 GMT'

setFullYear():修改日期,参数:年,月,日,时,分,秒,毫秒,返回时间戳

1
2
3
4
var d = new Date(2023,0);
var t = d.setFullYear(2020,10);
console.log(t);//1604160000000
console.log(new Date(t));//Sun Nov 01 2020 00:00:00 GMT+0800 (中国标准时间)

toJSON():将日期转为json格式

1
2
3
var d = new Date(2023,0);
var t = d.toJSON();
console.log(t);//2022-12-31T16:00:00.000Z

获取时间戳

getTime():获取时间戳,也就是返回从基准时间至今的毫秒数(时间戳也可以是秒数,但函数返回的是毫秒数)。

1
2
3
4
var date = new Date(2023,0);
console.log(date);//Sun Jan 01 2023 00:00:00 GMT+0800 (中国标准时间)
var time = date.getTime();//1672502400000
var date = new Date(time);//Sun Jan 01 2023 00:00:00 GMT+0800 (中国标准时间)

还有其它方法可以获取时间戳:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var time1 = +new Date();
console.log(time1);//1680076996003

var time2 = new Date().getTime();
console.log(time2);//1680076996003

var time3 = new Date().valueOf();
console.log(time3);//1680076996003

var time4 = new Date() * 1;
console.log(time4);//1680076996003

var time5 = Number(new Date());
console.log(time5);//1680076996003

获取当前时间的时间戳可以用这种方法

1
console.log(Date.now());//1680077268109

转为指定格式

使用 toLocaleString() 简单格式化输出

1
2
new Date().toLocaleString();
// 2023/4/12 09:39:49

也可以通过Date的prototype属性在原型上添加自定义的属性和方法,给Date对象添加format()方法,该方法封装如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Date.prototype.format = function(fmt) { 
var o = {
"M+" : this.getMonth()+1, //月份
"d+" : this.getDate(), //日
"h+" : this.getHours(), //小时
"m+" : this.getMinutes(), //分
"s+" : this.getSeconds(), //秒
"q+" : Math.floor((this.getMonth()+3)/3), //季度
"S" : this.getMilliseconds() //毫秒
};
if(/(y+)/.test(fmt)) {
fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
}
for(var k in o) {
if(new RegExp("("+ k +")").test(fmt)){
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
}
}
return fmt;
}

使用案例,分隔符任意
1
2
3
4
5
6
7
8
var date = new Date(1680076326495);//Wed Mar 29 2023 15:52:06 GMT+0800 (中国标准时间)
var time = date.format("yyyy-MM-dd hh:mm:ss");
console.log(time);// 2023-03-29 15:52:06
time = date.format("yyyy/MM/dd");
console.log(time);// 2023/03/29
time = date.format("yyyy年MM月dd日 hh时mm分ss秒");
console.log(time);// 2023年03月29日 15时52分06秒

还可引入各种时间库来处理,如momentjsDay.js

数组对象Array

下面是一个普通对象和数组对象:

1
2
var obj = {name: 'chuckle' , age: 19 };
var arr = ["chuckle","19"];

普通对象使用字符串作为属性名,而数组使用数字作为索引,数组适合用于存储同类型的一组数据,如列表数据。

数组中的元素可以是任意的数据类型,可以是对象、函数、数组。也可以同时存储不同类型数据

1、使用字面量创建数组:

1
2
var arr = []; // 创建空数组
arr = [1, 2, 3]; // 带初始值的数组

2、使用构造函数创建数组对象:

1
2
3
var arr = new Array(); // 创建空数组
arr = new Array(4); // 创建大小为4的数组,初始值都为空属性
arr = new Array(1,2,3); // 带初始值的数组

JS中的数组会自动扩容,当我们访问数组大小以外的下标时,会返回undefined,但可以直接给超过数组大小的下标赋值,并自动给扩容的下标赋空属性,注意,空属性也会计入数组的长度 arr.length

1
2
3
4
5
6
7
8
9
var arr = [1, 2, 3];
console.log(arr); // [1, 2, 3]
console.log(arr.length); // 3
console.log(arr[6]);// undefined

arr[6] = 7;
console.log(arr); // [1, 2, 3, 空属性 × 3, 7]
console.log(arr[4]); // undefined
console.log(arr.length); // 7

解构赋值

解构赋值是ES6中新增的一种赋值方式。可以方便地把数组中的元素按顺序赋值给其他多个变量。

1
2
3
4
5
var arr = [1, 2, [3,4]];
var [a, b, c] = arr;
console.log(a);// 1
console.log(b);// 2
console.log(c);// [3,4]

先指定变量的默认值,会被覆盖

1
2
3
4
5
6
var arr = [1, 2, [3,4]];
var [a, b = 0, c = 0, d = 0] = arr;
console.log(a);// 1
console.log(b);// 2
console.log(c);// [3,4]
console.log(d);// 0,数组中无第四个元素,保持原值

ES6中新增的扩展运算符...打包剩余的数据作为一个新数组打包时扩展运算符只能写在最后。

1
2
3
var [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]

数组属性和方法

arr.length数组的长度,数组中元素的个数

数组的方法:

  1. 类型相关方法:
    1. Array.isArray():判断是否为数组
    2. toString():将数组转换为字符串
    3. join():将数组转换为字符串,可以指定分隔符
    4. Array.from():将伪数组或可遍历对象转为真数组
    5. Array.of(a,b,c):将多个值按顺序转为数组
    6. 字符串的方法:split():将字符串按指定的分隔符,组装为数组
  2. 元素的添加和删除:
    1. push():从数组尾部插入任意数量元素,返回新数组的长度改变原数组
    2. pop():删除数组中最后一个元素,返回被删除的元素,改变原数组
    3. unshift():从数组头部插入任意数量元素,返回新数组的长度改变原数组
    4. shift():删除数组中第一个元素,返回被删除的元素,改变原数组
    5. splice():从数组中删除指定的任意数量元素,返回被删除元素组成的新数组,改变原数组
    6. slice():从数组中提取指定的任意数量元素,返回新数组不改变原数组
    7. concat():合并多个数组,返回合并后的新数组,不改变原数组
    8. fill():用固定的值填充数组,返回新数组,改变原数组
  3. 数组排序:
    1. reverse():反转数组,返回反转后的数组,改变原数组
    2. sort():排序,元素默认按照Unicode编码,从小到大进行排序,改变原数组
  4. 查找数组元素:
    1. indexOf()从前往后搜索数组中的元素,并返回它首次所在位置的索引。
    2. lastIndexOf()从后往前搜索数组中的元素,并返回它首次所在位置的索引。
    3. includes():判断数组是否包含一个指定的值,返回布尔
    4. find(function()):返回第一个符合传入测试(函数)条件的数组元素。
    5. findIndex(function()):返回第一个符合传入测试(函数)条件的数组元素的索引
    6. every(function()):检测数组所有元素是否符合指定(函数)条件,返回布尔
    7. some(function()):检测数组是否存在符合指定(函数)条件的元素,返回布尔
    8. valueOf():返回数组本身,意义不大,数组名就代表该数组了
  5. 遍历数组:
    1. for循环遍历,大多数语言对于数组通用的遍历方法
    2. forEach()传入一个回调函数作为参数,它由我们创建但是不由我们调用,数组中有几个元素,该回调函数就会执行几次,没用返回值
    3. for of,ES6新增循环遍历数组方法
    4. map(),遍历数组,并对数组中的每一项进行加工。
    5. filter():数组中的每一项运行回调函数,回调函数返回结果是true的项(符合条件的项),组成新数组返回,不改变原数组
    6. reduce():参数是接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值返回

类型相关方法

Array.isArray():判断是否为数组

1
2
3
4
var a = [];
console.log(Array.isArray(a));//true
a = {};
console.log(Array.isArray(a));//false

toString():将数组转换为字符串,每一项用逗号分割。

大多数的数据类型都可以使用.toString()方法,将其转换为字符串。

1
2
var a = [1,[2,3],{name:'chuckle',age:19},function(){}];
console.log(a.toString());//1,2,3,[object Object],function(){}

还可以使用String()将数组转换为字符串

1
2
var a = [1,[2,3],{name:'chuckle',age:19},function(){}];
console.log(String(a));//1,2,3,[object Object],function(){}

join():将数组转换为字符串,可以指定分隔符,默认为逗号分割。

1
2
3
4
var a = [1,[2,3],{name:'chuckle',age:19},function(){}];
console.log(a.join());//1,2,3,[object Object],function(){}
console.log(a.join(' '));//1 2,3 [object Object] function(){}
console.log(a.join('|'));//1|2,3|[object Object]|function(){}

可以使用JSON.stringify()将某个对象转换成 JSON 字符串形式,数组中的空属性会转为null。

1
2
3
4
var arr = [];
arr[5] = 6;
console.log(arr); // [空属性 × 5, 6]
console.log(JSON.stringify(arr)); // [null,null,null,null,null,6]

字符串的方法:split():将字符串按指定的分隔符,组装为数组,默认为逗号分割,找不到指定分隔符时也会用逗号分割

1
2
3
4
5
var str = "qx,chuckle,轻笑"
console.log(str.split());//['qx,chuckle,轻笑']
console.log(str.split(''));//['q', 'x', ',', 'c', 'h', 'u', 'c', 'k', 'l', 'e', ',', '轻', '笑']
console.log(str.split('-'));//['qx,chuckle,轻笑']
console.log(str.split('c'));// ['qx,', 'hu', 'kle,轻笑']

Array.from():将伪数组或可遍历对象转为真数组

伪数组也有length属性,可以使用索引对数据进行操作,但是没有真数组的方法,因为该对象的原型不指向Array,需要将伪转真才能调用数组的方法。

伪数组一般不会直接创建,而是通过一些js操作得到,通过浏览器方法获取标签、字符串、接受实参的函数arguments得到参数的伪数组,因为伪数组具有长度和索引,所以可以使用循环语句遍历。

1
2
3
4
5
6
var str = "chuckle";
str.push('qx');//报错str.push is not a function
var a = Array.from(str);
console.log(a);//['c', 'h', 'u', 'c', 'k', 'l', 'e']
a.push('qx')
console.log(a);// ['c', 'h', 'u', 'c', 'k', 'l', 'e', 'qx']

Array.of(a,b,c):将多个值按顺序转为字符串,和new Array()差不多,区别是只有一个参数时,在new Array()表示数组的长度,而在of()仍然代表数组的元素

1
2
3
4
5
6
var arr = Array.of(1, [2,3], 'qx');
console.log(arr);// [1, Array(2), 'qx']
arr = Array.of(3);
console.log(arr);// [3]
arr = new Array(3);
console.log(JSON.stringify(arr));// [null,null,null]

元素的添加和删除

push()从数组尾部插入任意数量元素,返回新数组的长度改变原数组

1
2
3
var arr = [1,2,3];
console.log(arr.push(4,5,'123'));// 6
console.log(JSON.stringify(arr));// [1, 2, 3, 4, 5, '123']

pop()删除数组中最后一个元素,返回被删除的元素,改变原数组

1
2
3
var arr = [1,2,3];
console.log(arr.pop());// 3
console.log(JSON.stringify(arr));// [1,2]

unshift()从数组头部插入任意数量元素,返回新数组的长度改变原数组

1
2
3
var arr = [1,2,3];
console.log(arr.unshift('0123',0));// 5
console.log(JSON.stringify(arr));// ["0123",0,1,2,3]

shift()删除数组中第一个元素,返回被删除的元素,改变原数组

1
2
3
var arr = [1,2,3];
console.log(arr.shift());// 1
console.log(JSON.stringify(arr));// [2,3]

splice()从数组中删除指定的任意数量元素,返回被删除元素组成的新数组,改变原数组

语法,索引值为负代表从倒数第几个开始删
1
2
3
新数组 = 原数组.splice(起始索引);
新数组 = 原数组.splice(起始索引, 需要删除的个数);
新数组 = 原数组.splice(起始索引, 需要删除的个数, 新的元素1, 新的元素2...);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var arr = [1,2,3,4,5];
console.log(arr.splice(1));// 删除下标1后的所有元素,[2, 3, 4, 5]
console.log(JSON.stringify(arr));// [1]

arr = [1,2,3,4,5];
console.log(arr.splice(1,2));// 从下标1开始删两个元素,包括下标1,[2, 3]
console.log(JSON.stringify(arr));// [1,4,5]

arr = [1,2,3,4,5];
console.log(arr.splice(1,2,'a','b'));// 删完后再从删除的起始位置插入'a','b'元素,[2, 3]
console.log(JSON.stringify(arr));// [1,"a","b",4,5]

arr = [1,2,3,4,5];
console.log(arr.splice(-2));// 从倒数第2个元素开始删后面的所有元素,[4, 5]
console.log(JSON.stringify(arr));// [1,2,3]

搭配indexOf(),删除指定内容的元素

1
2
3
var arr = [1,2,3,4,5];
console.log(arr.splice(arr.indexOf(3), 1));// 删除3这个元素,[3]
console.log(JSON.stringify(arr));// [1,2,4,5]

slice():从数组中提取指定的任意数量元素,返回新数组不改变原数组

语法,负数代表倒数索引
1
2
新数组 = 原数组.slice(开始位置的索引);
新数组 = 原数组.slice(开始位置的索引, 结束位置的索引);//提取的元素中,包含开始位置,不包含结束位置
1
2
3
4
5
6
var arr = ['a', 'b', 'c', 'd'];
console.log(arr.slice()); // 不带参数提取所有元素,['a', 'b', 'c', 'd']
console.log(arr.slice(2)); // 从下标2提取后面所有元素,['c', 'd']
console.log(arr.slice(-2)); // 提取最后两个元素,['c', 'd']
console.log(arr.slice(1,3)); // 提取[1,3)索引的元素,['b', 'c']
console.log(arr.slice(3,1)); // 范围内无元素,提取为空数组,[]

concat()合并多个数组,返回合并后的新数组,不改变原数组

1
2
3
4
5
var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
var arr3 = [7, 8, 9];
console.log(arr1.concat(arr2,arr3));// [1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(arr1);// 不改变原数组 [1, 2, 3]

数组合并的另一种方式:使用扩展运算符...

1
2
3
var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
var a = [0, ...arr1, ...arr2, 7];//[0, 1, 2, 3, 4, 5, 6, 7]

fill()用固定的值填充数组,返回新数组,改变原数组

1
2
3
4
5
6
// 数组中每一个元素都替换为该值
新数组 = 数组.fill(固定值);
//从起始位置开始填充
新数组 = 数组.fill(固定值, 起始索引);
//从起始位置到结束位置填充,左闭右开
新数组 = 数组.fill(固定值, 起始索引, 结束索引);
1
2
3
4
5
6
var arr = new Array(6).fill(0)//创建一个元素均为0,长度为6的数组
console.log(arr);// [0, 0, 0, 0, 0, 0]
arr.fill('a',2);//索引2后的所有元素填充为'a'
console.log(arr);// [0, 0, 'a', 'a', 'a', 'a']
arr.fill('b',2,4);//索引[2,4)的元素填充为'b'
console.log(arr);// [0, 0, 'b', 'b', 'a', 'a']

数组排序

reverse():反转数组,返回反转后的数组,改变原数组

1
2
3
var arr = ['a', 'b', 'c', 'd', 'e'];
console.log(arr.reverse());// ['e', 'd', 'c', 'b', 'a']
console.log(arr);// ['e', 'd', 'c', 'b', 'a']

sort():排序,元素默认按照Unicode编码(逐个字符比较,非字符串先隐式转换为字符串),从小到大进行排序,返回排序后的新数组,改变原数组

1
2
3
var arr = ['c', 'e', 'a', 'd', 'b'];// 乱序
console.log(arr.sort());// ['a', 'b', 'c', 'd', 'e']
console.log(arr);// ['a', 'b', 'c', 'd', 'e']

当数组内元素是数字时,不能直接使用sort()排序,因为默认是按逐个字符的Unicode编码进行排序

1
2
3
var arr = [7, 3, 11, 4, 1, 5];
//11排到了3的前面,没有按我们所想的从小到大排
console.log(arr.sort());//[1, 11, 3, 4, 5, 7]

对于非字符串排序(数字的排序),需要传入一个比较函数,有两个参数 a 和 b(可以是数组中任意元素

arr.sort(Fun(a, b)),a:第一个用于比较的元素,b:第二个用于比较的元素,数组按照比较函数的返回值进行排序,而不是Unicode编码。

JS规定了Fun(a, b)返回值的效果:

  1. 返回值小于0,让a排b前面
  2. 返回值大于0,让a排b后面
  3. 返回值等于0,a,b的相对位置不变

对于[7, 3, 11, 4, 1, 5]这个数组,比较11和4时,不带比较函数,会按Unicode编码从小到大排序,11会排在4前面,带比较函数后,因为a-b=7大于零,所以会让4排11前面。

1
2
3
4
//实现整体升序(小到大)
arr.sort((a, b) => a - b);
//实现整体降序(大到小)
arr.sort((a, b) => b - a);
实际用用
1
2
3
4
var arr = [7, 3, 11, 4, 1, 5];
arr.sort();//[1, 11, 3, 4, 5, 7]
arr.sort((a, b) => a - b);// [1, 3, 4, 5, 7, 11]
arr.sort((a, b) => b - a);// [11, 7, 5, 4, 3, 1]

Fun(a, b)具体比较什么,什么情况返回大于0的数,什么时候返回小于0,需要自己去编写,所以可以实现商品的按价格排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//这个数组中存放了几个商品对象,试着让它们按价格升序排序
var commodityList = [
{
name: 'biscuit',
price: 10,
},
{
name: 'Coke',
price: 3,
},
{
name: 'toy',
price: 8,
},
{
name: 'bread',
price: 5,
},
];

commodityList.sort((a, b) => {
// 比较价格,规范起见,都进行parseInt()转换,也可以用parseFloat(),看业务需要
return parseInt(a.price) - parseInt(b.price);
});

console.log(JSON.stringify(commodityList));

输出如下
1
2
3
4
5
6
[ 
{"name":"Coke","price":3},
{"name":"bread","price":5},
{"name":"toy","price":8},
{"name":"biscuit","price":10}
]

查找数组元素

indexOf() 从前往后搜索数组中的元素,并返回它首次所在位置的索引。
lastIndexOf() 从后往前搜索数组中的元素,并返回它首次所在位置的索引。

找到元素返回其索引,没找到返回-1严格类型约束,类似===。

1
2
3
4
5
6
var arr = ['1', 2, 1, '2'];
console.log(arr.indexOf(1));// 2
console.log(arr.indexOf('1'));// 0
console.log(arr.indexOf('2'));// 3
console.log(arr.indexOf(2));// 1
console.log(arr.indexOf(3));// -1

可以指定第二个参数,指定查找的起始位置,包括该位置

1
2
3
4
5
var arr = [1, 2, 3, 4, 3, 2, 1];
//正着从数组一半开始找
console.log(arr.indexOf(1, parseInt(arr.length/2)));// 6
//倒着从数组一半开始找
console.log(arr.lastIndexOf(1, parseInt(arr.length/2)));// 0

includes()判断数组是否包含一个指定的值,严格类型约束,返回布尔,可以加上第二个参数规定查找的起始位置。

1
2
3
4
5
var arr = [1, 2, '3', '4'];
console.log(arr.includes(1)); // true
console.log(arr.includes('1')); // false
console.log(arr.includes(2, 2)); // false
console.log(arr.includes('3', 2)); // true

find(function())返回第一个符合传入测试(函数)条件的数组元素。
findIndex(function())返回第一个符合传入测试(函数)条件的数组元素的索引

找到符合条件的第一个元素就停止查找,没找到返回find()返回undefinedfindIndex()返回-1

找到大于30的第一个元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var arr = [10, 20, 30, 40, 50, 60];
//用find
var result = arr.find((item, index, array) => {
// item是元素内容,index是该元素索引,array是该数组
return item > 30;
});
console.log(result);// 40
//用findIndex
var result = arr.findIndex((item, index, array) => {
// item是元素内容,index是该元素索引,array是该数组
return item > 30;
});
console.log(result);// 3

every(function()):检测数组所有元素是否符合指定(函数)条件,返回布尔,有一项返回 false 立刻停止遍历。
some(function()):检测数组是否存在符合指定(函数)条件的元素,返回布尔,有一项返回 true 立刻停止遍历。

every():全部真,才为真,some():一个真,就为真,

every举例
1
2
3
4
5
6
var arr = [10, 20, 30, '40', '50', '60'];
var result = arr.every((item, index, array) => {
// item是元素内容,index是该元素索引,array是该数组
return item > 0;// 判断数组中元素是否都大于0,字符串会隐式转为数值
});
console.log(result);// true
some举例
1
2
3
4
5
6
var arr = [10, 20, 30, '40', '50', '60'];
var result = arr.some((item, index, array) => {
// item是元素内容,index是该元素索引,array是该数组
return item > 30;// 判断是否有大于0的元素,字符串会隐式转为数值
});
console.log(result);// true

遍历数组

for循环遍历,大多数语言对于数组通用的遍历方法

1
2
3
4
5
6
var arr = [1, 2, 3, 4, 5];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
//1 2 3 4 5
console.log(JSON.stringify(arr));//[1,2,3,4,5]

这不够优雅,JS有更简单便捷遍历数组的方法

forEach()传入一个回调函数作为参数,它由我们创建但是不由我们调用,数组中有几个元素,该回调函数就会执行几次,没用返回值

1
2
3
arr.forEach(function (item, index, array) {
//做些事情
});

回调函数中传递三个参数:

  1. 参数1(item):当前正在遍历的元素
  2. 参数2(index):当前正在遍历的元素的索引
  3. 参数3(array):正在遍历的数组
1
2
3
4
5
var arr = [1, 2, 3, 4, 5];
arr.forEach(function (item, index, array) {
console.log(`${index}:${item}`);
});
//0:1 1:2 2:3 3:4 4:5

forEach()的回调函数中不能通过参数1(item)直接修改数组中的元素,但元素是一个对象时,可以访问并修改该对象的属性,这是因为数组中存放的是该对象的引用(地址)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var arr = [1, 2, 3, 4, 5];
arr.forEach(function (item, index, array) {
item += 1;//试图让数组中的元素都加1
});
console.log(JSON.stringify(arr));//[1,2,3,4,5]很显然,做不到

var arr = [{name: 'qx', age: 19}];
arr.forEach(function (item, index, array) {
item = {name: 'chuckle', age: 19}//试图修改数组中的元素
});
console.log(JSON.stringify(arr));//[{"name":"qx","age":19}]很显然,做不到

var arr = [{name: 'qx', age: 19}];
arr.forEach(function (item, index, array) {
item.name = 'chuckle';//试图访问该对象的属性并修改
});
console.log(JSON.stringify(arr));//[{"name":"chuckle","age":19}]很显然,这是可以的

如果要修改数组中的元素,需通过参数2(index)和3(array)array[index]来访问数组元素并修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var arr = [1, 2, 3, 4, 5];
arr.forEach(function (item, index, array) {
array[index] += 1;//试图让数组中的元素都加1
});
console.log(JSON.stringify(arr));//[2,3,4,5,6]可以做到

var arr = [{name: 'qx', age: 19}];
arr.forEach(function (item, index, array) {
array[index] = {name: 'chuckle', age: 19}//试图修改数组中的元素
});
console.log(JSON.stringify(arr));//[{"name":"chuckle","age":19}]可以做到

var arr = [{name: 'qx', age: 19}];
arr.forEach(function (item, index, array) {
array[index].name = 'chuckle';//试图访问该对象的属性并修改
});
console.log(JSON.stringify(arr));//[{"name":"chuckle","age":19}]可以做到

纯粹只是遍历数组,可以用forEach(),但同时要修改元素时,最好使用map(),避免一些低级错误

for of,ES6新增循环遍历数组方法

1
2
3
4
5
6
var arr = [1, 2, 3, 4, 5];
for(let item of arr) {
//item是元素的拷贝,无法直接修改item来修改元素值
console.log(item);
}
// 1 2 3 4 5

for in用于遍历无序的对象的属性,而不是有序的数组

1
2
3
4
5
6
7
8
9
10
11
var obj = {
name: 'chuckle',
age: '19'
};
for(let key in obj) {
//key是属性名,obj[key]可以修改属性值
console.log(`属性名:${key},值:${obj[key]}`);
}
//属性名:name,值:chuckle
//属性名:age,值:19

map(),遍历数组,并对数组中的每一项进行加工。

对数组中每一项运行回调函数,返回每一项加工后的结果,组成的新数组,不改变原数组

语法
1
2
3
4
var newArr = arr.map((item, index, array) => {
// item是元素内容,index是该元素索引,array是该数组
return newItem;//返回该项加工后的结果
});
1
2
3
4
5
var arr = [1, 2, 3, 4, 5];
var newArr = arr.map((item, index, array) => {
return item += 1;//返回每一项加一
});
console.log(JSON.stringify(newArr));//[2,3,4,5,6]

常用案例:将 A 数组(通常存对象)中某个属性的值,存储到 B 数组中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var arr = [
{ name: '张三', age: 19 },
{ name: '李四', age: 18 },
{ name: '王五', age: 20 },
];

//把属性name都提取出来
var newArr = arr.map((item) => item.name);//返回每个item的name属性
console.log(JSON.stringify(newArr));//["张三","李四","王五"]

//重新组一个对象,改键名
newArr = arr.map((item) => ({
myName: item.name,
myAge: item.age,
}));//把属性拿出来重新组一个对象
console.log(JSON.stringify(newArr));
//[{"myName":"张三","myAge":19},{"myName":"李四","myAge":18},{"myName":"王五","myAge":20}]

filter()数组中的每一项运行回调函数,回调函数返回结果是true的项(符合条件的项),组成新数组返回,不改变原数组

1
2
3
4
5
var arr = [7, 2, 3, 6, 7, 4];
var newArr = arr.filter(item => {
return item > 4;//item > 4回调函数返回true,filter()就把该元素放进新数组里
});
console.log(JSON.stringify(newArr));//[7,6,7]
1
2
3
4
5
6
7
8
9
10
11
12
var arr = [
{ name: '张三', age: 19 },
{ name: '李四', age: 18 },
{ name: '王五', age: 20 },
];
//筛选出年龄大于18的同学
var newArr = arr.filter((item) => item.age > 18);
console.log(JSON.stringify(newArr));//[{"name":"张三","age":19},{"name":"王五","age":20}]
//再用map()筛选出名字
var resultArr = newArr.map((item) => item.name);
console.log(JSON.stringify(resultArr));//["张三","王五"]

reduce()参数是接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值返回

reduce() 对于空数组不会执行回调函数

语法
1
var result = arr.reduce((prev, item, index, array) => {}, initialValue);

回调函数参数解释:

  1. prev:必填,上一次调用回调函数时的返回值
  2. item:必填,当前正在处理的数组元素
  3. index:可选,当前正在处理的数组元素下标
  4. array:可选,该数组
  5. initialValue:可选,作为第一次调用回调函数时传给prev的值,最好手动初始化为0

举例 1、数组求和:

1
2
3
4
5
var arr = [1, 2, 3, 4, 5, 6];
var result = arr.reduce((prev, item) => {
return prev + item;// 累计求和
});
console.log(`总和:${result}`); // 总和:21

举例 2、统计某个元素出现的次数:

1
2
3
4
5
6
7
8
9
10
11
12
13
var arr = [5, 2, 6, 4, 3, 6];

//统计函数,传入数组arr和要统计的value,返回value出现的次数
function arrCount(arr, value){
return arr.reduce((prev, item)=>{
//判断当前项item是否等于value,是则让prev计数加一并返回
return prev += item === value ? 1 : 0;
}, 0);
}

console.log(arrCount(arr, 6)); // 2
console.log(arrCount(arr, 7)); // 0

举例 3、找到最大的元素:

1
2
3
4
5
6
7
8
9
10
11
12
13
var arr = [5, 2, 6, 7, 3, 6];

//传入数组arr,返回最大元素(首次找到)的下标
function maxValue(arr){
return arr.reduce((prev, item, index, arr) => {
//prev初始值为0,默认下标0的元素最大,每一项与arr[prev]比较,大于就更新prev为当前下标index
return prev = item > arr[prev] ? index : prev;
}, 0)
}

console.log(maxValue(arr));// 3
console.log(arr[maxValue(arr)]);// 7