数组

数组的概念

把一组相关的数据一起存放, 并提供方便的访问(获取)权限

一组数据的集合, 其中每个数据被称作元素, 再数组中可以i存放任意类型的元素.

数组是一种将一组数据存储在单个变量下的优雅方式.

var arr =[ 1,2,3,4,5];

创建数组

new一个数组

利用new Array() 创建一个空数组

vae arr = new Array();

注意Array(); A要大写

利用数组字面量创建数组

var arr = [ ] 更为常用

var arr = [ 1,2,'pink', true];

数组中的数据可以存放任意数据的类型, 例如字符串型, 数字, 布尔值

注意

数组里面的数据用逗号分割

数组里面的数据称为数组元素

获取数组中的元素

数组的索引(下标) : 用来访问数组元素的序号, 数组下标从0开始

获取/访问的语法:

数组名[索引号]
var arr1 = [1,2,'pink', true];
console.log(arr1[2]); //pink
var week = ['星期一','星期二','星期三','星期四','星期五','星期六','星期天'];
console.log(week[4]); //星期五

注意:

没有这个数组元素 输出后显示undefined

遍历数组

使用for循环 遍历 打印数组

i从0开始

arr.length

var week = ['星期一','星期二','星期三','星期四','星期五','星期六','星期天'];
for (var i= 0; i<week.length; i++) {
console.log(week[i]);
}

案例1:

求数组[2,6,1,7,4]里面所有元素的和以及平均值

var arr = [2, 6, 1, 7, 4];
var sum = 0;
var average = 0;
for (var i = 0; i < arr.length; i++) {
sum += arr[i]; //我们加的是数组元素 arr[i] 不是计数器i
}

average = sum / arr.length;
console.log(sum + '\n', average); //想要输出多个变量 用逗号分隔即可

案例2:

求数组[2,6,1,77,52,25,7]中的最大值

分析:

  1. 声明一个保存最大元素的变量max
  2. 默认最大值为数组的第一个元素
  3. 遍历这个数组, 把里面每个数组元素与max相比较
  4. 如果这个数组元素大于max, 就把这个数组元素存到max里面. 否则进行下一轮比较
  5. 最后输出这个max

实施:

var arr = [2, 6, 1, 77, 100, 25, 7];
var max = arr[0];
for (var i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
console.log('数组里面的最大值是' + max);

​ 举一反三

// 求数组[2,6,1,77,100,25,7]中的最小值\
var arr = [2, 6, 1, 77, 100, 25, 7];
var min = arr[0];
for (var i = 1; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
}
}
console.log('数组里面的最小值是' + min);

案例4:

要求:

要求将数组[‘red’, ‘green’, ‘blue’, ‘pink’]转换为字符串, 并且用| 或者其他符号分割开来

结果:

输出: ‘red|gree|blur|pink|’

分析:

  1. 需要一个str变量 用于存放转换完的字符串str
  2. 遍历数组, 分别把里面的数据取出来, 加到字符串里面

实施:

var arr = ['red', 'green', 'blue', 'pink'];
var str = '';
for (var i = 0; i < arr.length; i++) {
str += arr[i] + '\!';
}
console.log(str); // red!green!blue!pink!

为数组追加元素

通过.length修改数组的长度

var arr = ['red', 'green', 'blue'];
console.log(arr.length);
arr.length = 5;
console.log(arr.length);
console.log(arr);// ['red', 'green', 'blue', 空 ã2]

通过索引号(强行)添加元素

! ! ! 开辟一个新的索引号, 则数组长度就到达这个索引号

var arr1 = ['red', 'green', 'blue'];
// arr1[3] = 'pink';
// console.log(arr1[3]);
arr1[4] = 'hotpink'
console.log(arr1[4]); // hotpink
console.log(arr1); // ['red', 'green', 'blue', 空, 'hotpink']
arr1[0] = 'blue' //替换
console.log(arr1); //['blue', 'green', 'blue', 空, 'hotpink']

注意:

可以通过需改数组索引的方式追加数组元素

不能直接给数组名赋值, 否则会覆盖掉以前的数据


案例1 :

新建一个数组, 里面存放100个整数(1-100)

分析:

  1. 使用循环来追加数组.
  2. 声明一个空数组arr
  3. 循环中的计数器i可以作为数组元素存入
  4. 由于数组的索引是从0开始的, 因此计数器从0开始更何时, 存入的数组元素要+1

