一、使用arugments实现 函数的递归调用
使用arugments.callee实现函数的递归调用.
arugments 在严格模式下禁止使用。
<script>
//斐波那切数列使用递归实现
/*var fibo = function (n) {
if (n === 1 || n === 2)
return 1;
return fibo (n - 1) + fibo (n - 2);
}*/
var fibo = function (n) {
if (n === 1 || n === 2)
return 1;
return arguments.callee (n - 1) + arguments.callee (n - 2);
}
for (let i = 1; i < 10; i++) {
console.log (fibo(i));
}
//多个变量指向同一个对象
var fibo1 = fibo;
console.log (fibo1(9));
//废弃一个对象变量
fibo = null;
//fibo();会报错。
console.log (fibo1(10));
</script>
二、引入数组
需求:随机得到10个学生的分数。然后求学生的总分和平均分。
<script>
const COUNT = 10;
const MIN_SCORE = 60;
const MAX_SCORE = 101;
//定义数组,空数组。
var scores = [];
function random(min, max) {
return ~~(Math.random () * (max - min) + min);
}
var sum = 0;
var avg = 0;
//使用循环得到学生的分数,累加
for (let i = 0; i < COUNT; i++) {
var score = random (MIN_SCORE, MAX_SCORE);
sum += score;
//将得到的随机数,添加到数组中。
scores[i] = score;
console.log (`第${i+1}个学生的分数为:${score}`);
}
avg = sum / COUNT;
console.log ("sum = " + sum);
console.log ("avg = " + avg);
//访问每一个学生的分数。
//打印数组
console.log (scores);
for (let i = 0; i < COUNT; i++) {
console.log (`第${i+1}个学生的分数为:${scores[i]}`);
}
</script>
三、数组的定义和特点
数组的概念: array
数组是一组【有序的】【变量】的【集合】。
数组的简单定义形式:
var 数组变量 = [数据1,数据2,…];
特点:
1:数组是我们接触到的第二种引用(reference)数据类型。数组的所有的数据在堆内存(heap)中。数据是连续的。
2:数组中的数据是有顺序的。有序号。序号是连续的,从0开始的。依次递增。最大到32bits的最大值 - 2。序号一般称为:索引(index)、下标、角标。
4: 数组中的数据一般称为元素(element);数组中的每个元素都是有下标的。
5: 数组访问元素,通过: 数组名[下标] (代表了数组中的一个变量)。
6:数组是一种特殊的对象。使用typeof 返回 object。
7: 数组是一种特殊的对象,也是键值对的集合。所有的键都是数值型的字符串。从0开始。
对象中的键都是字符串。
8:数组中的元素的类型可以是js支持的任意类型。元素可以重复。元素的数据类型可以不同。
9:数组有一个属性,length。代表了数组的元素的个数。是一个整数值。取值范围是[0~2**32 - 1],通过数组名.length 来访问该属性。 所以,元素的下标的取值范围是[0~length-1];
<script>
var arr = [0,1,2,3,4,5,6,7,8,9];
//length
console.log (arr.length);//10
//length的最大值。下标的最大值。2**32 - 2。
arr.length = 2**32 - 1;
//如果下标超过了length,那么就当做字符串来处理了。
arr[2**32] = 100;
var num = 10;
num ++;
num += 10;
//之前的变量如何使用,数组的元素就如何使用。
arr[0] ++;
arr[0] += 10;
console.log (arr[0]);//11
console.log (arr["0"]);//11
var obj = {
"0":10,
"1":11,
"2":10
};
console.log (typeof arr);//object
var arr1 = [
1,
"千万里我追寻着你",
true,
undefined,
null,
[1,2,true,null],
function () {
console.log ("hello");
},
{
name:"刘奇",
age:21
}
];
console.log (arr1[0]);
console.log (arr1[1]);
console.log (arr1[5][2]);
arr1[6]();
console.log (arr1[7].name);
console.log (arr1[7]["name"]);
</script>
四、in关键字介绍
in 关键字:
作用:用来判断某一个值是否是某个对象的属性(key)。
语法:key in obj : key 是否是obj对象的一个键。如果是返回true,否则返回fasle。
<script>
var arr = [1, 2, 3, 4, 5];
console.log (0 in arr);//true
console.log ("4" in arr);//true
console.log (5 in arr);//false
var obj = {
name:"小刚",
age:19,
gender:"男"
};
console.log ("name" in obj);//true
console.log ("age" in obj);//true
var gen = "gender";
console.log (gen in obj);//true
</script>
五、数组的length属性
length:是数组的一个属性.
1: length 作为数组对象的一个特殊的key ,值是数组中键值对的个数。
是一个大于等于0的值。最大值为 2**32 - 1; 最小值为0.
该值不需要开发者来管理,数组这种数据类型底层自行维护。该值会
自动的调整,是一个动态的值。
最大值:4294967295
2:访问length属性的方式:数组名.length
3: 可以通过修改length属性的值,实现对数组的扩容和缩容。
a:通过修改length属性,扩容。没有赋值的元素的值为:undefined
b: 缩容,直接保留低索引的元素,超过数量的高索引元素直接被截断。
<script>
var arr = ["a","b","c"];
console.log (arr);
console.log (arr.length);//3
arr[3] = "d";
console.log (arr.length);//4
//修改length属性
arr.length = 2**32 - 1;
console.log (arr);
console.log (arr[4]);
//缩容
arr.length = 2;
console.log (arr);
//中间有若干个元素没有赋值。中间的元素的值为undefined。
//不建议使用如下的方式。
arr[10] = "g";
console.log (arr);
console.log (arr.length);
console.log (arr[5]);
</script>
六、练习
练习:求2-100之间所有的素数,存入一个数组中。并打印数组的内容。
质数:又称为素数,只能被1和自身整除的数。
<script>
/**
* 判断num是否是素数
* @param num
*/
function isPrime(num) {
if (num <= 1)
return false;
for (let i = 2; i < num; i++) {
if (num % i === 0)
return false;
}
return true;
}
/**
* 得到区间的所有的素数
* @param min 区间包含
* @param max 区间不包含
*/
function getPrimes(min, max) {
var arr = [];
var index = 0;
//遍历区间,将素数i添加到数组中
for (let i = min; i <max ; i++) {
if(isPrime(i)){
arr[index++] = i;
// index ++;
}
}
//最后返回数组
return arr;
}
//测试方法
function test() {
var primes = getPrimes(2,101);
console.log (primes);
}
test();
</script>
七、数组的初始化方式
数组的初始化方式:
1:表达式直接赋值的方式 (一般情况)
2:构造函数式 (少用的情况)
<script>
//1 比较常用的方式。
var arr = [1,2,3,4];
var arr = [];
arr[0] = 1;
arr[1] =2;
arr[2] = 3;
//2 构造函数方式
//创建了数组对象,初始化元素个数为6,并指定了每个元素的值。
var arr = new Array(1,2,3,4,5,6);
console.log (arr);
//创建了数组对象,初始化元素个数为6,每个元素的默认值为undefined。
var arr = new Array(6);
console.log (arr);
</script>
八、数组的内存图
九、数组的元素的操作
数组元素的操作:
增:
数组名[新下标] = 值;
会动态的修改数组的length属性。
删:
delete 数组名[删除元素的下标];
删除之后,该位置的值被删除,修改元素的默认值undefined。
不会修改length属性。
改:
数组名[下标] = 新的值;
查:
数组名[下标];
<script>
var arr = ["a","b","c","d"];
//增加元素的操作
arr[4] = "e";//下标连续增加
arr[10] = "x";//下标不连续,中间会有undefined的元素。
// ["a", "b", "c", "d", "e", empty × 5, "x"]
console.log (arr);
//删除某个元素
delete arr[3];
console.log (arr);
//修改
arr[1] = "B";
console.log (arr);
//获取
console.log (arr[0]);
</script>
十、数组的传引用
基本数据类型作为参数,传参的过程:给形参分配内存,并将实参的【值】赋值给形参的过程。
传值的过程。pass by value。
数组作为实参,参数传递介绍:
数组是引用数据类型,数组变量保存的是数组对象的引用(地址)。
数组作为参数,传参的过程是:给形参分配内存,并将实参的【引用】赋值给形参的过程。
传引用的过程:pass by reference。
<script>
var arr = [1, 100];
//交换数组中的两个元素的值
function change(arr) {
arr[0] = arr[0] ^ arr[1];
arr[1] = arr[0] ^ arr[1];
arr[0] = arr[0] ^ arr[1];
}
change (arr);
console.log (arr);
//传值的例子
var num1 = 10;
//将num1的值赋值给了num2.
var num2 = num1;
num2++;
console.log (num1);//10 没有变
console.log (num2);//11 变了。
var arr1 = [1];
//将arr1的引用赋值给了arr2.
//arr1 和 arr2 同时指向了同一个对象。
var arr2 = arr1;
arr2[0]++;
console.log (arr1);//[2];
console.log (arr2);//[2];
</script>
十一、数组的遍历
遍历数组的方式:
1:基本的for循环 使用最多的一种。
2: for in 循环。用来遍历对象。
3:for of 循环。
4:for-each 实例方法
<script>
var arr = ["a", "b", 'c', "d", "e", "f", "g"];
const LEN = arr.length;
//1 使用基本的for循环遍历数组的元素
for (let i = 0; i < LEN; i++) {
console.log (arr[i]);
}
console.log ("-----------------");
//2 for in 循环 i代表了数组元素的所有的下标。
for (var i in arr){
console.log (arr[i]);
}
console.log ("-----------------");
//3 for of 循环 不能直接得到ele元素所对应的下标。
for (var ele of arr){
console.log (ele);
}
console.log ("-----------------");
//4 for-each 遍历 实例方法,想遍历哪个数组,就用哪个数组对象去调用该方法
var fn = function(ele,index){
//ele : 数组的元素。
//index 是ele的元素的下标。
console.log (`第${index+1}个元素是:${ele}`);
};
arr.forEach(fn);
console.log ("-----------------");
arr.forEach(function(ele,index){
//ele : 数组的元素。
//index 是ele的元素的下标。
console.log (`第${index+1}个元素是:${ele}`);
});
console.log ("-----------------");
arr.forEach(function (ele,index) {
console.log (`第${index+1}个元素是:${ele}`);
});
</script>
十二、类数组对象介绍
类数组对象:类似于数组对象的对象。
类数组对象的条件:
1:所有的key都是数值型的字符串。
2:还有length属性。
类数组对象和数组对象的区别:
1:length属性的区别。数组的length 是动态的。
类数组对象的length,不会自动修改个数。
2:数组作为js的内置数据类型,js提供了大量的操作数组的方法供它使用。
类数组对象是不存在这些函数的。
相同点:
1:都是对象
2:都可以添加非数值型的键key。数组中添加非数值型的键,不会影响length属性。
补充:
可以通过一个函数来判断任意对象是否是数组对象。
Array.isArray(obj); 如果obj是数组返回true,否则返回false。
<script>
var obj = {
0 : "a",
1 : "b",
2 : "c",
length:3
};
console.log (Array.isArray(obj));//false
console.log (obj[0]);
console.log (obj[1]);
console.log (obj[2]);
obj[3] = "d";
console.log (obj.length);
//给对象添加属性。
obj.name = "对象";
console.log (obj);
//给数组添加非数值型的key。不会影响数组的长度。
var arr = ["a","b"];
arr.name = "数组";
console.log (arr);
console.log (arr.length);
console.log (Array.isArray(arr));//true
</script>
十三、数组练习
1:自定义函数实现,获得一个随机数组的方法,数组元素的个数是任意的,元素的取值区间是任意的。
2:自定义函数实现:求任意数组中的元素的最大值。
3:自定义函数实现:统计任意数组中的元素等于某个值的个数。
4:自定义函数实现:统计任意数组中的元素等于某个值的所有的下标。需要返回一个数组。
<script>
/**
*
* @param length
* @param min
* @param max
*/
function getRandomArray(length, min, max) {
var arr = [];
for (let i = 0; i < length; i++) {
arr[i] = random (min, max);
}
return arr;
}
function random(min, max) {
return ~~(Math.random () * (max - min) + min);
}
//2
function max(arr) {
if (!Array.isArray (arr)) {
return undefined;
}
var max = arr[0];
//max和后续的所有的元素比较
for (let i = 1; i < arr.length; i++) {
if (arr[i] > max)
max = arr[i];
}
return max;
}
/**
* 统计arr中有多少个value值
* @param arr
* @param value
*/
function counterValue(arr, value) {
if (!Array.isArray (arr)) {
return 0;
}
const LEN = arr.length;
if (LEN === 0)
return 0;
//遍历数组,挨个和value比较,相等计数加一
var counter = 0;
for (let i = 0; i < LEN; i++) {
if(arr[i] === value)
counter++;
}
return counter;
}
//4
/**
* 统计arr中值为value的所有的索引
* @param arr
* @param value
*/
function counterIndexes(arr,value) {
if (!Array.isArray (arr)) {
return [];
}
const LEN = arr.length;
if (LEN === 0)
return [];
var indexes = [];
var index = 0;
//遍历数组,挨个比较,和value相等,将该元素的下标添加到indexes中
for (let i = 0; i <LEN ; i++) {
if(arr[i] === value){
indexes[index ++] = i;
}
}
return indexes;
}
var arr = getRandomArray (20, 0, 10);
console.log (arr);
console.log (max (arr));
console.log (counterValue(arr,7));
console.log (counterIndexes(arr,7));
</script>