一. JavaScript 数组、对象、函数
1. 数组
-
JavaScript中数组的使用和 Java 中的数组基本一致,但是在 JavaScript 中的数组更加灵活,数据类型和长度都没有限制。数组官方文档可参考:文档
-
javascript和java数组的区别
-
js数组可以自动扩容,不会出现数组越界的情况,数组中可以存放任意数据类型。
-
java数组一旦定义长度,不可以更改,数组中的数据类型必须一致。
-
1.1. 创建数组
var cars = ["奔驰", "宝马", "保时捷"];
var arr = ["aa", 23, 3.14, false];
1.2. 基本操作
1.2.1. 通过下标访问数据元素
数组中的元素是通过下标访问的,下标从0开始,一直到数组的长度-1
var firstCar = cars[0]; // 获取第一个元素
var car = cars[2]; // 获取下标为2的元素
var lastCar = cars[cars.length - 1]; // 获取最后一个元素
console.log(firstCar);//奔驰
console.log(car); //保时捷
console.log(lastCar); //保时捷
1.2.2. 更改数组元素
cars[2] = "法拉利";
console.log(cars); // ['奔驰','宝马','法拉利']
1.2.3. 获取数据长度
var length = cars.length;
console.log('cars数组的长度:' + length); // 3
需要注意的是和Java中的数组不同,JS中数组的length属性是可写的
//将length赋为一个大的值,剩余元素的值使用 empty x 7 表示
cars.length = 10;
console.log(cars); // ['奔驰', '宝马', '法拉利', empty × 7]
//将length赋为一个更小的值会删除元素
cars.length = 2;
console.log(cars); // ['奔驰', '宝马']
cars.length = 3;
console.log(cars); //['奔驰', '宝马', empty]
1.2.4. 遍历数组
for(let i = 0; i < cars.length; i++) {
let car = cars[i];
console.log('car: ' + car);
}
// ECMA5.1新增
//参数1:遍历的元素的值 参数2:遍历的元素的角标索引(可选) 参数3:遍历的数组
cars.forEach((item,index,cars) => {
console.log(item+":"+index);
})
1.2.5. 将数组转成字符串 — toString()
var ss = cars.toString();
console.log(ss); //奔驰,宝马
1.2.6. 查找第一个匹配元素的下标 — indexOf()
返回数组中第一个与指定值相等的元素的索引,如果找不到这样的元素,则返回 -1
var idx = cars.indexOf("宝马");
console.log(idx);//1
idx = cars.indexOf("大众");
console.log(idx); // 未找到,返回-1
1.2.7. 查找最后一个匹配元素的下标 — lastIndexOf()
返回数组中最后一个(从右边数第一个)与指定值相等的元素的索引,如果找不到这样的元素,则返回 -1。
var lastidx = cars.lastIndexOf("奔驰");
console.log(lastidx); // 0
lastidx = cars.lastIndexOf("大众");
console.log(lastidx); // 未找到,返回-1
1.2.8. 判断一个对象是不是数组类型 — isArray()
console.log(Array.isArray(car)); // true
1.3. 进阶操作
1.3.1. 向数组尾部追加元素 — push()
用push方法可以完成向数组中添加一个或多个元素的操作,新添加的元素会放到数组最后的位置
//添加一个元素
cars.push("凯迪拉克");
console.log(cars.toString()); //奔驰,宝马,凯迪拉克
//添加多个元素
cars.push("大众", "福特");
console.log(cars.toString()); //奔驰,宝马,凯迪拉克,大众,福特
1.3.2. 删除数组中最后一个元素 — pop()
删除数组中最后一个元素,并返回该元素
var car = cars.pop();
console.log(car); //福特
console.log(cars.toString())//奔驰,宝马,凯迪拉克,大众
1.3.3. 向数组头部插入元素 — unshift()
unshift方法可以将一个或多个元素添加到数组的开头位置,与push方法对应
cars.unshift("劳斯莱斯");
console.log(cars.toString());//劳斯莱斯,奔驰,宝马,凯迪拉克,大众
cars.unshift("雷克萨斯","蒙迪欧");
console.log(cars.toString()); // 雷克萨斯,蒙迪欧,劳斯莱斯,奔驰,宝马,凯迪拉克,大众
1.3.4. 删除数组中第一个元素 — shift()
shift方法可以删除数据中第一个元素,并返回删除的元素,与pop方法对应
var car = cars.shift();
console.log("被删除的元素:" + car); // 雷克萨斯
console.log(cars.toString()); //蒙迪欧,劳斯莱斯,奔驰,宝马,凯迪拉克,大众
1.3.5. 将数组的所有元素连接成一个字符串 — join()
var strCars = cars.join("*");
console.log(strCars); // 蒙迪欧*劳斯莱斯*奔驰*宝马*凯迪拉克*大众
该方法也不会修改原数组
1.3.6. 连接多个数组 — concat()
concat方法可以将一个或多个数组中的元素拼接成一个新的数组(不会修改原数组)
var myGirls = ["邓紫棋", "孙燕姿"];
var myBoys = ["周杰伦", "刘德华", "陈奕迅"];
var myFruits = ["苹果", "香蕉", "橙子"];
var myChildren1 = myGirls.concat(myBoys);
var myChildren2 = myBoys.concat(myGirls,myFruits);
console.log(myChildren1); // ["邓紫棋", "孙燕姿", "周杰伦", "刘德华", "陈奕迅"]
console.log(myChildren2); // ["周杰伦", "刘德华", "陈奕迅", "邓紫棋", "孙燕姿", "苹果", "香蕉", "橙子"]
//两个数组连接,调用concat函数的一方的数组元素在新数组的前边
//如果concat函数的参数是多个数组,在新数组中,参数1数组的元素在参数2数组的元素的前边
1.3.7. 将元素添加到数组中指定位置,并删除该位置后若干元素 — splice()
splice方法的功能比较强大:
-
删除数组中的元素
var fruits = ["香蕉", "橙子", "苹果", "芒果"];
let delItem = fruits.splice(2, 1); // 从下标为2的元素开始,往后删除一个元素,返回删除的元素
console.log('被删除的元素:' + delItem); //被删除的元素是香蕉
console.log(fruits); // ["香蕉", "橙子", "芒果"]
- 插入元素到指定位置
fruits.splice(2, 0, "柠檬", "石榴"); // 在第三个元素前面添加"柠檬", "石榴"
console.log(fruits); // ['香蕉', '橙子', '柠檬', '石榴', '芒果']
- 删除指定位置元素,然后在该位置插入指定元素
fruits.splice(3, 2, "榴莲", "西瓜") // 从第四个元素开始删除两个元素,之后再添加两个元素
console.log(fruits); // ['香蕉', '橙子', '柠檬', '榴莲', '西瓜']
1.3.8. 数组排序 — sort()
sort方法可以将数组中的元素按照默认的排序算法做升序排序,我们也可以指定自定义的排序算法
// 使用默认排序算法将数组升序排序(可结合reverse方法实现降序排列)
var languages = ["Java", "PHP", "IOS"];
languages.sort();
console.log(languages.toString()); // IOS,Java,PHP
//指定自定义的排序方法
// 使用js中的lamada表达式传一个匿名函数完成按照字符串的本地比较方法作为排序算法
fruits.sort((a,b) => {return a.localeCompare(b)});
console.log(fruits); // ['橙子', '榴莲', '柠檬', '西瓜', '香蕉']
1.3.9. 数组反转 — reverse()
将数组中的元素顺序反转
languages.reverse();
console.log(languages.toString()); // PHP,Java,IOS
1.3.10. 抽取数组中部分元素生成新数组 — slice(start, end)
slice方法可以根据传入的start下标和end下标从数组中截取部分元素生成新的数组,包含start不包含end( [start,end) )。
注意:slice方法不会改变原数组
console.log('原始数组:');
console.log(fruits); // ['橙子', '榴莲', '柠檬', '西瓜', '香蕉']
// 从下标1开始,截取到下标2
// 注意:slice不会并不会裁剪原数组,只是从原数组中截取部分元素生成一个新的数组对象
var newFruits = fruits.slice(1,3);
console.log('新数组:');
console.log(newFruits); // ['榴莲', '柠檬']
2. Map
ECMAScript 2015(ES6) 引入了一个新的数据结构来将一个值映射到另一个值。一个Map
对象就是一个简单的键值对映射集合,可以按照数据插入时的顺序遍历所有的元素。
Map
对象常用操作如下:
// 创建map类型
var sayings = new Map();
// 添加元素
sayings.set('dog', 'woof');
sayings.set('cat', 'meow');
sayings.set('elephant', 'toot');
console.log(sayings);
// 获取map元素数量
console.log("sayings map的长度" + sayings.size); // sayings map的长度3
// 按照Key获取元素值(如果该key不存在,则返回undefined)
console.log(sayings.get('cat')); // meow
// 判断map中是否存在指定的key,存在true 不存在false
console.log(sayings.has('bird')); // false
// 按照key删除map中的元素
sayings.delete('dog');
console.log(sayings.has('dog')); // false
//循环遍历map
for (var [key, value] of sayings) {
console.log(key + ":" + value); //cat:meow
// elephant: toot
}
// 清空map
sayings.clear();
console.log("sayings map的长度" + sayings.size); // 0
3. Set
Set
对象是一组值的集合,这些值是不重复的,可以按照添加顺序来遍历,这点和大多数编程语言类似。
Set
对象常用操作如下:
// 创建Set对象
var mySet = new Set();
// 添加元素
mySet.add(1);
mySet.add("some text");
mySet.add("foo");
console.log(mySet); //Set(3) { 1, 'some text', 'foo' }
// 判断是否存在某个元素
console.log(mySet.has(1)); // true
// 删除某个元素
mySet.delete("foo");
//获取set集合的长度
console.log(mySet.size); //2
//遍历所有的元素
for (let item of mySet) {
console.log(item) // 1 some text
};
4. 函数
函数是JavaScript中的一个基本概念, 它允许你在一个代码块中存储一段用于处理单任务的代码,然后在任何你需要的时候用一个简短的命令来调用,而不是把相同的代码写很多次。
函数分为 内置函数 和 自定义函数
4.1. 内置函数
在前面的章节我们已经学习了好多内置函数,比如数组中的 join()
、slice()
,Math中的random()
等。
JavaScript有许多内置的函数,可以让你做很多有用的事情,而无需自己编写所有的代码。事实上, 许多你调用(运行或者执行的专业词语)浏览器内置函数时调用的代码并不是使用JavaScript来编写——大多数调用浏览器后台的函数的代码,是使用像C++这样更低级的系统语言编写的,而不是像JavaScript这样的web编程语言。
还有一些内置函数在浏览器API的内置对象上,如 window.alert()
、window.open()
,这些内置浏览器函数不是核心JavaScript语言的一部分,而是被定义为浏览器API的一部分。
4.2. 数学运算函数
- round 四舍五入
console.log(Math.round(12.2));// 12
- pow 次方
//次方 参数1:数值 参数3:次方
console.log(Math.pow(2,3));//8
-
sqrt 平方根
//平方根 console.log(Math.sqrt(9));// 3
-
abs 绝对值
console.log(Math.abs(-10)); //10
-
ceil 向上取整
console.log(Math.ceil(10.1));//11
-
floor 向下取整
console.log(Math.floor(10.8))//10
-
random 返回介于0(包括)与1(不包括)之间的随机数
// 随机0 ~ N(不包含)之间的整数 Math.floor(Math.random()*N) // 随机0 ~ N(包含)之间的整数 Math.floor(Math.random()*(N+1)) // 返回0 ~ 11(不包含)之间的随机整数 Math.floor(Math.random()*11) // 返回0 ~ 100(包含)之间的随机整数 Math.floor(Math.random()*101) // 返回10 ~ 100(包含)之间的随机整数 Math.floor(Math.random()*91) + 10 // 返回 min ~ max(包含)之间的随机整数 Math.floor(Math.random() * (max - min + 1) ) + min; //10-20之间的随机整数 console.log(Math.floor(Math.random() * (20 - 10 + 1)) + 10);
-
sin 正弦
-
cos 余弦
-
max 返回参数列表中最大值
// 获取一组数字中的最大值 var maxNum = Math.max(0, 150, 30, 20, -8, -200);
注意:如果参数列表中有非数字,最后结果会返回NaN
-
min 返回参数列表中最小值
-
Math.PI 返回PI的值
console.log(Math.PI); // 3.141592653589793
-
isNaN()
判断所传的值是否为非数字
console.log(isNaN(34)); // false console.log(isNaN('34d')); // true
4.3. 日期操作相关
JavaScript没有日期数据类型。但是你可以在你的程序里使用 Date
对象和其方法来处理日期和时间。Date对象有大量的设置、获取和操作日期的方法。 它并不含有任何属性。
下面列举日期对象常用方法:
-
创建日期对象
var dateObjectName = new Date([parameters]);
-
无参数 : 创建今天的日期和时间,例如:
today = new Date();
. 最常用var date = new Date(); console.log(date); //Wed Mar 01 2023 16:54:34 GMT+0800 (中国标准时间)
-
一个符合以下格式的表示日期的字符串: "月 日, 年 时:分:秒." 例如:
var Xmas95 = new Date("December 25, 1995 13:30:00")。
如果你省略时、分、秒,那么他们的值将被设置为0。console.log(new Date("December 25, 1995 13:30:00")); //Mon Dec 25 1995 13:30:00 GMT+0800 (中国标准时间)
-
一个年,月,日的整型值的集合,例如:
var Xmas95 = new Date(1995, 11, 25)。
console.log(new Date(1995, 11, 25)); //Mon Dec 25 1995 00:00:00 GMT+0800 (中国标准时间)
-
一个年,月,日,时,分,秒的集合,例如:
var Xmas95 = new Date(1995, 11, 25, 9, 30, 0);
console.log(new Date(1995, 11, 25, 9, 30, 0)); //Mon Dec 25 1995 09:30:00 GMT+0800 (中国标准时间)
-
-
日期对象中的其他方法总体可以分成下面几类:
-
"set" 方法, 用于设置Date对象的日期和时间的值。
-
"get" 方法,用于获取Date对象的日期和时间的值。
-
"to" 方法,用于返回Date对象的字符串格式的值。
-
parse 方法, 将符合日期格式的字符串转成距离1970年1月1日的毫秒数
-
示例:打印当前系统的时间,格式: xxx年xx月xx日 HH:mm:ss 星期xx
<script>
function date() {
let time = new Date();
year = time.getFullYear(), //年
month = time.getMonth() + 1, //月份的范围是0~11,注意要 +1
date = time.getDate(), //日
hour = time.getHours(), //时
minutes = time.getMinutes(), //分
second = time.getSeconds() //秒
// 对不符合格式的字符串进行拼接
if (month < 10) {
month = "0" + month;
}
if (date < 10) {
date = "0" + date;
}
if (hour < 10) {
hour = "0" + hour;
}
if (minutes < 10) {
minutes = "0" + minutes;
}
if (second < 10) {
second = "0" + second;
}
console.log(year + "年" + month + "月" + date + "日 " + hour + ":" + month + ":" + second);
}
//调用函数
date();
</script>
4.2. 自定义函数
JavaScript 函数是通过 function 关键词定义的。
4.2.1. 使用函数声明的方式定义函数
function myFunction(a, b) {
return a * b;
}
//函数调用
var number = myFunction(2,3);
4.2.2. 使用函数表达式的方式定义函数(匿名函数)
匿名函数:就是没有函数名的函数。
var x = function (a, b) {
return a * b
};
//函数调用
var z = x(4, 3);
4.2.3. 函数参数
-
参数规则
-
JavaScript 函数定义不会为参数(parameter)规定数据类型。
-
JavaScript 函数不会对所传递的参数(argument)实行类型检查。
-
JavaScript 函数不会检查所接收参数(argument)的数量。
-
JavaScript 函数参数的默认值为 undefined。
-
-
arguments对象
JavaScript 函数有一个名为 arguments 对象的内置对象。arguments 对象包含函数调用时使用的参数数组。
这样,您就可以简单地使用函数来查找(例如)数字列表中的最高值:
function findMax() { var i; var max = -Infinity; // -Infinity:负无穷大 // 通过arguments遍历传进来的所有参数 for (i = 0; i < arguments.length; i++) { if (arguments[i] > max) { max = arguments[i]; } } return max; } console.log(findMax(1, 123, 500, 115, 44, 88));
4.3. 自调用函数
通过在正常定义的函数后面添加一对小括号可以定义一个自调用函数
// 不带参数的自调用函数
(function sayHello() {
console.log("大家好,我是John老师");
}());
// 带参数的自调用函数
(function sayHello(name) {
console.log("大家好,我是" + name + "老师");
}("Tony"));
console.log(
function jian(a, b) {
return a - b;
}(3, 2)
);
5. 内置对象
JavaScript中的内置对象分为两大类,一类是JavaScript中的标准内置对象,另一类是JavaScript浏览器API中特有的内置对象。
5.1. 浏览器API中的内置对象(Browser对象 BOM)
-
window (全局对象,每当 <body> 或 <frameset> 标签出现时,window 对象就会被自动创建)
-
Location (地址栏操作相关)
-
History (浏览历史操作相关,如:前进、后退等)
-
Screen (获取屏幕相关参数)
-
Navigator (Navigator 对象包含有关浏览器的信息)
-
示例
//windows var age = 34; console.log(window.age); //window.alert("你好!"); //alert("你好!"); //window可以省略不写 //location //location.href="http://www.jd.com"; //打开页面直接跳转到京东首页 //history //history.back(); //后退 //history.forward();//前进 //screen console.log(screen.availWidth); // 屏幕宽度 console.log(screen.availHeight); //屏幕高度 //Navigator 根据 W3C HTML 5 的规范,navigator 对象的 appName 要么返回 Netscape,要么返回浏览器的全名,这是为了兼容性而考虑的! console.log(navigator.appName);
5.2. 标准内置对象(JavaScript 本地对象和内置对象)
-
Array
-
Number
-
String
-
Date
-
Math
...
5.3创建自定义对象
在JavaScript中我们可以通过以下三种方式创建自定义对象
-
使用对象初始化器
let stu1 = {sname: "张三", age: 21, sex:"男"};
-
使用构造函数
function Student(sname, age, sex) { this.sname = sname; this.age = age; this.sex = sex; } // 构造函数定义对象支持通过prototype属性扩展对象功能(是在对象原型上扩展功能,类似与Java中的类,所以后续通过该构造函数创建出的对象都带有扩展的功能) Student.prototype.say = function() { console.log("Hi, I'm " + this.sname + "!"); } let stu2 = new Student("李四", 23, "女"); console.log(stu2.sname); // 李四 stu2.say(); // Hi, I'm 李四!
-
使用Object.create方法
// 创建一个空对象,然后给对象添加属性值 let obj = Object.create(null); obj.tname = "John"; obj.addr = "河南"; console.log(obj); // Object { tname: "John", addr: "河南" } // 定义一个有属性的对象 let Teacher = { tname: "John", // 定义Teacher类tname属性,并赋默认初值 teach: function(){ // 定义Teacher类teach方法 console.log("The Teacher "+this.tname+" is teaching Java..."); } }; // 基于Teacher对象作为模板创建对象,创建的对象会自动继承Teacher对象的属性 let john = Object.create(Teacher); console.log(john.tname); john.teach(); // 基于Teacher对象作为模板创建对象,然后覆盖Teacher中默认的属性值 let tony = Object.create(Teacher); tony.tname = "Tony"; console.log(tony.tname); tony.teach();