实施:

var arr =[];
for (var i= 0; i<100; i++){
arr[i] = i+1; //不要直接给数组名赋值, 否则以前的元素都没了
}
console.log(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, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]

案例2:

要求:

把数组[2,0,6,1,77,0,52,0,25,7] 中大于等于10的元素选出来, 放入新的数组中

分析:

  1. 一个新数组newArr
  2. 遍历旧数组, 找出大于等于10的元素
  3. 一次追加给新的数组newArr

实施:

var arr = [2,0,6,1,77,0,52,0,25,7];
var newArr = [];
var j=0;
for (var i=0; i< arr.length; i++) {
if (arr[i]>=10) {
newArr[j]= arr[i] //新数组的索引号从0开始 依次加1
j++;
}
}
console.log(newArr); //[77, 52, 25]

​ 改良

var arr = [2,0,6,1,77,0,52,0,25,7];
var newArr = [];

for (var i=0; i< arr.length; i++) {
if (arr[i]>=10) {
newArr[newArr.length]= arr[i] //新数组的长度开始是0 随着数组内容增加 长度自动增加

}
}
console.log(newArr);

数组综合案例

案例1: 将数组[2,0,6,1,77,0,52,0,25,7]中的0去掉后, 形成一个不包含0的新数组

var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] != 0) {
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);

案例2: 翻转数组 ‘red’,’green’,’blue’, ‘pink’, ‘purple’

分析:

  1. 声明一个新数组newArr
  2. 把就数组索引号第四个取过来(arr.length - 1), 给新数组索引号第0个元素(newArrange.length)
  3. 我们采取 递减的方式 i–

实施:

var arr = ['red', 'green', 'blue', 'pink', 'purple'];
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i]
}
console.log(newArr);

案例3: 冒泡排序

是一种算法, 把一系列的数据按照一定的顺序精心排列显示(从小到大或者从大到小)

例如, 我们可以将数组[5,4,3,2,1]中的元素从小到大排序

从小到大排列

var arr = [5,4,3,2,1];
for(var i=0; i<arr.length; i++) {// 外层循环管趟数
for (var j = 0; j< arr.length-i; j++) { //里面的循环管 每一趟的交换次数
//内部交换两个两个变量的值 前一个和后一个 数组元素的比较
if (arr[j]>arr[j+1]) {
var temp = arr[j];
arr[j]= arr[j+1];
arr[j+1] = temp;
}

}
}
console.log(arr);

从大到小排列

var arr = [3,4,5,2,1];
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;
}

}
}
console.log(arr);

函数

概念

函数就是封装了一段可以重复执行调用的代码块
目的就是让大量代码重复使用

使用步骤

声明函数

格式:

function 函数名() {
//函数体
}

注意:

函数是做某件事情 函数名一般是动词
function必须小写
函数不调用 自己不执行

例子:

function syaHi() {
console.log('hi~~');
}

调用函数

格式:
js 函数名( );
注意:
调用函数的时候不要忘记加小括号
例子
sayHi()

函数的参数

利用函数的参数实现函数重读不同的代码

结构:

function 函数名(形参1, 形参2...) {

};

函数名(实参1, 实参2...);

两种参数:

形参
在声明函数的小括号里面
可以看作是不用声明的变量

实参
在函数调用的小括号里面

注意:

函数的参数可以 也可以没有 个数不限

多个参数之间用逗号隔开

实例:

function cook(aru) {  //形参是接收实参的 aru='酸辣土豆丝儿' 形参类似与一个变量
console.log(aru);
}
cook('酸辣土豆丝儿');
cook('茄子豆角')

案例:

//1.利用函数求任意两个数的和;

function getSum(num1, num2) {
console.log(num1 + num2);
}
getSum(1, 3);

//2.求 任意两个数且两个数之间的总和 :例如求1—100之间数字的综合(包括1和100)

function getSums(start, end) {
var sum = 0;
for (var i = start; i <= end; i++) {
sum += i;
}
console.log(sum);
}
getSums(1, 100);
getSums(55, 100);

函数形参和实参个数不匹配问题

实参个数等于形参个数 : 正常
实参个数>形参格式: 正常
实参取到形参的个数
实参个数<形参格式: 不正常 NaN

