JS对象简介
尽管JavaScript里没有Java,但两者都是面向对象语言,按顺序学过java这部分也是大差不差。
在JavaScript中,对象是一组无序的相关属性和方法的集合。 对象中的属性均是键值对,属性名是键,属性值是值。
new关键字可以创建对象的实例。
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);//轻笑对象的属性值可以是任何的数据类型,也可以是个函数
var obj = new Object();obj.fun = function(){ console.log('这是一个函数');};console.log(obj.fun);//获取而不执行函数console.log(obj.fun());//执行函数,这是一个函数对象的属性也可以是另一个对象
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);//一个对象对象变量保存的是对象的地址,当两个变量指向同一个对象时,两个变量都可以修改对象中的属性。
对象的分类:
- 内置对象: 由ES标准中定义的对象,如:Object、Math、Date、String、Array、Number、Boolean、Function等。
- 宿主对象: 由JS的运行环境提供的对象,如浏览器提供了BOM、DOM,console、document。
- 自定义对象: 开发者创建的对象。
基本包装类型
基本数据类型string无法绑定属性和方法,但将其转换为基本包装类型,就可以。
var str = '';str.name = '一个字符串';//不会报错,但无法绑定console.log(str.name);//输出undefined实际上,当我们对基本数据类型调用属性和方法(如str.length)时,js会自动将其临时转换为对应的基本包装类型(隐式类型转换),再调用内置方法。
基本包装类型包括:Number、Boolean、String,它们都属于引用数据类型,可以绑定属性和方法。
var strObj = new String('');strObj.name = '一个字符串';console.log(strObj.name);//一个字符串String():将基本数据类型字符串,转换为 String 对象。Number():将基本数据类型的数字,转换为 Number 对象。Boolean():将基本数据类型的布尔值,转换为 Boolean 对象。
注意,在实际应用中一般不会使用基本数据类型的对象
在底层,字符串以字符数组的形式保存
var str = 'chuckle';//保存方式["c", "h", "u", "c", "k", "l", "e"]console.log(str.length);//7console.log(str[2]); //因为是数组,可以直接访问下标,字符串中的第3个字符,u内置对象
内置对象是语言自带的一些对象,提供了最基本最常用的属性和方法。
Arguments(函数参数集合),Array(数组),Boolean(布尔对象),Math(数学对象),Date(日期时间),Error(异常对象),Function(函数构造器),Number(数值对象),Object(基础对象),RegExp(正则表达式对象),String(字符串对象)
字符串对象String
字符串的所有方法,都不会改变原字符串
indexOf()/lastIndexOf():获取字符串中指定内容的索引search():获取字符串中指定内容的索引(参数里一般是正则)includes():字符串中是否包含指定的内容startsWith():字符串是否以指定的内容开头endsWith():字符串是否以指定的内容结尾charAt()和str[index]:返回字符串指定位置(下标)的字符charCodeAt(index):返回字符串指定位置的字符的 Unicode 编码slice():截取指定范围的字符串,可传入负值,代表倒数第几个字符(截取时包括该字符)substring():截取指定范围的字符串**,不可传入负值,传入负值转为0,自动调整参数的位置,如果第二个参数小于第一个,则自动交换substr():从起始位置截取指定长度的字符串**,两个参数,起始位置,截取指定长度String.fromCharCode():据字符的 Unicode 编码获取字符concat():拼接两个字符串,不如直接用+号split():字符串转换为数组 【重要】replace():替换字符串内容repeat():重复该字符串指定次数toUpperCase()和toLowerCase():大小写转换trim():去除字符串头尾的空格
查找字符
1、indexOf()/lastIndexOf():获取字符串中指定内容的索引
indexOf()从前向后查找,lastIndexOf()从后向前,用法一致。
功能:检索一个字符串中是否含有指定内容。如果字符串中含有该内容,则会返回其第一次出现的字符串底层数组下标(0代表在开头);如果没有找到指定的内容,则返回 -1。
var str = 'abc cba';console.log(str.indexOf('c'));//2console.log(str.lastIndexOf('c'));//4
console.log(str.indexOf('a'));//0console.log(str.lastIndexOf('a'));//6var str = 'chuckle';console.log(str.indexOf('uc'));//2,代表uc第一个字符u是字符串中第三个字符添加起始位置参数,指定查找的起始位置
var str = 'chuckle';console.log(str.indexOf('uc',2));//从下标2即字符串第三个字符开始找起,输出2console.log(str.indexOf('uc',3));//从下标3即字符串第四个字符开始找起,输出-1案例:查找字符串"abcabcabc"中,所有 a 出现的位置以及次数
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。
var str = 'CHUCKLE';console.log(str.search('uc')); //-1console.log(str.search(/uc/i)); //2 正则写法,忽略大小写3、includes():字符串中是否包含指定的内容
功能:判断字符串中是否含有指定内容。有返回 true;否则返回 false。可以传入起始位置参数。
var str = "chuckle";console.log(str.includes('uc')); //trueconsole.log(str.includes('ab')); //falseconsole.log(str.includes('ab',5)); //false4、startsWith():字符串是否以指定的内容开头
功能:判断字符串是否以指定的字符串开头。是返回 true;否则返回 false。可以指定起始位置下标,指定的位置则当做字符串开头。
var str = "chuckle";console.log(str.startsWith('uc')); //falseconsole.log(str.startsWith('c')); //trueconsole.log(str.startsWith('uc',2)); //true5、endsWith():字符串是否以指定的内容结尾
功能:判断字符串是否以指定的字符串结尾。是返回 true;否则返回 false。可以指定检索的字符串长度(检索到第几个字符)。
var str = "chuckle"console.log(str.endsWith('uc')); //falseconsole.log(str.endsWith('e')); //trueconsole.log(str.endsWith('uc',4)); //true获取指定位置的字符
1、charAt()和str[index]:返回字符串指定位置(下标)的字符
var str = "chuckle";console.log(str.charAt(2));//uconsole.log(str[2]);//u2、charCodeAt(index):返回字符串指定位置的字符的 Unicode 编码
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():截取指定范围的字符串,可传入负值,代表倒数第几个字符(截取时包括该字符)
新字符串 = str.slice(开始索引, 结束索引);var str = "qxchuckle";console.log(str.slice(2));//chuckle,从下标2开始截取到最后console.log(str.slice(2,str.length));//chuckleconsole.log(str.slice(2, -1));//chuckl,从下标2开始截取到倒数第一个字符,包括,-0无效console.log(str.slice(5, 2));//无效范围,返回空字符串2、substring():截取指定范围的字符串,不可传入负值,传入负值转为0,自动调整参数的位置,如果第二个参数小于第一个,则自动交换。
新字符串 = str.substring(开始索引, 结束索引);var str = "qxchuckle";console.log(str.substring(2)); //chuckle,从下标2开始截取到最后console.log(str.substring(2,str.length)); //chuckleconsole.log(str.substring(5, 2)); //chu,自动交换位置,相当于截取下标2到5console.log(str.substring(2, -1)); //qx,-1看作0,然后自动交换位置3、substr():从起始位置截取指定长度的字符串,两个参数,起始位置,截取指定长度
新字符串 = str.substr(开始索引, 截取的长度);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 编码获取字符
var a = String.fromCharCode(97);console.log(a);//aconcat():拼接两个字符串,不如直接用+号,数组中也有此方法,用于两个数组的拼接,那边常用
var str1 = "qx";var str2 = "chuckle";str2 = str1.concat(str2);//qxchucklesplit():字符串转换为数组 【重要】
功能:通过指定的分隔符,将字符串拆分成数组,分隔符不会出现在数组中。不传入参数则将整个字符串作为数组的一个元素存入。
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():替换字符串内容
功能:将字符串中的指定内容,替换为一段字符串,默认只会替换第一个被匹配到的字符。如果要全局替换,需要使用正则。
新的字符串 = str.replace(被替换的子串,新的子串);var str = "生活就像海洋,只有咕噜咕噜";str = str.replace('咕噜咕噜','意志坚强的人才能到达彼岸');console.log(str);//生活就像海洋,只有意志坚强的人才能到达彼岸repeat():重复该字符串指定次数
var str = "chuckle!"str = str.repeat(2);//重复两次console.log(str);//'chuckle!chuckle!'trim():去除字符串头尾的空格
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);//9toUpperCase() 和 toLowerCase():大小写转换
var str = 'abcdEFG';//转换成小写console.log(str.toLowerCase()); //abcdefg//转换成大写console.log(str.toUpperCase()); //ABCDEFGhtml方法:不常用,多数是拼接成模板字符串返回
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)
Number.isInteger():判断是否为整数toFixed(num):保留小数点后num位(四舍五入),返回字符串
Number.isInteger():判断是否为整数
布尔值 = Number.isInteger(数字);var a = 10;console.log(Number.isInteger(a));//truea = -10;console.log(Number.isInteger(a));//truea = 1.00;console.log(Number.isInteger(a));//true,虽然有小数点,但后面都是0,所以会被当做整数a = 3.14;console.log(Number.isInteger(a));//falsetoFixed(num):保留小数点后num位(四舍五入),返回字符串,将字符串转为整数可用Number(),详见数据类型转换--JavaScript基础笔记(1)
字符串 = nb.toFixed(num);var nb = 3.1415926;console.log(nb.toFixed(1));//3.1console.log(nb.toFixed(3));//3.142console.log(nb.toFixed(4));//3.1416数学对象Math
Math不是一个构造函数,无需创建对象即可直接使用其属性和方法,它是一个工具类,里面封装了数学运算相关的属性和方法。
Math.PI:圆周率Math.abs():获取绝对值Math.random():生成0-1之间的随机浮点数,[0,1)Math.floor():向下取整(往小取值)Math.ceil():向上取整(往大取值)Math.round():四舍五入取整(正数四舍五入,负数五舍六入)Math.max(x, y, z):返回多个数中的最大值Math.min(x, y, z):返回多个数中的最小值Math.pow(x,y):乘方:返回 x 的 y 次幂Math.sqrt():开方:对一个数进行开方运算
Math.abs():获取绝对值,可传入字符串,自动做隐式转换。
console.log(Math.abs(10));//10console.log(Math.abs(-10));//10console.log(Math.abs('-10'));//10console.log(Math.abs(-3.14));//3.14console.log(Math.abs('123abc'));//NaNMath.random():生成0-1之间的随机浮点数,[0,1)
//生成 [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实例化后才能使用。
无参时获取系统时间
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小时。
var date = new Date(传入毫秒数(时间戳));//表示基准时间加上这个毫秒数//至少要两个参数,不能缺少年,会自动进位,其余默认都是首时间var date = new Date(年,月,日,时,分,秒,毫秒);//月份是0到11之间的整数值,表示从一月到十二月//传入时间字符串,有格式要求,星期 月 日 年 时:分:秒var date = new Date(时间字符串);//Thu Jan 01 1970 08:00:00 GMT+0800 (中国标准时间)//传入2000毫秒,表示基准时间过2svar 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 (中国标准时间)常用方法
getFullYear():获取年份getMonth():获取月,0到11之间的整数值,表示从一月到十二月getDate():获取日:1-31getDay():获取星期:0-6,0代表星期日getHours():获取小时:0-23getMinutes():获取分钟:0-59getSeconds():获取秒:0-59getMilliseconds():获取毫秒setFullYear():修改日期,参数:年,月,日,时,分,秒,毫秒。返回时间戳toUTCString():将当日的日期(根据 UTC)转换为字符串toJSON():将日期转为json格式getTime():获取时间戳toLocaleString()格式化输出 2023/4/12 09:39:49
var date = new Date(1680076326495);//Wed Mar 29 2023 15:52:06 GMT+0800 (中国标准时间)console.log(date.getFullYear());//2023console.log(date.getMonth());//2console.log(date.getDate());//29console.log(date.getDay());//3console.log(date.getHours());//15console.log(date.getMinutes());//52console.log(date.getSeconds());//6console.log(date.getMilliseconds());//495toUTCString():将当日的日期(根据 UTC)转换为字符串
var d = new Date();//Wed Mar 29 2023 16:11:02 GMT+0800 (中国标准时间)d.toUTCString()//'Wed, 29 Mar 2023 08:11:02 GMT'setFullYear():修改日期,参数:年,月,日,时,分,秒,毫秒,返回时间戳
var d = new Date(2023,0);var t = d.setFullYear(2020,10);console.log(t);//1604160000000console.log(new Date(t));//Sun Nov 01 2020 00:00:00 GMT+0800 (中国标准时间)toJSON():将日期转为json格式
var d = new Date(2023,0);var t = d.toJSON();console.log(t);//2022-12-31T16:00:00.000Z获取时间戳
getTime():获取时间戳,也就是返回从基准时间至今的毫秒数(时间戳也可以是秒数,但函数返回的是毫秒数)。
var date = new Date(2023,0);console.log(date);//Sun Jan 01 2023 00:00:00 GMT+0800 (中国标准时间)var time = date.getTime();//1672502400000var date = new Date(time);//Sun Jan 01 2023 00:00:00 GMT+0800 (中国标准时间)还有其它方法可以获取时间戳:
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获取当前时间的时间戳可以用这种方法
console.log(Date.now());//1680077268109转为指定格式
使用 toLocaleString() 简单格式化输出
new Date().toLocaleString();// 2023/4/12 09:39:49也可以通过Date的prototype属性在原型上添加自定义的属性和方法,给Date对象添加**format()**方法,该方法封装如下:
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;}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:06time = date.format("yyyy/MM/dd");console.log(time);// 2023/03/29time = date.format("yyyy年MM月dd日 hh时mm分ss秒");console.log(time);// 2023年03月29日 15时52分06秒数组对象Array
下面是一个普通对象和数组对象:
var obj = {name: 'chuckle' , age: 19 };var arr = ["chuckle","19"];普通对象使用字符串作为属性名,而数组使用数字作为索引,数组适合用于存储同类型的一组数据,如列表数据。
数组中的元素可以是任意的数据类型,可以是对象、函数、数组。也可以同时存储不同类型数据。
1、使用字面量创建数组:
var arr = []; // 创建空数组arr = [1, 2, 3]; // 带初始值的数组2、使用构造函数创建数组对象:
var arr = new Array(); // 创建空数组arr = new Array(4); // 创建大小为4的数组,初始值都为空属性arr = new Array(1,2,3); // 带初始值的数组JS中的数组会自动扩容,当我们访问数组大小以外的下标时,会返回undefined,但可以直接给超过数组大小的下标赋值,并自动给扩容的下标赋空属性,注意,空属性也会计入数组的长度 arr.length。
var arr = [1, 2, 3];console.log(arr); // [1, 2, 3]console.log(arr.length); // 3console.log(arr[6]);// undefined
arr[6] = 7;console.log(arr); // [1, 2, 3, 空属性 × 3, 7]console.log(arr[4]); // undefinedconsole.log(arr.length); // 7解构赋值
解构赋值是ES6中新增的一种赋值方式。可以方便地把数组中的元素按顺序赋值给其他多个变量。
var arr = [1, 2, [3,4]];var [a, b, c] = arr;console.log(a);// 1console.log(b);// 2console.log(c);// [3,4]先指定变量的默认值,会被覆盖
var arr = [1, 2, [3,4]];var [a, b = 0, c = 0, d = 0] = arr;console.log(a);// 1console.log(b);// 2console.log(c);// [3,4]console.log(d);// 0,数组中无第四个元素,保持原值ES6中新增的扩展运算符...打包剩余的数据作为一个新数组。打包时扩展运算符只能写在最后。
var [a, ...b] = [1, 2, 3];console.log(a); // 1console.log(b); // [2, 3]数组属性和方法
arr.length:数组的长度,数组中元素的个数
数组的方法:
- 类型相关方法:
Array.isArray():判断是否为数组toString():将数组转换为字符串join():将数组转换为字符串,可以指定分隔符Array.from():将伪数组或可遍历对象转为真数组Array.of(a,b,c):将多个值按顺序转为数组- 字符串的方法:
split():将字符串按指定的分隔符,组装为数组
- 元素的添加和删除:
push():从数组尾部插入任意数量元素,返回新数组的长度,改变原数组pop():删除数组中最后一个元素,返回被删除的元素,改变原数组unshift():从数组头部插入任意数量元素,返回新数组的长度,改变原数组shift():删除数组中第一个元素,返回被删除的元素,改变原数组splice():从数组中删除指定的任意数量元素,返回被删除元素组成的新数组,改变原数组slice():从数组中提取指定的任意数量元素,返回新数组,不改变原数组concat():合并多个数组,返回合并后的新数组,不改变原数组fill():用固定的值填充数组,返回新数组,改变原数组
- 数组排序:
reverse():反转数组,返回反转后的数组,改变原数组sort():排序,元素默认按照Unicode编码,从小到大进行排序,改变原数组
- 查找数组元素:
indexOf():从前往后搜索数组中的元素,并返回它首次所在位置的索引。lastIndexOf():从后往前搜索数组中的元素,并返回它首次所在位置的索引。includes():判断数组是否包含一个指定的值,返回布尔find(function()):返回第一个符合传入测试(函数)条件的数组元素。findIndex(function()):返回第一个符合传入测试(函数)条件的数组元素的索引。every(function()):检测数组所有元素是否都符合指定(函数)条件,返回布尔some(function()):检测数组是否存在符合指定(函数)条件的元素,返回布尔valueOf():返回数组本身,意义不大,数组名就代表该数组了
- 遍历数组:
for循环遍历,大多数语言对于数组通用的遍历方法forEach()传入一个回调函数作为参数,它由我们创建但是不由我们调用,数组中有几个元素,该回调函数就会执行几次,没用返回值for of,ES6新增循环遍历数组方法map(),遍历数组,并对数组中的每一项进行加工。filter():数组中的每一项运行回调函数,回调函数返回结果是true的项(符合条件的项),组成新数组返回,不改变原数组reduce():参数是接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值返回
类型相关方法
Array.isArray():判断是否为数组
var a = [];console.log(Array.isArray(a));//truea = {};console.log(Array.isArray(a));//falsetoString():将数组转换为字符串,每一项用逗号分割。
大多数的数据类型都可以使用.toString()方法,将其转换为字符串。
var a = [1,[2,3],{name:'chuckle',age:19},function(){}];console.log(a.toString());//1,2,3,[object Object],function(){}还可以使用String()将数组转换为字符串
var a = [1,[2,3],{name:'chuckle',age:19},function(){}];console.log(String(a));//1,2,3,[object Object],function(){}join():将数组转换为字符串,可以指定分隔符,默认为逗号分割。
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。
var arr = [];arr[5] = 6;console.log(arr); // [空属性 × 5, 6]console.log(JSON.stringify(arr)); // [null,null,null,null,null,6]字符串的方法:split():将字符串按指定的分隔符,组装为数组,默认为逗号分割,找不到指定分隔符时也会用逗号分割
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得到参数的伪数组,因为伪数组具有长度和索引,所以可以使用循环语句遍历。
var str = "chuckle";str.push('qx');//报错str.push is not a functionvar 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()**仍然代表数组的元素
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():从数组尾部插入任意数量元素,返回新数组的长度,改变原数组
var arr = [1,2,3];console.log(arr.push(4,5,'123'));// 6console.log(JSON.stringify(arr));// [1, 2, 3, 4, 5, '123']pop():删除数组中最后一个元素,返回被删除的元素,改变原数组
var arr = [1,2,3];console.log(arr.pop());// 3console.log(JSON.stringify(arr));// [1,2]unshift():从数组头部插入任意数量元素,返回新数组的长度,改变原数组
var arr = [1,2,3];console.log(arr.unshift('0123',0));// 5console.log(JSON.stringify(arr));// ["0123",0,1,2,3]shift():删除数组中第一个元素,返回被删除的元素,改变原数组
var arr = [1,2,3];console.log(arr.shift());// 1console.log(JSON.stringify(arr));// [2,3]splice():从数组中删除指定的任意数量元素,返回被删除元素组成的新数组,改变原数组
新数组 = 原数组.splice(起始索引);新数组 = 原数组.splice(起始索引, 需要删除的个数);新数组 = 原数组.splice(起始索引, 需要删除的个数, 新的元素1, 新的元素2...);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(),删除指定内容的元素
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():从数组中提取指定的任意数量元素,返回新数组,不改变原数组
新数组 = 原数组.slice(开始位置的索引);新数组 = 原数组.slice(开始位置的索引, 结束位置的索引);//提取的元素中,包含开始位置,不包含结束位置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():**合并多个数组,返回合并后的新数组,不改变原数组
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]**数组合并的另一种方式:**使用扩展运算符...
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():用固定的值填充数组,返回新数组,改变原数组
// 数组中每一个元素都替换为该值新数组 = 数组.fill(固定值);//从起始位置开始填充新数组 = 数组.fill(固定值, 起始索引);//从起始位置到结束位置填充,左闭右开新数组 = 数组.fill(固定值, 起始索引, 结束索引);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():反转数组,返回反转后的数组,改变原数组
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编码(逐个字符比较,非字符串先隐式转换为字符串),从小到大进行排序,返回排序后的新数组,改变原数组
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编码进行排序
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)返回值的效果:
- 返回值小于0,让a排b前面
- 返回值大于0,让a排b后面
- 返回值等于0,a,b的相对位置不变
对于[7, 3, 11, 4, 1, 5]这个数组,比较11和4时,不带比较函数,会按Unicode编码从小到大排序,11会排在4前面,带比较函数后,因为a-b=7大于零,所以会让4排11前面。
//实现整体升序(小到大)arr.sort((a, b) => a - b);//实现整体降序(大到小)arr.sort((a, b) => b - a);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,需要自己去编写,所以可以实现商品的按价格排序:
//这个数组中存放了几个商品对象,试着让它们按价格升序排序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));[ {"name":"Coke","price":3}, {"name":"bread","price":5}, {"name":"toy","price":8}, {"name":"biscuit","price":10}]查找数组元素
indexOf(): 从前往后搜索数组中的元素,并返回它首次所在位置的索引。
lastIndexOf(): 从后往前搜索数组中的元素,并返回它首次所在位置的索引。
找到元素返回其索引,没找到返回**-1**,严格类型约束,类似===。
var arr = ['1', 2, 1, '2'];console.log(arr.indexOf(1));// 2console.log(arr.indexOf('1'));// 0console.log(arr.indexOf('2'));// 3console.log(arr.indexOf(2));// 1console.log(arr.indexOf(3));// -1可以指定第二个参数,指定查找的起始位置,包括该位置
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)));// 0includes():判断数组是否包含一个指定的值,严格类型约束,返回布尔,可以加上第二个参数规定查找的起始位置。
var arr = [1, 2, '3', '4'];console.log(arr.includes(1)); // trueconsole.log(arr.includes('1')); // falseconsole.log(arr.includes(2, 2)); // falseconsole.log(arr.includes('3', 2)); // truefind(function()):返回第一个符合传入测试(函数)条件的数组元素。
findIndex(function()):返回第一个符合传入测试(函数)条件的数组元素的索引。
找到符合条件的第一个元素就停止查找,没找到返回find()返回undefined,findIndex()返回-1
var arr = [10, 20, 30, 40, 50, 60];//用findvar result = arr.find((item, index, array) => { // item是元素内容,index是该元素索引,array是该数组 return item > 30;});console.log(result);// 40//用findIndexvar result = arr.findIndex((item, index, array) => { // item是元素内容,index是该元素索引,array是该数组 return item > 30;});console.log(result);// 3every(function()):检测数组所有元素是否都符合指定(函数)条件,返回布尔,有一项返回 false 立刻停止遍历。
some(function()):检测数组是否存在符合指定(函数)条件的元素,返回布尔,有一项返回 true 立刻停止遍历。
**every():**全部真,才为真,**some():**一个真,就为真,
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);// truevar 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循环遍历,大多数语言对于数组通用的遍历方法
var arr = [1, 2, 3, 4, 5];for (let i = 0; i < arr.length; i++) { console.log(arr[i]);}//1 2 3 4 5console.log(JSON.stringify(arr));//[1,2,3,4,5]这不够优雅,JS有更简单便捷遍历数组的方法
forEach()传入一个回调函数作为参数,它由我们创建但是不由我们调用,数组中有几个元素,该回调函数就会执行几次,没用返回值
arr.forEach(function (item, index, array) { //做些事情});回调函数中传递三个参数:
- **参数1(item):**当前正在遍历的元素
- **参数2(index):**当前正在遍历的元素的索引
- **参数3(array):**正在遍历的数组
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)直接修改数组中的元素,但元素是一个对象时,可以访问并修改该对象的属性,这是因为数组中存放的是该对象的引用(地址)
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]来访问数组元素并修改
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新增循环遍历数组方法
var arr = [1, 2, 3, 4, 5];for(let item of arr) { //item是元素的拷贝,无法直接修改item来修改元素值 console.log(item);}// 1 2 3 4 5**for in**用于遍历无序的对象的属性,而不是有序的数组
var obj = { name: 'chuckle', age: '19'};for(let key in obj) { //key是属性名,obj[key]可以修改属性值 console.log(`属性名:${key},值:${obj[key]}`);}//属性名:name,值:chuckle//属性名:age,值:19map(),遍历数组,并对数组中的每一项进行加工。
对数组中每一项运行回调函数,返回每一项加工后的结果,组成的新数组,不改变原数组。
var newArr = arr.map((item, index, array) => { // item是元素内容,index是该元素索引,array是该数组 return newItem;//返回该项加工后的结果});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 数组中。
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的项(符合条件的项),组成新数组返回,不改变原数组
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]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() 对于空数组不会执行回调函数
var result = arr.reduce((prev, item, index, array) => {}, initialValue);回调函数参数解释:
- prev:必填,上一次调用回调函数时的返回值
- item:必填,当前正在处理的数组元素
- index:可选,当前正在处理的数组元素下标
- array:可选,该数组
- initialValue:可选,作为第一次调用回调函数时传给prev的值,最好手动初始化为0
举例 1、数组求和:
var arr = [1, 2, 3, 4, 5, 6];var result = arr.reduce((prev, item) => { return prev + item;// 累计求和});console.log(`总和:${result}`); // 总和:21举例 2、统计某个元素出现的次数:
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)); // 2console.log(arrCount(arr, 7)); // 0举例 3、找到最大的元素:
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));// 3console.log(arr[maxValue(arr)]);// 7
评论