系统学习一下JavaScript,每天进步一点点
文章目录
一、数组能够存放什么?
可以在相同数组中存放不同类型的变量(对象、函数、数组)
二、相关语法
1.检测数据类型
语句 | 返回 | 理解 |
---|---|---|
typeof arr | 'Object' | 检测基本的数据类型 |
arr instanceof Array | true | 运算符,检测实例arr构造器是否为Array |
Object.constructor.name | 'Array' | arr的原型链下(构造函数的原型下)的属性 |
Array.isArray(arr) | true | 判断是否为数组(H5新增方法,ie9以上版本支持) |
Object.prototype.toString.call(arr) | '[object Array]' | 返回当前方法中的this的所属类信息 (PS.call改变this指向,使arr能够使用Object的方法,详情点这) |
检测数据类型详情点这
2.属性
语句 | 理解 |
---|---|
arr.length | 数组长度 |
arr.constructor | 返回创建数组对象的原型函数 |
Array.prototype.方法名 = function(){} arr.方法名() | 向数组对象添加属性或方法 |
3.创建
对比下数组和对象的创建方式
数组 | 对象 |
---|---|
var arr = ["a", "b", "c"] | var person = {firstName:"Bill", lastName:"Gates", age:19} |
var arr1 = new Array(); //创建空数组 var arr2 = new Array(2); //创建长度为2的数组 var arr3 = new Array("a", "b", "c") |
4.访问
对比下数组和对象的访问方式
数组 | 对象 |
---|---|
arr[i] | person.firstName |
5.增/删/改
①增加
语句 | 解释 | 是否改变原数组 | 返回 |
---|---|---|---|
//原本arr.length = 3 arr.length = 4 | 数组扩容, 增加了一个undefined元素 | 是 | - |
//原本arr.length = 3 arr[arr.length] = 'add' | 追加数组元素, 增加了一个'add'元素 | 是 | - |
arr.push(item,...) | 向数组的末尾添加一个或更多元素 | 是 | 新的长度 |
arr.unshift(item,...) | 向数组的开头添加一个或更多元素 | 是 | 新的长度 |
②删除
语句 | 解释 | 是否改变原数组 | 返回 |
---|---|---|---|
arr.pop() | 删除数组的最后一个元素 | 是 | 删除的元素 |
arr.shift() | 删除数组的第一个元素 | 是 | 删除的元素 |
③增删结合
语句 | 解释 | 是否改变原数组 | 返回 |
---|---|---|---|
arr.splice(2) | 删除从 数组下标2 开始到原数组结尾的所有元素 | 是 | ①未删除任何元素,返回空数组; ②删除n个元素,返回被删元素的数组 |
arr.splice(2,0) | 删除从 数组下标2 开始到原数组结尾的0个元素 | ||
arr.splice(2,1,item,...) | 删除从 数组下标2 开始到原数组结尾的1个元素; 在 数组下标2 后添加一个或更多元素 |
④填充
语句 | 解释 | 是否改变原数组 | 返回 |
---|---|---|---|
arr.fill(item) | 将一个 固定值item 替换数组的元素 | 是 | 填充后的数组 |
arr.fill(item,2) | 将一个 固定值item 在 [2, arr.length) 替换数组的元素 | ||
arr.fill(item,2,4) | 将一个 固定值item 在 [2, 4) 替换数组的元素 |
⑤拷贝(浅拷贝)
语句 | 解释 | 是否改变原数组 | 返回 |
---|---|---|---|
arr.copyWithin(2,0) | 将 [0,arr.length) 部分元素拷贝到 下标元素2及之后(超出部分不管) | 是 | 拷贝后的数组 |
arr.copyWithin(2,0,2) | 将 [0,2) 部分元素拷贝到 下标元素2及之后 |
⑥截取(浅拷贝)
语句 | 解释 | 是否改变原数组 | 返回 |
---|---|---|---|
arr.slice(1) | 截取数组 [1,arr.length) 部分 | 否 | 被提取的部分的新数组 |
arr.slice(-3) | 截取数组 最后三个元素 | ||
arr.slice(1,3) | 截取数组 [1,3) 部分 | ||
arr.slice(-3,-1) | 截取数组 [倒数第三个 ,倒数第一个) 的两个元素 |
⑦连接(浅拷贝)
语句 | 解释 | 是否改变原数组 | 返回 |
---|---|---|---|
arr1.concat(item,arr2,...) | 连接两个或多个具体元素 或 数组中的元素 | 否 | 连接后的新数组 |
浅拷贝规则:
①原数组的某元素是 对象引用(let obj = {'Orange'}; let arr = ['Apple', obj, 'Banana'];)
拷贝 此对象引用 到新数组,被引用对象发生改变,新数组和原数组的这个元素均发生改变
②原数组的某元素是 字符串、数字及布尔值(不是String、Number、Boolean对象)
拷贝 此值 到新数组,修改值互不影响
③两数组任一添加新元素,另一个不会受影响
6.查
语句 | 解释 | 返回 | |
---|---|---|---|
打印 | arr.valueOf() | 无 | 数组对象的原始值(所有值) |
首次出现 | arr.indexOf(item) | 从 头 到 尾 搜索item | ①没找到指定元素返回 -1 ②找到则返回 item 的第一次出现的索引值 |
arr.indexOf(item,1) | 从 数组下标1 到 尾 搜索item | ||
最后出现 | arr.lastIndexOf(item) | 从 尾 到 头 搜索item | ①没找到指定元素返回 -1 ②找到则返回 item 的最后一次出现的索引值 |
arr.lastIndexOf(item, 1) | 从 数组下标1 到 头 搜索item | ||
是否出现 | arr.includes(item) | 从头到尾搜索item | ①没搜索没找到返回 false ②找到指定值返回 true |
arr.length = 3 arr.includes(item,1) | 从 数组下标1 到 尾 搜索 | ||
arr.length = 3 arr.includes(item,3) arr.includes(item,100) | 3、100大于等于数组长度,数组不被搜索 | ||
arr.length = 3 arr.includes(item,-2) | 3 + (-2) = 1 > 0 从 数组下标1 到 尾 搜索 | ||
arr.length = 3 arr.includes(item,-100) | 3 + (-100) = -97 < 0 从头到尾搜索item | ||
符合规则的第一个元素值 | 写法一: checkFn = function(age){ return age >= 18;} arr.find(checkFn) 写法二: arr.find(age => age >= 18); | 从头到尾, 找到第一个符合函数的元素就停止 | ①没有符合条件(包括空数组)返回undefined ②有符合条件返回符合的第一个元素的值 |
符合规则的第一个元素索引 | arr.findIndex(age => age >= 18); | ①没有符合条件(包括空数组)返回-1 ②有符合条件返回符合的第一个元素的位置 |
7.遍历
①迭代器
语句 | 解释 | 返回 |
---|---|---|
①arr.keys() ②arr.keys().next() ③arr.keys().next().value | 从数组创建一个包含数组键的可迭代对象 | ①[object Array Iterator] ②[object Object] ③数组下标如1 |
①arr.entries() ②arr.entries().next() ③arr.entries().next().value | 从数组创建 一个包含数组键值对的可迭代对象 | ①[object Array Iterator] ②[object Object] ③数组下标,数组元素如1,Orange |
②对元素进行操作
语句 | 解释 | 是否改变原数组 | 返回 | |
---|---|---|---|---|
forEach 遍历 数组 | arr.forEach(function(item, index, arr){}, thisValue) | item:数组当前项的值 index:数组当前项的索引 arr:数组对象本身 (PS.空数组不执行回调函数) | 是 | undefined |
例:arr.forEach(alert) | ||||
var arr = [1, 2, 3, 4, 5]; arr.forEach(function (item) { | 不支持continue和break语句 可用return实现continue | |||
map 遍历 数组 | var numbers = [4, 9, 16, 25]; numbers.map(Math.sqrt); | 按照原始数组元素顺序依次处理元素 (PS.空数组不执行) | 否 | 一个新数组,数组中的元素为处理后的值 |
filter 筛选 数组 | arr.filter(function(item, index, arr){}, thisValue) | item:数组当前项的值 index:数组当前项的索引 arr:数组对象本身 | 否 | ①没有符合条件的元素,返回空数组; ②有,返回包含符合条件的所有元素的数组 |
var newArr = arr.filter(item => { // return item >= 18; return item % 2 === 0; | 创建一个新的数组,包含通过检查 指定数组 中符合条件的所有元素 (PS.空数组不执行) | |||
some 检测 是否存在 满足条件的元素 | arr.some(function(item, index, arr){}, thisValue) | item:数组当前项的值 index:数组当前项的索引 arr:数组对象本身 | 否 | ①有一个元素满足条件,返回true , 剩余的元素不会再执行检测。 ②没有满足条件的元素,返回false |
var flag = arr.some(item => { return item > 5 }) | 检测数组中的元素是否存在满足函数指定条件 (PS.空数组不执行) | |||
arr.some(function (item) { // 不能为 return false | 可用return实现continue | |||
every 检测 所有元素 是否 满足条件 | arr..every(function(item, index, arr){}, thisValue) | item:数组当前项的值 index:数组当前项的索引 arr:数组对象本身 | 否 | ①有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。 ②所有元素都满足条件,则返回 true |
arr.every(item => { return item >= 18; }) | 检测数组所有元素是否都符合函数指定条件 (PS.空数组不执行) | |||
可用于实现break | ||||
计算 | arr.reduce(function(total, item, index, arr){},initialValue) | 接收一个函数作为累加器,初始值为initialValue, 数组arr 中的 每个值item(从左到右)开始缩减,最终计算为 一个值total (PS.空数组不执行) (PPS.更多用法点这) | 否 | 计算出的最终值 |
numbers.reduce((total, item) => {return total + item;}) | ||||
arr.reduceRight(function(total, item, index, arr){},initialValue) | 类似reduce,但是从右往左 | 否 | 计算出的最终值 |
i.回调函数:
函数A 作为 实参 被引入 另一函数B,并在B 内部调用 A,A称为B的回调函数
function greeting(name) { alert('Hello' + name); } function processUserInput(callback) { //此处callback是形参 var name = prompt('请输入你的名字'); callback(name); } processUserInput(greeting); //此处greeting是实参
ii. 其余循环遍历(for ... of/in) :
for...of for...in 适用 可迭代对象(Array、Map、Set、String、TypedArray、arguments等)
const str = "Hello World"; for (const element of str) { console.log(element); //H e l l o W o r l d }
除 Symbol 外的对象,且对应属性的enumerable为true(如简单赋值或属性初始化器创建的属性的默认情况)
PS.不推荐用于遍历字符串和数组(会跳过稀疏数组的空白)
const test = { aa : "123456", bb : "233" } for key in test { console.log(key, test[key]); } /* aa 123456 bb 233 */
不适用 const obj = { name : 'xxx', age : 18 } for(const item of obj) { console.log(item); //报错:obj is not iterable }
①Symbol
②对应属性的enumerable为false(如Object.defineProperty创建的属性的默认情况)
Object.defineProperty(test, "cc", { value : "566", enumerable : false } for (key in test) { console.log(key, test[key]); } //结果只显示aa和bb,不显示cc
8.排序
语句 | 解释 | 是否改变原数组 | 返回 |
---|---|---|---|
arr.sort() | 默认排序顺序为按字母升序 (PS.当数字是按字母顺序排列时"40"将排在"5"前面) (PPS.排序方式点此) | 是 | 排序后的数组 |
arr.sort((a, b) => { return a-b; }) | 数字升序排序 | ||
arr.sort((a, b) => { return b-a; }) | 数字降序排序 | ||
arr.reverse(); | 颠倒数组中元素的顺序 | 是 | 颠倒顺序后的数组 |
9.转换
语句 | 是否改变原数组 | |
---|---|---|
其他 =》数组 | let arr = Array.from(set) //通过拥有 length 属性的对象或可迭代的对象来返回一个数组 | - |
数组 =》Set | let set = new Set([1,2,1,2]) //数组去重 | 否 |
数组 =》字符串 | arr.toString() // 用,分割 arr.join() // 用,分割 arr.join('&') // 用&分割 | 是 |
各数组函数的手写实现:
总结
本文主要参考菜鸟教程总结了JavaScript数组的基本属性和方法