函数的返回值-return语句

有的时候, 我们会希望函数将值返回给调用者, 此时通过使用return语句就可以实现

思路:

​ 只要函数遇到return 就把后面的结果 返回给函数的调用者 即 函数名()=return 后面的结果

实例:

function getSum(num1, num2) {
return num1 + num2;
}
console.log(getSum(1, 3));

案例1: 利用函数求任意两个数的最大值,并返回最大值

function getMax(num1, num2) {
// if(num1>num2) {
// return num1;
// } else {
// return num2;
// }
return num1 > num2 ? num1 : num2; //三元表达式写法
}
console.log(getMax(1, 3)); //3
console.log(getMax(11, 3)); //11

案例2: 求数组[5,2,99,101,67,77]中的最大值

function getArrMax (arr) {  //arr 接收一个数组
var max = arr[0];
for (var i=1; i<= arr.length; i++) {
if(arr[i] > max) {
max = arr[i]
}
}
return max;
}
// console.log(getArrMax([1,2,3,4,5,6,78,6,6,,55])); //实参是一个数组 送过去
var re =getArrMax([1,2,3,4,5,6,78,6,6,55])
console.log(re); //78***在实际开发当中, 我们经常用一个变量来接受函数的返回结果, 使用更简单***

在实际开发当中, 我们经常用一个变量来接受函数的返回结果, 使用更简单

注意:

return终止函数
return语句之后的代码就不执行了

return只能返回一个值. 如果用逗号隔开多个值, 以最后一个值为准

但是可以利用数组返回多个值

function getResult(num1, num2) {
return [num1 + num2, num1 - num2, num1 * num2, num1 / num2];
}
var re= getResult(1,2)
console.log(re); //[3, -1, 2, 0.5]

函数都有返回值:

如果有return则返回return后面的值

如果没有return 则返回undefined

函数中的break continue return 的区别

break
结束当前循环体(如 for, while)
continue
跳出本次循环, 继续执行下次循环(for, while)
return
不仅可以退出循环, 还能返回return语句中的值, 同时还可以结束当前函数体内的代码, 函数内return的下一行语句将不再执行

arguments的使用

当我们不确定有多少个参数传递的时候, 可以用aruguments来获取.

在JS中, arguments 实际上它是当前函数的一个内置对象.

所有函数都内置一个arguments对象, arguments对象中以数组的形式储存了传递过来的所有实参

function fn() {
console.log(arguments);// [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(arguments.length); //3
console.log(arguments[1]); // 2
}
fn(1, 2, 3)

我们可以按照数组的方式遍历aruguments

for (var i=0; i<arguments.length; i++) {
console.log(arguments[i]);
}

注意:

arguments是伪数组 并不是正真意义上的数组

  1. 具有数组的length属性
  2. 按照索引的方式进行储存
  3. 它没有真正数组的一些方法 pop() push() 等等

案例: 利用函数来求任意个 数的最大值(找出一组数中的最大值)

function getMax() { //arguments = [1,2,3]
var max = arguments[0]; //将第一个元素作为初始值 来比较
for (var i =1; i<arguments.length; i++) {
if (arguments[i] > max) {
max =arguments[i];
}
}
return max;
}
console.log(getMax (1,2,3)); //3
console.log(getMax (1,2,3,4,5)); //5
console.log(getMax (11,2,34,46,57)); //57

一个函数调用另一个函数

function fn1() {
console.log(11);
fn2();
}

fn1();

function fn2() {
console.log(22);
}

函数的相关案例

案例1:利用函数封装方式, 翻转任意一个数组

思路就是: 进入循环后, 把旧数组的从后面开始的值依次添加到新数组中

function reverse(arr) {
var newArr = [];
for (var i=arr.length-1; i>=0; i--) { //i是旧数组的索引号
newArr[newArr.length] = arr[i];

}
return newArr
}
var arr1 = reverse([1,2,3,4,5,5,6,6,6,433,222,1,2])
console.log(arr1);
var arr2 = reverse (['red', 'blue', 'pink', 'red','哈哈哈'])
console.log(arr2);

案例2: 利用函数封装方式, 将数组排序–冒泡排序

