目录
数组
认识数组
数组:用一个变量存储一堆数据结构。
数据类型:
基本数据类型
特殊数据类型
复合/引用数据类型
声明数组
1、通过new创建数组
参数:传入任意的数据,存储到数组中。
2、省略new运算符创建数组
【注】上述两种方法,传入参数只有一个,并且是数字的时候,直接声明这么长的数组
3、数组常量进行赋值。(JS一般使用中括号[ ])
<script>
/* 通过new创建数组 */
var arr = new Array(100,true,"hello");
alert(arr);
/* 省略new运算符创建数组 */
var arr2 = Array(100,true,"hello");
alert(arr2);
/* 上述两种方法,传入参数只有一个,并且是数字的时候,直接声明这么长的数组 */
var arr4 = new Array(10);
alert(arr4);
var arr5 = Array(10);
alert(arr5);
/* 数组常量进行赋值。(JS一般使用中括号[ ]) */
var arr3 = [100,true,"hello"];
alert(arr3);
</script>
数组的属性
数组.length 返回值数组【元素】的个数。
元素:将数组存储的每一个数据,叫做数组的元素
访问数组的元素
数组[下标];下标是从0开始的。
【注】数组和循环是天生一对
<script>
/* 数组常量进行赋值。(JS一般使用中括号[ ]) */
var arr3 = [100,true,"hello"];
alert(arr3);
var arr = [100,true,"hello"];
/* alert(arr.length);
alert(arr[1]); */
for(var i = 0;i < arr.length; i++){
document.write(arr[i] + "<br/>");
}
</script>
数组遍历
Math.randon( ); 随机数 [0,1)
parseInt(Math.randon( ) * 10 ); 随机数 [0,10)
<script>
// 1、长度是10的数组
var arr = new Array(10);
for(var i = 0; i < arr.length; i++){
arr[i] = parseInt(Math.random() * 10);
}
alert(arr);
/* 数组的遍历
for 循环
for...in 遍历 快速遍历/快速枚举,不需要判断任何东西
*/
var arr = [10,20,30,40,50];
//在页面上分别将每一个数输出
for(var i = 0; i < arr.length; i++){
document.write(arr[i] + "<br/>");
}
for(var i in arr){
document.write(arr[i] + "<br/>");
}
</script>
数组方法
栈结构:
结构:从同一头进,从同一头进出
特点:先进后出
数组的两个方法形成栈结构
- push
- 格式:数组.push(参数1,参数2...);
- 功能:给数组的末尾添加元素
- 返回值:插完元素以后数组的长度
- pop
- 格式:数组.pop( )
- 参数:没有参数
- 返回值:取下一个元素
- 功能:从数组末尾取下一个元素
<script>
var arr = ["北京","上海","广州"];
var res = arr.push("深圳","天津","成都");
alert(arr);
alert(res);/* 插完元素以后数组的长度:6 */
var arr2 = ["北京","上海","广州"];
var res2 = arr2.pop();
alert(res2);
alert(arr2);
</script>
队列结构:
结构:从末尾进,从头部出
特点:先进先出
- push
- shift( )
- 格式:数组.shift( )
- 参数:没有参数
- 功能:从数组的头部取下一个元素
- 返回值:取下的元素
- unshift( )
- 格式:数组.unshift(参数1,参数2...)
- 功能:从数组的头部插入元素
- 返回值:插完元素以后数组的长度
- shift( )
<script>
var arr = ["唐朝","元朝","清朝"];
var res = arr.shift();
alert(res);
alert(arr); /* 首部元素不存在了 */
var arr2 = ["唐朝","元朝","清朝"];
var res2 = arr.unshift("隋朝","商汤");
alert(res2); /* 插完元素以后数组的长度:4 */
alert(arr2);
</script>
数组方法
-
contact( )
- 1、拷贝原数组,生成新数组
- 2、合并数组
- 格式:数组.contact( 数组,数据,...)
- 返回值:合并成的新数组
<script>
var arr1 = [10,20,30];
var arr2 = [50,60,70];
var newArr = arr1.concat(arr2,"hello",true);
alert(newArr);
alert(newArr.length); // 8,将arr2中的元素拆开单独存入arr1中
alert(arr1);
</script>
-
slice( ) 方法
- 格式:数组.slice(start , end); [start , end)
- 功能:可以基于当前数组获取指定区域元素 [start , end),提取出元素生成新数组
- 返回值:生成的新数组,原数组不会发生任何的改变
<script>
var arr1 = [10,20,30,40,50,60];
var newArr = arr1.slice(1,4);
alert(newArr); /* 20,30,40 */
alert(arr1); /* 10,20,30,40,50,60 */
</script>
-
splice( )
- 格式:数组.splice(start , length , 数据1 , 数据2 ...);
- 参数:
- start 开始截取的位置
- length 截取的元素长度
- 第三个参数开始:在start 位置,插入的元素
- 返回值:截取下来的元素组成的数组
<script>
var arr = [10,20,30,40,50,60];
// 增加功能
var res = arr.splice(2,0,"hello","world");
alert(arr); /* 10,20,hello,world,30,40,50,60 */
alert(res); /* 为空 */
// 删除功能
var res = arr.splice(1,2);
alert(arr); /* 10,40,50,60 */
alert(res); /* 20,30 */
//修改功能
arr.splice(2,1,"hello");
alert(arr); /* 10,20,hello,40,50,60 */
</script>
-
join( )
- 格式:数组.join(字符串)
- 功能:将数组中的元素,用传入的拼接符,拼接成一个字符串
- 返回值:拼接好的字符串
var arr = [10,20,30];
var str = arr.join("==");
alert(str);
alert(arr);
-
reverse( ) 逆序
var arr = [true,"hello",100];
arr.reverse();
alert(arr);
-
数组排序 sort
- 格式:数组.sort( ) 默认从小到大排序,按照字符串排序
- 如果要进行数值大小排序
- 传参数:一个函数,代表要怎么去进行排序(固定用法)
<script>
var arr = [30,20,50,10,40,60];
arr.sort();
alert(arr);/* 10,20,30,40,50,60 */
var arr2 = [1,10,20,15,25,5];
arr2.sort();
alert(arr2);/* 1,10,15,20,25,5 */
/* 数值从小到大 */
var arr = [1,10,20,15,25,5];
arr.sort(function(value1,value2){
return value1 - value2;
})
alert(arr);
/* 数值从大到小 */
var arr = [1,10,20,15,25,5];
arr.sort(function(value1,value2){
return value2 - value1;
})
alert(arr);
</script>
数组求平均数
<script>
/*
定义一个含有30个整型元素的数组,按顺序分别赋予从2开始的偶数;然后按顺序每五个数求出一个平均值,放在另一个数组中并输出。
*/
//1、声明数组
var arr = new Array(30);
for(var i = 0; i < arr.length; i++){
arr[i] = i * 2 + 2;
}
// alert(arr);
// 2、求平均数
var averageArr = [];
for(var i = 0; i < 6; i++){
// 3、取出求平均数的这组数
var newArr = arr.splice(0,5); /* y也可以用slice,但是slice不会改变数组,所以需要提取不同的下标 arr.slice(i * 5,(i + 1) * 5) */
// 4、求平均值
var sum = 0;
for(var j = 0; j < newArr.length; j++){
sum += newArr[j];
}
averageArr.push(sum / 5);
}
alert(averageArr);
</script>
数组的引用
【引用】数据类型
数组,数组的变量存储的是数组的存储
<script>
var arr1 = [10,20,30,40];
var arr2 = arr1;
arr2.push(50,60);
alert(arr1);/* 10,20,30,40,50,60 */
alert(arr2);/* 10,20,30,40,50,60 */
</script>
concat( )
拷贝原数组,生成一个新数组
<script>
var arr1 = [10,20,30,40];
var arr2 = arr1.concat();
arr2.push(50,60);
alert(arr1);/* 10,20,30,40 */
alert(arr2);/* 10,20,30,40,50,60 */
</script>
声明提升
概念:在当前作用域,声明变量和函数,会直接提升在整个代码的最前面运行
<script>
/*
内存分配,一次分配
准备做菜,先要将菜谱从头到尾看一遍,所有准备材料准备好,才开始工作
预编译:在所有代码运行之前,计算机将代码从头到尾看一遍。
将这个程序需要运行的空间一次性分配好
相当于:
var num;
alert(num);
var num = 10;
alert(num);
函数也会声明提升。
*/
alert(num); //undefined
var num = 10;
alert(num); //10
show(); //hello world 声明提升了
function show(){
document.write("hello world");
}
/* 局部作用域 */
function show(){
var num; //声明提升
alert(num); //undefined
var num = 10;
alert(num); //10
}
show();
alert(num); //报错,离开了局部作用域的范围
</script>
省略var
<script>
/*
省略var,直接去强制给一个变量赋值,这个变量会被JS强制声明成全局变量
【注】不建议,这属于语法错误
*/
function show(){
var num = 10;
alert(num);
}
show();
alert(num);//报错
function show2(){
num2 = 10;
alert(num2);
}
show2();
alert(num2); //10
</script>
二维数组
数组存储数据,数组中每一个元素,元素可以是任意的数据类型。
【注】数组中的元素可以是数组
二维数组:认为起的,不为官方命名。
<script>
var arr1 = [10,20,30];
var arr = [true,100,"hello",arr1];
alert(arr.length); //4
alert(arr[3]); //[10,20,30]
alert(arr[3] == arr1); //true
alert(arr[3][1]); //20
</script>
<script>
/* 通过循环按行顺序为一个5x5的二维数组a赋1到25的自然数,然后输出该数组的左下半三角。 */
var arr = [
[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]
];
// for(var i = 0; i < arr.length; i++){
// for(j = 0; j <= i; j++){
// document.write(arr[i][j] + " ");
// }
// document.write("<br/>");
// }
// for(var i = 0; i <arr.length; i++){
// // document.write(arr[i]);
// var newArr = arr[i];
// for(var j = 0; j < newArr.length; j++){
// if(i >= j){
// document.write(newArr[j] + " ");
// }
// }
// document.write("<br/>");
// }
for(var i = 0; i <arr.length; i++){
// document.write(arr[i]);
for(var j = 0; j < arr[i].length; j++){
if(i >= j){
document.write(arr[i][j] + " ");
}
}
document.write("<br/>");
}
</script>
冒泡排序
- 规则:前后两个数两两进行比较,如果符合交换条件就交换两个数的位置
- 规律:冒泡排序每一轮排序,都可以找出一个较大的数,放在正确的位置
<script>
/* 冒泡排序:前后两个数两两进行比较,如果符合交换条件就交换两个数的位置
分析:
比较轮数 = 数组长度- 1;
每一轮比较的次数 = 数组长度 - 当前的轮数。
*/
var arr = [9, 8, 7, 6, 5, 4];
for(var i = 0; i < arr.length - 1; i++){
/* 注意:j < arr.length - (i + 1) */
for(var j = 0; j < arr.length - (i + 1); j++){
if(arr[j] > arr[j + 1]){
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for(var i = 0; i < arr.length; i++){
document.write(arr[i] + " ");
}
</script>
选择排序
- 规则:选出一个位置,这个位置上的数,和后面所有的数进行比较,如果比较出大小就交换两个数位置。
- 规律:每一轮都能选出一个最小的数,放在正确的位置
<script>
/*
9, 8, 7, 6, 5, 4
第一轮:
9, 8, 7, 6, 5, 4
8, 9, 7, 6, 5, 4
7, 9, 8, 6, 5, 4
6, 9, 8, 7, 5, 4
5, 9, 8, 7, 6, 4
4, 9, 8, 7, 6, 5
第二轮:
9, 8, 7, 6, 5
8, 9, 7, 6, 5
7, 9, 8, 6, 5
6, 9, 8, 7, 5
5, 9, 8, 7, 6
. . . . . .
比较的轮数 = 数组长度 - 1;
每一轮比较的次数 = 数组长度 - 当前的轮数
*/
var arr = [9, 8, 7, 6, 5, 4];
//用的擂台的下标
for(var i = 0; i < arr.length - 1; i++){
//被比较的数的下标
for(var j = i + 1; j < arr.length; j++){
if(arr[i] > arr[j]){
var tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
alert(arr);
</script>
可以将冒泡排序和选择排序封装成函数,写在新的 tool.js 文件内,后续使用更加便捷
/* 冒泡排序升序 */ function bubbleSortAsc(arr){ for(var i = 0; i < arr.length - 1; i++){ for(var j = 0; j < arr.length - (i + 1); j++){ if(arr[j] > arr[j + 1]){ var temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } for(var i = 0; i < arr.length; i++){ document.write(arr[i] + " "); } } /* 冒泡排序降序 */ function bubbleSortDesc(arr){ for(var i = 0; i < arr.length - 1; i++){ for(var j = 0; j < arr.length - (i + 1); j++){ if(arr[j] < arr[j + 1]){ var temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } for(var i = 0; i < arr.length; i++){ document.write(arr[i] + " "); } } /* 选择排序升序 */ function changeSortAsc(arr){ for(var i = 0; i < arr.length - 1; i++){ //被比较的数的下标 for(var j = i + 1; j < arr.length; j++){ if(arr[i] > arr[j]){ var tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } } } } /* 选择排序降序 */ function changeSortDesc(arr){ for(var i = 0; i < arr.length - 1; i++){ //被比较的数的下标 for(var j = i + 1; j < arr.length; j++){ if(arr[i] < arr[j]){ var tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } } } }
数组的练习
- 随机给出一个五位以内的数,然后输出该数共有多少位,每位分别是什么
/* 方法一: */
var x = parseInt(Math.random() * 100000);
document.write("x=" + x + "<br>");
var y = x, count = 1;
while(true){
if(parseInt(y / 10) == 0){
break;
}else{
y = parseInt(y / 10);
count++;
}
}
document.write("count=" + count + "<br>");
for(var i = 0; i < count; i++){
var a = Math.pow(10,(count - i));
var b = Math.pow(10,(count - i - 1));
var c = x % a;
var n = parseInt(c / b);
document.write("第" + (i + 1) + "位数为" + n + "<br>")
}
/* 方法二: */
function countOfNum(num){
var arr = [];
while(num){
arr.push(num % 10);
num = parseInt(num / 10);
}
arr.reverse();
alert("一共是:" + arr.length + "位" + ", 每一位分别是" + arr);
}
countOfNum(12345);
- 编写函数 has(arr, 60) 判断数组中是否存在60这个元素,返回布尔类型
function has(arr, item){
for(var i = 0; i < arr.length; i++){
if(arr[i] === item){
return true;
}
}
return false;
}
alert(has([10,20,30],20));
- 生成13位条形码(对之前的知识综合练习)
Ean-13码规则:第十三位数字是前十二位数字经过计算得到的校验码
例如:690123456789
第三位计算其校验码过程为:
@前十二位的奇数位和6+0+2+4+6+8=26
@前十二位的偶数位和9+1+3+5+7+9=34
@将奇数和与偶数和的三倍相加26+34*3=128
@取结果的个位数:128的个位数位8
@用10减去这个个位数10-8=2
所以校验码位2(注:如果取结果的个位数为0,那么校验码不是(10-0=10),而是0)实现方法ean13() 计算验证码,输入12位条码,返回13位校验码
例如:输入:692223361219
输出:6922233612192
alert(ean(692223361219));
function ean(num){
var arr = [];
while(num){
arr.unshift(num % 10);
num = parseInt(num / 10);
}
var odd = 0;
var even = 0;
for(var i = 0; i < arr.length; i++){
if(arr[i] % 2 == 0){
odd += arr[i]; //下标为偶数,但在本身这个数中为奇数
}else{
even += arr[i]; //下标为奇数,但在本身这个数中为奇数
}
}
var sum = (odd + even * 3) % 10;
if(sum){
sum = 10 -sum;
}
arr.push(sum);
return Number(arr.join(""));
}
ECMA5严格模式
严格模式:写在哪个作用域下,就在哪个作用域下生效。
"use strict"
【注】尽量注意不要严格模式写在全局。
用了严格模式,会有什么变量:
1、全局变量声明时,必须加var
/* function show(){
num = 10; //全局变量
}
show();
alert(num); //10,在控制台中查看会报错 */
function show(){
"use strict";
var num = 10; //强制声明称全局变量
alert(num);
}
show();
alert(num); //控制台报错,无法输出
2、this无法指向全局对象(后续介绍)
3、函数内重名属性
/* function show(num1, num1, num2){
alert(num1 + "," + num2); //20,30 因为后一个num1会覆盖前一个num1
}
show(10,20,30); */
function show(num1, num1, num2){
"use strict";
alert(num1 + "," + num2); //Uncaught SyntaxError: Duplicate parameter name not allowed in this context
}
show(10,20,30); //无输出内容
4、arguments对象
4.1 arguments对象不允许被动态改变
/* function show(num1, num2){
alert(num1 + "," + num2); //10,20
alert(arguments[0] + "," + arguments[1]); //10,20
}
show(10,20); */
function show(num1, num2){
num1 = "hello";
alert(num1 + "," + num2); //hello,20
alert(arguments[0] + "," + arguments[1]); //hello,20
}
show(10,20);
function show(num1, num2){
"use strict";
num1 = "hello";
alert(num1 + "," + num2); //hello,20
alert(arguments[0] + "," + arguments[1]); //10,20; arguments对象不允许被动态改变
}
show(10,20);
5、新增保留字:
implements, interface, let, package, private, protected, public, static, yield
/* var interface = 10;
alert(interface); //10 */
"use strict";
var interface = 10;
alert(interface); //interface是关键字,不可以声明成变量
严格模式的目的:
- 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
- 消除代码运行的一些不安全之处,保证代码运行的安全;
- 提高编译器效率,增加运行速度;
- 为未来新版本的JavaScript做好铺垫
【注】严格模式体现了JavaScript更合理、更安全、更严谨的发展方向,包括IE 10在内的主流浏览器,都已经支持它。
另一方面,同样的代码,在严格模式中,可能会有不一样的运行结果;一些在正常模式下可以运行的语句,在严格模式下将不能运行。
ECMA5新增数组方法
indexOf():
格式: 数组.index(item,start);
参数:item 任意的数据
start 下标 可以不传入,默认是0
功能:在数组中查找第一次出现item元素下标,从start开始去查找
返回值:-1 没有查找到
>= 0 查找到的元素的下标
var arr = [10, 20, 30, 40, 50, 20, 30];
// var index = arr.indexOf(20); //返回找到的第一个数的下标,1
// var index = arr.indexOf(20,2); //从下标2开始找可以找到后面20的下标,5
var index = arr.indexOf(120); //-1
alert(index);
数组遍历:
for循环
for...in
forEach( ECMA5新增)
forEach 屏蔽了初学者对于循环的理解
item:当前遍历到的元素
index:当前遍历到元素的下标
arr数组本身
var arr = [10, 20, 30, 40, 50];
arr.forEach(function(item, index, arr){
/*
item:当前遍历到的元素
index:当前遍历到元素的下标
arr数组本身
*/
document.write(item + "," + index + "," +arr + "<br/>");
});
map()
映射,可以根据固定的一个计算公式把原来的数计算出结果,把它放在一个数组里
var arr = [10, 20, 30, 40, 50];
var newArr = arr.map(function(item, index, arr){
//遍历要做的事情 映射关系
return item * 1.3;
});
alert(newArr); //13,26,39,52,65
alert(arr); //10,20,30,40,50
filter( ) 过滤
把我们想要的符合条件的元素单独拿出来存储在新数组中
var arr = [10, 20, 30, 40, 50];
var newArr = arr.filter(function(item, index, arr){
//过滤的条件
return item > 20;
});
alert(newArr); //30,40,50
alert(arr); //10,20,30,40,50
some 某些
【注】在数组中查找是否有符合条件的数,有返回true;没有返回false
短路操作:主要找到符合条件的元素,后面的循环就停止了
var arr = [10, 20, 30, 40, 50];
var res = arr.some(function(item, index, arr){
//过滤的条件
return item > 20;
});
alert(res); //true
alert(arr); //10,20,30,40,50
every 每一个
【注】在数组中查找每一个元素是否符合条件,符合返回true,不符合返回false
短路操作:只要找到不符合条件的元素,后面的循环就停止了
var arr = [10, 20, 30, 40, 50];
var res = arr.every(function(item, index, arr){
//过滤的条件
return item < 30; //如果条件为 item < 100;那么将会把所有的数遍历一遍
});
alert(res); //false
alert(arr); //10,20,30,40,50
reduce 归并
prev:第一次是 下标位0的元素
第二次开始 上一次遍历return的值
next:从下标1开始,当前遍历到的元素
arr:数组本身
/*
prev = 10; next = 20; prev + next = 30
prev = 30; next = 30; prev + next = 60
prev = 60; next = 40; prev + next = 100
prev = 100; next = 50; prev + next = 150
res = 150
*/
var arr = [10, 20, 30, 40, 50];
var res = arr.reduce(function(prev, next, index, arr){
alert(prev + "," + next);
return prev + next;
});
alert(res);