文章目录
数据的流程
JavaScript数组的使用小结(详细还是去看MDN)
MDN是一个官方的文档,上面关于编程的知识点都是官方发布的,很严谨,上面也有代码的示范,可以帮助我们学习和查阅相关的知识点。
JavaScript中的数组是一种特殊的对象,由于对象的属性必须是字符串的形式,所以数组的数字索引在内部被转为字符串类型。
创建数组
- 直接用 []创建
数组中的元素可以是不同的数据类型
- 用Array对象创建
Array构造函数有一个很大的缺陷,就是不同的参数,会导致它的行为不一致。
- 通过字符串的split()方法生成数组
- 用已有的数组创建数组
4.1 通过数组拼接
用concat拼接数组是生成了一个新的数组,原数组不发生变化
4.2 通过数组截取
用splice截取数组,原数组会发生变化,可用来删除数组中的元素
- ES6 创建数组的两个API
5.1 Array.of
返回由所有参数值组成的数组,如果没有参数,就返回一个空数组
5.2 Array.from
定义:用于将两类对象转为真正的数组(不改变原对象,返回新的数组)。
参数:
第一个参数(必需):要转化为真正数组的对象。
第二个参数(可选): 类似数组的map方法,对每个元素进行处理,将处理后的值放入返回的数组。
第三个参数(可选): 用来绑定this。
增加数组元素
-
直接通过下标添加
通过数组索引添加,若添加的索引位置原来有值则更新原来的值,若没有值则新建一个数组元素,若新建的元素与之前的数组元素不连续,则中间的数据位置保留并为undefined -
通过push在尾部添加
push可以在数组的末尾添加1个或者多个元素,并返回添加完毕之后数组中元素的个数 -
通过unshift在数组头部插入
unshift可以在数组的头部插入一个或者多个元素,并返回添加完毕之后数组中的元素个数 -
通过splice自由的插入元素
splice有3个元素, 第一个是索引,删除或者添加的位置, 第二个是删除的元素个数,第三个是添加的元素
splice有多个元素, 第一个固定为索引,删除或者添加的位置。第二个是删除的元素个数,是 0 或者负数,则不移除元素。这种情况下,至少应添加一个新元素。第三个之后则是添加进数组的元素
删除数组元素
-
通过 pop 移除末尾的元素
pop移除数组最后一个元素并将其返回 -
通过shift 移除头部的元素
shift移除数组第一个元素并将其返回 -
通过splice 删除任意位置的元素
splice有3个元素, 第一个是索引,删除或者添加的位置, 第二个是删除的元素个数,第三个是添加的元素
在删除数组元素的时候一般只用前两个,指定删除的索引起始位置和删除的个数,并将删除的元素按照子数组返回
查询数组元素
-
通过indexOf查找
indexOf查询是否包含指定的元素,若存在则返回索引,不存在返回-1 -
通过includes查找
查找数组中是否含有某个元素,存在返回true,不存在返回false
数组排序
使用sort函数
对于字符类型的数组,可以直接用**sort()**函数按照Unicode码升序排序,如果需要反序使用reverse()
数组的进阶操作
-
join
使用join()拼接数组生成字符串,并返回这个字符串。其中join可以接受一个符号用来拼接字符串,默认的情况下为直接串联不添加任何拼接字符串。 -
slice
slice(start,end)获取原数组的部分作为子数组返回,原数组不发生改变。截取的时候遵循左闭右开原则。 -
map
map()创建一个新数组并返回,其中新数组的每个元素由调用原始数组中的每一个元素执行提供的函数得到,原数组不发生改变 -
every
对数组中的每个元素都执行一次指定的回调函数,直到回调函数返回false,此时every()返回false并不再继续执行。如果回调函数对每个函数都返回true,every()函数也返回true。
可以将every(func)函数看成判断数组中的元素是否都满足func指定的规则,若全部满足返回true,若有一个不满足则不再判断返回false
操作类似于下面的截断运算
- some
对数组中的每个元素都执行一次指定的回调函数,直到回调函数返回true,此时some()返回true并不再继续执行。如果回调函数对每个元素都返回false,那么some()将返回false。
可以将some(func)函数看成判断数组中的元素是否存在满足func指定的规则的元素,若存在满足的元素返回true,并不再向后判断,若全部不满足则返回false
操作类似于
- filter
创建一个新的数组,包含通过所有提供函数实现的测试的所有元素。过滤数组。原数组不发生改变
过滤数组,返回符合回调函数为true的元素
-
forEach
针对每一个元素执行提供的函数。会修改原来的数组,不会返回执行结果,返回undefined。 -
reduce
Array的reduce()把一个函数作用在这个Array的[x1, x2, x3…]上,这个函数必须接收两个参数,reduce()把结果继续和序列的下一个元素做累积计算,其效果就是:
案例1:求累加和
案例2:求元素出现的次数
对reduce的思考:
reduce(callback,initiaValue)会传入两个变量,回调函数(callback)和初始值(initiaValue)。如果不设置初始值,则第一次执行的时候,callback的第一个参数是数组的第一个元素,第二个参数是数组的第二个元素。有初始值则prev为初始值,next为数组第一个元素。
数组遍历
-
length + for 循环
-
使用forEach
forEach中的回调函数的两个参数中值在前,索引在后 -
for … in
for…in的方式遍历的是数组中的索引,前面也提到过数组是一种特殊的对象,在默认的情况下是以0…n的数字作为索引,但是也可以用其他字符作为索引,所以当数组中存在其他索引的时候可以用for…in获取
前面三种遍历打印的值
- for … of
for … of直接遍历数组中的值
5. for…in 和 for…of的区别
for … in循环,它遍历的实际上是对象的属性名称。
一个Array数组实际上也是一个对象,它的每个元素的索引被视为一个属性。
当我们手动给Array对象添加了额外的属性后,for … in循环将带来意想不到的意外效果:
for … of执行的时候,只遍历值但是没有去遍历新加的k
两个升序数组合为一个升序数组
数组去重
求两个数组的交集
遍历其中一个数组,然后用indexOf来判断是否在另一个数组中出现
求只出现一次的数字
一个非空数组,其中只有一个元素只出现了一次,其余均出现两次,找出那个只出现一次的数字
JavaScript中的坑点
这里有一个问题需要特别注意,如果字符串键值能够被强制类型转换为十进制数字的话,它就会被当作数字索引来处理。
数据的流程的练习代码1:
/*
1. 输入100 个HelloWord!
*/
for(var i=0;i<100;i++)
{
console.log('HelloWord!');
}
/*
2. 输出100~200
*/
for(var i=100;i<=200;i++)
{
console.log(i);
}
/*
3. 创建一个包含1~100的数组
*/
//怎么设置一个数组的长度,包括像C语言一样去一位一位的赋值,用循环语句
var arr=[101];
for(var i=0,j=1;i<=100,j<=100;j++,i++)
{
arr[i]=j;
}
console.log(arr);
var arr=[];
for(var i=1;i<=100;i++)
{
arr.push(i);
}
console.log(arr);
/*
4. 定义一个数组,遍历输出他的每一项
*/
var arr=['123','dhfsj','邓哥','MOncuia'];
for(var i=0;i<5;i++)
{
console.log(arr[i]);
}
// i 的范围:length-1!很方便
数据的流程的练习代码2:
/*
1. 输出1~100的所有奇数
*/
var num=0;
for(var i=0;i<50;i++)
{
num=(2*i)+1;
console.log(num);
}
/*
2. 定义一个数组,输出数组中的所有奇数
*/
var arr=[];
for(var i=0;i<50;i++)
{
arr.push((2*i)+1);
}
console.log(arr);
var arr=[123,232,445,554,565];
for(var i=0;i<=arr.length-1;i++)
{
if(arr[i]%2!==0)
{
console.log(arr[i]);
}
}
/*
3. 定义一个数组,找到所有的奇数,然后放到一个新的数组里面
*/
var nem=[123,234,432,333,111,129];
var newNum=[];
for(var i=0;i<=nem.length-1;i++)
{
if(nem[i]%2!==0)
{
newNum.push(nem[i]);
}
}
console.log(newNum);
数据的流程的练习代码3:
/*
1. 1~100求和
*/
var sum=0;
for(var i=1;i<=100;i++)
{
sum+=i;
}
console.log(sum);
/*
2. 求某个数的阶乘
*/
var num=1;
console.log('10!的阶乘');
for(var i=1;i<=3;i++)
{
num*=i;
}
console.log(num);
/*
3. 数组求和
*/
var most=0;
var arr=[12,13,14,15,1,2,3,4];
for(var i=0;i<=arr.length-1;i++)
{
most+=arr[i];
}
console.log(most);
/*
4. 求数组中的奇数的个数
*/
var jishu=[12,23,34,45,42,23,34,55,221,11];
var counter=0;
for(var i=0;i<=jishu.length-1;i++)
{
if(jishu[i]%2!==0)
{
counter++;
}
}
console.log(counter);
/*
5. 求数组中的奇数和
*/
var jishu=[12,23,34,45,42,23,34,55,221,11];
var counter=0,sum=0;
for(var i=0;i<=jishu.length-1;i++)
{
if(jishu[i]%2!==0)
{
sum+=jishu[i];
}
}
console.log(sum);
流程的切割
函数的作用
使用函数切割流程,不仅可以减少重复代码、还可以有效的降低整体复杂度
函数的常见问题
如何理解函数的参数、返回值、函数体?
参数:表示完成流程所需的必要信息
返回值:表示完成流程后产生的结果
函数体:表示具体的流程
函数的参数、返回值只取决于函数的作用,与函数体无关
为什么我觉得有了函数之后,程序反而变得更复杂了?
函数的本质其实就是封装,也可以称作方法,将解决这个问题的代码进行包装,要解决问题的时候就去使用这个方法就可以。
函数的核心作用,是为了让某一段复杂的流程变得简单。
如果在函数的帮助下,反而觉得流程变得复杂了,极有可能的原因是开发思想没有做相应的切割,导致思想负担过重。
始终记住以下两点:
- 定义函数时,只需要考虑这个函数如何实现即可,完全不需要考虑其他无关的东西。
- 调用函数时,只需要考虑向其传递什么参数,如何使用它的返回结果,完全无需考虑函数的具体实现。
函数具有三要素:函数名、参数、返回值
只要具备三要素,就能书写函数体;只要具备三要素,就能完成函数调用。
学习函数时不知道该如何切割流程怎么办?
要完成一个函数声明,分为两步:
-
设计函数
设计函数就是如何切割流程,具体来说就是设计出函数的三要素,这一步是最难的,目前无须同学们掌握,老师会帮你把函数设计好。
-
书写函数体
根据设计的三要素完成函数体,这一步就是现阶段练习的重点。
数据的切割练习代码1:
// 完成下面的函数
/**
*得到某个数的阶乘
*如果数小于了1,则得到0
* @param{number} n 要求阶乘的数
* @return{number} 阶乘结果
*/
function factorial(n)
{
if(n===1)
{
return 1;
}
else{
return n*factorial(n-1);
}
}
//利用上面的函数,完成下面的练习题
/*
1.输出5的阶乘
*/
var n =factorial(5);
console.log(n)
/*
2.求5和6的阶乘之和,然后输出
*/
// var number1=0;
// var number2=0;
// number1=factorial(5);
// number2=factorial(6);
// console.log(number1+number2)
/*
3. 输出阶乘的结果不超过1000的所有数字
*/
// var arr=[];
// for(var i=1;i<20;i++)
// {
// if(factorial(i)<=1000)
// {
// arr.push(i);
// }
// else{
// break;
// }
// }
// console.log(arr);
数据的切割练习代码2:
// 完成下面的函数
/**
* 在arr中寻找是否存在target
* @param {Array} arr 要遍历寻找数组
* @param {any} target 要寻找的目标
* @return {boolean} 是否找到
*/
function includes(arr,target){
var isFind=false;
for(var key in arr)
{
if(arr[key]===target)
{
isFind=true;
break;
}
}
return isFind;
}
//利用上面的函数,完成下面的练习题
var nums=[1,3,8,2,5,1,9];
// var target=19;
// console.log(includes(nums,target));
/*
1. 判断nums中是否存在8,输出是或者否
*/
var nums2=[6,3,2,7,11,33];
/*
2.判断数字2是否同时存在于nums和nums2中,输出是或否
*/
// var target=2;
// var result1=includes(nums,target);
// var result2=includes(nums2,target);
// if(result1===result2)
// {
// console.log('是');
// }
// else{
// console.log('否');
// }
var nums3=[2,5,1];
/*
3.思考题:判断nums3中是否所有数字都在nums中存在,输出是或否
*/
//自己写的代码有一点冗杂
// var counter=0;
// for(var i=0;i<=nums.length;i++)
// {
// if(includes(nums3,nums[i])==='ture')
// {
// counter++;
// }
// }
// if(counter===nums3.length+1)
// {
// console.log('是');
// }
// else
// {
// console.log('否');
// }
var isFind=false
for(var i=0;i<nums3.length;i++)
{
if(!includes(nums,nums3[i]))
{
isFind=ture;
break;
}
}
if(isFind)
{
console.log('是');
}
else{
console.log('否');
}