function sort(arr) {
for (var i = 0; i < arr.length - 1; 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
}
}
return arr;
}
}
var arr1 = sort([1, 4, 2, 9])
console.log(arr1);
var arr2 =sort([11,7,33,999,888])
console.log(arr2);

案例3:判断闰年

输入一个年份, 判断是否闰年(闰年:能被4整除并且不能被100整除 或者能被400整除)

function isRunYear(year) {
//如果是闰年 反回true 否则 返回false
var flag =false;
if (year%4 ==0 && year%100 !=0 || year %400 == 0) {
flag =true;
}
return flag;
}
console.log(isRunYear(2000)); //true
console.log(isRunYear(1999)); //false

案例4: 输出年份的2月份的天数(一个函数调用另一个函数)

function backDay () {
var year =prompt('请输入年份');
if (isRunYear(year)) {
alert('当前年份是闰年, 2月份有29天');
} else {
alert('当前年份是平年, 2月份有28天');
}
}
backDay();
//判断是否为闰年的函数
function isRunYear(year) {
//如果是闰年 反回true 否则 返回false
var flag =false; //初始化比变量flag
if (year%4 ==0 && year%100 !=0 || year %400 == 0) {
flag =true;
}
return flag;
}

函数的两种声明方式

  1. 命名函数法
function fn() {
}
  1. 函数表达式法(匿名函数法)
var 变量名 = function () { 
}

实例

var fn = function( arr) {  
console.log('我是函数表达式');
}

fun 是变量名 不是函数名

函数表达式声明方式 跟声明变量差不多 , 只不过变量里面存的是函数表达式

函数表达式也可以进行传递参数

这两种的调用方法是一样的: 找到函数特定的名字 加上 (参数…) 即可;

fn()

作用域

代码名字(变量)在某个范围内起作用和效果 目的是为了提高程序的可靠性

更重要的是减少命名冲突

JS的作用域(es之前):

全局作用域

整个script标签
单独的一个js文件

局部作用域(函数作用域)

在函数内部就是局部作用域, 这个代码的名字只在函数内部起效果和作用

变量的作用域

根据作用域的不同,我们分为

全局变量

在全局作用域下的变量

在全局下都可以使用 也就是说可作用于函数内部

注意: 如果在函数内部 没有声明, 直接赋值的变量 也属于全局变量 || 不建议使用

局部变量

在函数内部的变量

注意: 函数的形参也可以看作是局部变量


从执行效率来看

全局变量 :只有浏览器关闭的时候才会销毁, 比较占内存资源

局部变量: 当我们程序执行完毕就会销毁, 比较节约内存资源

了解

JS没有块级作用域

在es6的时候新增的块级作用域

块级作用域 { }

作用域链

内部函数访问外部函数的变量 ,采取的是链式查找的方式来决定取哪个值

就近原则

预解析

介绍:

js引擎运行js分为两步:

预解析: js引擎里面所有的var 和function 提升到当前作用域的最前面

叫作 变量预解析 和 函数预解析

代码执行: 按照代码书写的顺序从上往下执行

变量预解析和函数预解析:

变量预解析: 变量提升 —把所有的变量声明提升到当前的作用域最前面 , 不提升赋值操作

函数预解析: 函数提升—把所有的函数声明 提升到当前作用域的最前面, 不调用函数

注意: 函数表达式 调用必须写在函数的表达式的下面

函数预解析的实例:

实例1

var num = 10;

function fn() {
console.log(num);
var num=20;
console.log(num);
}
fn();

解析过程

var num;
num = 10
function fn() {
var num;
console.log(num); //undefined
num=20;
console.log(num); //20
}
fn();

实例2

var a =18;
f1();
function f1() {
var b=9;
console.log(a);
console.log(b);
var a='123';
}

解析过程

// 解析过程
var a;

function f1() {
var b;
var a;
b=9;
console.log(a); //undefined
console.log(b);// 9
a ='123';
}
a=18;
f1();

案例4

经典例题:

f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9 // var a=9; b=9 c=9 //集体声明 var a=9, b=9, c=9;
console.log(a);
console.log(b);
console.log(c);
}

解析过程

//解析过程
function f1() {
var a;
a = b = c = 9
console.log(a); //9
console.log(b); //9
console.log(c);//9
}
f1();
console.log(c); //9
console.log(b); //9 因为b 与c 是全局变量了
console.log(a); // 报错 is not undefined