数组array
数组可以存储很多项,有顺序,很多项形成一个集合,就是数组。
数组字面量是:[]
如何获取数组中的数据:索引/下标,数组中的第一项的索引是从0开始的。
['kay', 'andy', 18, 19, true]数组可以存储多个值,也可以是不同数据类型但不建议使用!
存储的数组是要有意义的比如 name就只存名字,其他的元素18,19会把我们的数据给打乱!
创建数组与增删改查:
// 创建数组 var arr = ['andy', 'kay', 'jack']; // 获取数组里的第一项 console.log(arr[0]); // andy // 获取数组里的第二项 console.log(arr[1]); // kay // 获取数组的长度:就是数组中元素的个数 console.log(arr.length); // 3 // 获取数组中的最后一个元素:数组长度-1 console.log(arr[arr.length - 1]); // jack // 修改数组中的元素 arr[1] = 'aa'; console.log(arr); // ["andy", "aa", "jack"] // 在修改某元素时索引超出了它的长度就会给数组增加项 arr[5] = 'kay'; // 跳过的那些值默认就是undefined。 console.log(arr); // ["andy", "aa", "jack", empty × 2, "kay"] // 这是数组的长度可以动态改变 console.log(arr.length); // 6 // 追加元素 arr[arr.length] = 'abc'; console.log(arr); // ["andy", "aa", "jack", empty × 2, "kay", "abc"] // 清空数组 arr.length = 0; console.log(arr); // []
遍历数组
var arr = ['kay', 'andy', 'jack']; // 数组的第一个元素是从0开始,数组中的最后一个元素(就是数组的长度-1) for (var i = 0; i < arr.length; i++) { console.log(arr[i]); } // 反向遍历数组 var array = ['kay', 'andy', 'jack']; // 数组中的最后一个元素(就是数组的长度-1), 数组的第一个元素是从0开始 for (var j = array.length - 1; j >= 0; j--) { console.log(array[j]); }
例子:求一组数的和和平均值
var numbers = [10, 20, 30]; // 总和 var sum = 0; // 平均值 var avg = 0; for (var i = 0; i < numbers.length; i++) { sum += numbers[i]; } avg = sum / numbers.length; console.log(sum); // 60 console.log(avg); // 20
job:求一组数中的最大值和最小值,以及所在位置
var numbers = [79, 21, 3, 8, 45, 88, 89]; // 假设数组中第一个元素就是最大 var max = numbers[0]; // 假设数组中第一个元素就是最小 var min = numbers[0]; //最大值的索引位置 var maxIndex; // 最小值的索引位置 var minIndex; // 拿到数组中的每一元素 for (var i = 0; i < numbers.length; i++) { // 比max大 if (max < numbers[i]) { // 重新赋值 max = numbers[i]; // 索引位置 maxIndex = i; } // min大于numbers[i] if (min > numbers[i]) { // 重新赋值 min = numbers[i]; // 索引位置 minIndex = i; } } console.log(max + '索引位置:' + maxIndex); console.log(min + '索引位置:' + minIndex);
job:将字符串数组用符号(|)分割
var names = ['人工智能', '大数据', '前端', 'kay', 'java']; var str = names[0]; // 分隔符 var seperator = '|'; for (var i = 1; i < names.length; i++) { str += seperator + names[i]; } console.log(str); // 人工智能|大数据|前端|kay|java
job:将数组中的0项去掉,将不为0的的值存到一个新的数组,生成新的数组
var numbers = [88, 0, 13, 32, 0, 2, 0, 62]; // 新数组 var newArr = []; // 遍历数组 for (var i = 0; i < numbers.length; i++) { // 不等于0 if (numbers[i] !== 0) { // 储存到新数组里 newArr[newArr.length] = numbers[i]; } } console.log(newArr); // [88, 13, 32, 2, 62]
job:翻转数组
var arr = ['kay', 18, 'jack', 19]; // 新数组 var newArr = []; // 反向遍历 for (var i = arr.length - 1; i >= 0; i--) { // 存储到新数组里 newArr[newArr.length] = arr[i]; } console.log(newArr); // [19, "jack", 18, "kay"]
job:冒泡排序-从小到大排
var numbers = [79, 12, 3, 1, 54, 7, 45, 68]; // 外层循环控制趟数 for (var i = 0; i < numbers.length; i++) { // 假如已排好 var isOk = true; // 内层循环控制比较次数 for (var j = 0; j < numbers.length - 1 - i; j++) { // 元素1比元素2大 if (numbers[j] > numbers[j + 1]) { // 未排好序 isOk = false; // 定义临时变量 赋予元素1 var tmp = numbers[j]; // 元素2 放到 元素1的位置 numbers[j] = numbers[j + 1]; // 元素1 放到 元素2的位置 numbers[j + 1] = tmp; } } if (isOk) { // 终止循环 break; } } console.log(numbers); // [1, 3, 7, 12, 45, 54, 68, 79]
函数 function
函数的作用:封装代码,重复调用
定义函数
// 定义函数 function getSum() { // 函数体 // 计算1到100之间所有数的和 var sum = 0; for (var i = 1; i <= 100; i++) { sum += i; } console.log(sum); } // 调用函数 getSum(); // 5050
函数的参数:调用时,可以向其传递值
// 计算n到m之间所有数的和 // 定义函数(形参1, 形参2) function getSum(n, m) { // 函数体 var sum = 0; for (var i = n; i <= m; i++) { // 累加 sum += i; } console.log(sum); } // 调用函数并传递实参 getSum(50, 100); // 3825
传入的参数可以是变量,在函数内部修改形参的值,不会影响外部的实参的值。
因为在调用函数时,复制了一份给形参的。
function getSum(a, b) { // 修改形参的值 a = a + 1; b = b + 1; console.log(a); // 2 console.log(b); // 3 } var n1 = 1; var n2 = 2; getSum(n1, n2); // 不会影响外部的值 console.log(n1); // 1 console.log(n2); // 2
函数的返回值:返回值只有一个
可以用变量接收返回值。当函数里不写return返回值时用用变量接收的是undefined,不写return也是返回undefined!
return后面的代码是不会执行的!
// 计算n到m所有数的和,并返回 function getSum (n, m) { // 函数体 var sum = 0; for (var i = n; i <= m; i++) { // 累加 sum += i; } // 返回所有数的和 return sum; } // 接收返回值 var num = getSum(1, 100); console.log(num); // 5050
job: 判断一个数是否是素数(所谓质数就是只能被1或自身整除,不能被其他数整除)
// 定义函数 function getPrime(num) { // 只能被1或者自身整除 for (var i = 2; i < num; i++) { // 被整除 if (num % i === 0) { // 返回false return false; } } // 是质数 return true; } console.log(getPrime(13)); // true
job:求1!+2!+3!+....+n!
// 求阶乘 // 定义函数 function getFactorial(num) { // 因为是算乘法,我们用1去乘 var result = 1; for (var i = 1; i <= num; i++) { result *= i; } // 返回结果 return result; } // console.log(getFactorial(3)); // 6 // 求阶乘的综合 // 定义函数 function getSum(num) { var sum = 0; for (var i = 1; i <= num; i++) { // 累加 sum += getFactorial(i); } // 返回总和 return sum; } console.log(getSum(3)); // 9
arguments:在函数里获取实参,实参的个数可以发生改变。
实参个数不确定的时候可以使用,定义函数时不写形参。
arguments是一个伪数组,有长度
// 定义函数时不写形参 function test() { console.log(arguments); // [1, 66, 7, 34, 98, callee: ƒ, Symbol(Symbol.iterator): ƒ] } // 传递实参 test(1, 66, 7, 34, 98);
job: 求任意个数的最大值
// 定义函数 function getMax() { // 假设第一就是最大的值 var max = arguments[0]; // 遍历这个伪数组 for (var i = 1; i < arguments.length; i++) { // 比较 if (max < arguments[i]) { // max重新赋予值 max = arguments[i]; } } // 返回这个max return max; } // 传入任意个数的实参 var num = getMax(79, 78, 88, 45, 23, 21); console.log(num); // 88
job:求任意个数的和
// 定义函数 function getSum() { var sum = 0; // 遍历这个伪数组 for (var i = 0; i < arguments.length; i++) { // 累加 sum += arguments[i]; } // 返回sum return sum; } // 传入任意个数的实参 var num = getSum(10, 20, 30); console.log(num); // 60
job:任意个数从小到大排|冒泡排序
// 定义函数 function sort() { // 外层循环控制趟,每执行完一趟就排好一个元素 for (var i = 0; i < arguments.length; i++) { // 假设已经排好 var isSort = true; // 内层循环控制比较次数 for (var j = 0; j < arguments.length - 1 - i; j++) { // 比较两个元素 if (arguments[j] > arguments[j + 1]) { // 还没有排好序 isSort = false; // 交换位置 var tmp = arguments[j]; arguments[j] = arguments[j + 1]; arguments[j + 1] = tmp; } } // 判断是否排好序 if (isSort) { // 终止循环 break; } } // 返回已排好序的伪数组 return arguments; } // 传入任意个数的形参 var numbers = sort(79, 23, 56, 11, 2, 9); console.log(numbers); // [2, 9, 11, 23, 56, 79, callee: ƒ, Symbol(Symbol.iterator): ƒ]
函数其它
1,命名函数:有名
2,匿名函数:没名,赋给一个变量
// 赋给变量 var fn = function () { alert('hello kay'); } fn();
3,自调用函数:没名,也不赋给变量
// 没名,不赋给变量 (function () { alert('hello kay'); }) (); // 紧跟着一对括号直接调用
4.1函数当参数:传递给其它函数
// 先赋给一个变量 var fn1 = function () { alert('hello kay'); } function fn2 (fn) { // 调用函数 fn(); } // 当参数传入 fn2(fn1);
4.2函数当返回值
function fn() { // 函数当返回值 return function () { alert('hello'); } } // 一个变量取接收这个函数 var fn1 = fn(); // 调用接收的函数 fn1();
作用域:使用范围
全局变量和局部变量:
全局变量:声明的变量使用var声明的,那么这个变量就是全局变量,并且在任何位置都可以使用。
隐式全局变量:声明变量时没有加var,就叫全局变量。
全局变量不能被删除的,隐式全局变量可以被删除的,定义变量使用var是不会被删除的,没有var是可以用delete删除的
局部变量:在函数内部定义的变量,外面不能使用。
块级作用域:
{ var num = 88; } // 可以使用 console.log(num); // 88
一对大括号可以看成是一块,在这块区域中定义的变量,只能在这块区域使用,
但在js中在这块区域中定义的变量外面是可以使用的!
所以说明js没有块级作用域,也就是全局变量,函数除外
作用域链:
在函数中使用一个变量,先在该函数中搜索这个变量,找到了则使用,找不到则继续向外面找这个变量,找到了则使用,
一直找到全局作用域,找不到则报错!
// 0级全局作用域 var num = 456; function f1() { // 1级作用域 var num = 123; function f2() { // 2级作用域 console.log(num); } f2(); } f1();
预解析
浏览器的解析引擎:
javascript代码的执行是由浏览器中的javascript解析器来执行的。
javascript解析器执行javascript代码时分为两个过程:预解析和代码执行过程。
两个问题:
console.log(num); // 结果是undefined,而不是报错 var num = 666;
f1(); function f1() { console.log(666); } // 结果是666
预解析过程:
1,把变量的声明提升到当前作用域的最前面,只提升声明,不提升赋值!
2,把函数的声明提升到当前作用域的最前面,只提升声明,不提升调用!
3,先提升var,再提升function!
f1(); console.log(b); console.log(c); console.log(a); function f1() { var a = b = c = 8; console.log(a); console.log(b); console.log(c); }
8 8 8 8 8 a is not defined
由于a是局部变量,外部无法访问到,所以报错。
而b和c声明变量没有用var声明,是隐身全局变量,外部是可以访问到的。
console.log(a); function a() { console.log('666'); } var a = 8; console.log(a);
a() { console.log('666'); } 8
当变量名与函数名相同,函数优先