学习目标
-
了解什么是对象,能够说出JavaScript中的对象的概念
-
掌握对象的创建方式,能够使用3种方式创建对象
-
掌握对象的遍历,能够遍历对象的属性和方法
-
熟悉值类型和引用类型,能够说出值类型和引用类型的特点
-
掌握Math对象的使用,能够使用Math对象的常用方法和属性实现数学运算
-
掌握Date对象的创建,能够使用构造函数创建Date对象
-
掌握Date对象的使用,能够使用Date对象的常用方法处理日期和时间
-
掌握Array对象的使用,能够使用Array对象的常用方法对数组进行操作
-
掌握数组类型检测的两种常用方式,能够使用两种方式检测变量的类型是否为数组
-
掌握String对象的使用,能够使用String对象的常用方法处理字符串
-
掌握MDN Web文档的查阅方式,能够在MDN Web文档中查询对象
在日常开发中,经常需要对数组、日期或者字符串进行一些操作,例如对数组元素进行排序,虽然我们可以使用插入排序或者冒泡排序来完成,但是这两种排序方式实现起来都比较麻烦。为了提高开发效率,JavaScript提供了一些常用的内置对象,可以帮助我们快速实现程序的某些功能。例如,5.7.1小节会讲到如何用内置对象Array的sort()方法完成数组元素排序,sort()方法会帮我们完成数组元素排序,我们只需调用该方法即可,所以开发效率高。当内置对象无法满足开发需求时,还可以通过自定义对象来实现程序的功能。本章将针对JavaScript中的对象进行详细讲解。
5.1 初识对象
在现实生活中,对象是一个具体的实物,是一种看得见、摸得着的东西。例如,一部手机、一辆汽车、一个学生,都可以看成是“对象”。
如何区分对象呢?
我们可以通过描述对象的特征来区分对象,例如通过描述学生的性别、姓名和年龄来区分学生对象。
如何在程序中描述一个对象的特征?
大家可能会想到,通过定义多个变量来描述,以学生对象为例:
定义变量name来描述学生的姓名。 定义变量age来描述学生的年龄。 定义变量sex来描述学生的性别等。
但是,当需要描述多个学生时,如果每个学生的姓名、年龄和性别都通过变量来描述,会使程序出现大量的变量,导致程序难以维护。
此时,我们可以通过JavaScript中的对象(一种数据类型)来描述学生,将学生的特征保存在对象中。
在JavaScript中,对象属于复杂数据类型,它是由属性和方法组成的一个集合。
属性是指对象的特征。 方法是指对象的行为。
下面以学生的特征和行为为例进行说明。
学生的特征:姓名、年龄和性别,这些特征可以用对象的属性来表示。 学生的行为:打招呼、唱歌、写作业,这些行为可以用对象的方法来表示。
5.2 对象的创建
5.2.1 利用字面量创建对象
在JavaScript中,使用对象的字面量创建对象,就是用大括号“{}”来标注对象成员,每个对象成员使用键值对的形式保存,即 “key: value”的形式。
对象字面量的语法格式如下。
当对象不需要成员时,键值对可以省略,此时表示空对象。
演示如何使用字面量创建对象,示例代码如下。
// 创建一个空对象
var obj = {};
// 创建一个学生对象
var stu1 = {
name: '小明', // name属性
age: 18, // age属性
sex: '男', // sex属性
sayHello: function () { // sayHello()方法
console.log('Hello');
}
};
使用对象成员的两种方式如下。
如果对象的成员名中包含特殊字符,则可以用字符串来表示成员名,通过“[]”来访问,示例代码如下 。
添加对象成员:对象创建完成后,用户可以通过为属性或方法赋值的方式来添加对象成员。
var obj = {};
obj.name = 'Jack'; // 为对象添加name属性
obj['age'] = 18; // 为对象添加age属性
obj.sayHello = function () { console.log('Hello');}; // 为对象添加sayHello()方法
// 为对象添加sing()方法
obj['sing'] = function () { console.log('大海'); };
console.log(obj.name); // 访问name属性,输出结果:Jack
console.log(obj.age); // 访问age属性,输出结果:18
obj.sayHello(); // 调用sayHello()方法,输出结果:Hello
obj.sing(); // 调用sing()方法,输出结果:大海
如果访问对象中不存在的成员时,会返回undefined,示例代码如下。
var obj = {}; // 创建一个空对象
console.log(obj.name); // 输出结果:undefined
5.2.2 利用构造函数创建对象
在开发中,如果需要创建一个班级中所有的学生对象时,我们可以把学生看成一类对象,将学生拥有的共同特征和行为写在构造函数中,然后通过构造函数创建这些学生对象。
怎么理解构造函数?
所谓构造函数,就是一个提供生成对象的模板并描述对象基本结构的函数,主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值。
通过一个构造函数可以创建多个对象,这些对象都有相同的结构。利用构造函数创建对象的过程称为实例化,利用构造函数创建出来的对象称为构造函数的实例对象。
定义构造函数的语法和定义普通函数的语法类似,与普通函数的区别是,构造函数的名称 推荐首字符大写。
定义构造函数的语法格式如下。
在构造函数的函数体中可以为新创建的对象添加成员,其语法格式如下 。
定义构造函数后,使用构造函数创建对象的语法格式如下。
var 变量名 = new 构造函数名([参数1, 参数2, …]);
当不需要传入参数时,参数可以省略,且小括号“()”也可以省略。
在JavaScript中,构造函数本身也是对象,所以构造函数也有成员。
为了区分构造函数的成员和实例对象的成员,我们将构造函数的成员称为静态成员,将实例对象的成员称为实例成员。
代码演示静态成员和实例成员的区别。
function Person(name)
// 添加实例成员:name属性和say()方法
this.name = name;
this.say = function () {console.log('Hello'); };
}
// 添加静态成员:class属性和run()方法
Person.class = '102班';
Person.run = function () {console.log('run');};
// 使用静态成员
console.log(Person.class); // 输出结果:102班
Person.run(); // 输出结果:run
// 使用实例成员
var p1 = new Person('小明');
console.log(p1.name); // 输出结果:小明
p1.say(); // 输出结果:Hello
5.2.3 利用Object()创建对象
Object()是对象的构造函数,它可以用来创建对象。
使用Object()构造函数创建obj对象,其语法格式如下 。
var obj = new Object(); // 创建了一个空对象
obj.name = '小明'; // 创建对象后,为对象添加属性
obj.age = 18; // 创建对象后,为对象添加属性
obj.sayHello = function () { // 创建对象后,为对象添加方法
console.log('Hello');
};
5.3 对象的遍历
在开发中,有时需要查询一个对象拥有哪些属性和方法,这时就需要进行对象的遍历。
对象的遍历是指遍历对象中所有的成员。
使用for…in语法可以进行对象的遍历,其语法格式如下。
我们可以使用in运算符,判断一个对象中的某个成员是否存在,判断的结果为true表示存在,为false表示不存在。
var obj = { name: 'Tom', age: 16 };
console.log('age' in obj); // 输出结果:true
console.log('gender' in obj); // 输出结果:false
5.4 值类型和引用类型
值类型和引用类型的区别:
当值类型的数据被赋值给变量或作为函数的参数传递时,是将具体的值保存给了变量或参数。
当引用类型的数据被赋值给变量或作为函数的参数传递时,数据本身只有一份,变量或参数中保存的是对数据的引用。
下面通过代码进行演示值类型和引用类型的区别。
// 值类型
var a = 10;
var b = a;
a++;
console.log(b); // 输出结果:10
// 引用类型
var obj = { a: 10 };
var obj1 = obj;
obj.a++;
console.log(obj1.a); // 输出结果:11
变量obj和变量obj1的关系如图所示。
当两个变量引用同一个对象后,如果给其中一个变量重新赋值为其他对象,或者重新赋值为其他值,则该变量将不再引用原来的对象,但另一个变量仍然引用原来的对象,示例代码如下。
var obj = { a: 10 };
var obj1 = obj;
// obj重新引用一个新创建的对象
obj = { age: 15 };
// obj1仍然引用原来的对象
console.log(obj1.a); // 输出结果:10
当对象作为函数的参数来传递时,如果在函数的参数中修改对象的属性或方法,则在函数外面被引用的对象也会同步修改,因为它们操作的是同一个对象,示例代码如下。
function change(obj1) {
obj1.a = 15; // 在函数内修改了对象的属性
}
var obj = { a: 10 };
change(obj);
console.log(obj.a); // 输出结果:15
5.5 Math对象
5.5.1 Math对象的使用
Math对象表示数学对象,用来进行与数学相关的运算。Math对象的常用属性和方法如下。
属性和方法 | 作用 |
---|---|
PI | 获取圆周率,结果为3.141592653589793 |
abs(x) | 获取x的绝对值 |
max([value1[,value2, ...]]) | 获取所有参数中的最大值 |
min([value1[,value2, ...]]) | 获取所有参数中的最小值 |
pow(base, exponent) | 获取基数(base)的指数(exponent)次幂,即 baseexponent |
sqrt(x) | 获取x的平方根,若x为负数,则返回NaN |
ceil(x) | 获取大于或等于x的最小整数,即向上取整 |
floor(x) | |
获取小于或等于x的最大整数,即向下取整 | |
round(x) | 获取x的四舍五入后的整数值 |
random() | 获取大于或等于0且小于1的随机值 |
(1)利用PI获取圆周率,并计算半径为3的圆的周长。
console.log(2 * Math.PI * 3); // 输出结果:18.84955592153876
(2)利用abs()方法计算数字-25的绝对值。
console.log(Math.abs(-25)); // 输出结果:25
(3)利用max()方法和min()方法实现计算一组数“5、3、11、6”的最大值和最小值。
console.log(Math.max(5, 3, 11, 6)); // 输出结果:11
console.log(Math.min(5, 3, 11, 6)); // 输出结果:3
(4)利用pow()方法实现计算2的4次幂,然后利用sqrt()方法对其结果求平方根。
var a = Math.pow(2, 4);
console.log(a); // 输出结果:16
console.log(Math.sqrt(a)); // 输出结果:4
(5)利用ceil()方法实现计算大于或等于1.1和1.9的最小整数,利用floor()方法实现计算小于或等于1.1和1.9的最大整数。
console.log(Math.ceil(1.1)); // 输出结果:2
console.log(Math.ceil(1.9)); // 输出结果:2
console.log(Math.floor(1.1)); // 输出结果:1
console.log(Math.floor(1.9)); // 输出结果:1
(6)利用round()方法实现计算数字1.1、1.5、1.9、-1.5和-1.6四舍五入后的整数值。
console.log(Math.round(1.1)); // 输出结果:1
console.log(Math.round(1.5)); // 输出结果:2
console.log(Math.round(1.9)); // 输出结果:2
console.log(Math.round(-1.5)); // 输出结果:-1(取较大值)
console.log(Math.round(-1.6)); // 输出结果:-2
(7)利用random()方法生成一个大于等于0且小于1的随机数。
console.log(Math.random()); // 输出结果:0.925045617789475
生成指定范围内的随机数:
Math.random() * (n - m) + m; // 生成m~n(不包括n)的随机数
Math.floor(Math.random() * (n - m + 1) + m); // 生成m~n的随机整数
Math.floor(Math.random() * (n + 1)); // 生成0~n的随机整数
Math.floor(Math.random() * n + 1); // 生成1~n的随机整数
5.5.2 【案例】猜数字游戏
班级内开展活动日,老师提出了猜数字游戏,游戏的规则如下。
老师随机抽取一个1~10的数字,同学们来猜这个数字。
如果同学们猜的数字比老师抽取的数字大,则提示猜大了;
如果同学们猜的数字比老师抽取的数字小,则提示猜小了;
如果同学们猜的数字与老师抽取的数字相同,则提示猜对了。
猜数字游戏,案例的实现思路如下。
首先定义getRandom()函数实现随机生成一个1~10的数字。 然后利用循环结构实现让程序一直执行,在程序中接收同学们输入的数字,判断输入的数字和随机整数的大小。 如果输入的数字大于随机数,则程序提示“你猜大了” 。 如果输入的数字小于随机数,则程序提示“你猜小了”。 如果两个数字相等,就提示“恭喜你,猜对了”。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
var random = getRandom(1, 10);
while (true) { // 死循环,利用break来跳出循环
var num = prompt('请输入一个1~10的整数:');
if (num === null) {
break;
} else if (num > random) {
alert('你猜大了');
} else if (num < random) {
alert('你猜小了');
} else {
alert('恭喜你,猜对了');
break;
}
}
</script>
</body>
</html>
5.6 Date对象
5.6.1 Date对象的创建
JavaScript中的Date对象表示日期对象,需要使用Date()构造函数创建后才能使用。Date()构造函数的3种使用形式如下。
构造函数不传入参数,表示使用系统当前时间。
var date1 = new Date();
// 输出结果:Fri Aug 13 2021 10:30:45 GMT+0800 (中国标准时间)
console.log(date1);
构造函数传入数字型参数,规则如下:
当传入以数字表示的年、月、日、时、分、秒时,最少需要指定年、月两个参数,后面的参数若省略会自动使用默认值,且月的取值范围是0~11,0表示1月,1表示2月,以此类推。
当传入的数字大于合理范围时,会自动转换成相邻数字,将月份设为-1表示去年12月,设为12表示明年1月。
构造函数传入数字型参数的示例代码如下。
var date2 = new Date(2021, 7, 14, 10, 30, 45);
// 输出结果:Sat Aug 14 2021 10:30:45 GMT+0800 (中国标准时间)
console.log(date2);
构造函数传入字符串型参数。当传入以字符串表示的日期和时间时最少需要指定年份,需要注意的是,日期和时间的格式有多种,这里以“年-月-日 时:分:秒”格式为例。
为Date()构造函数传入字符串型参数的示例代码如下。
var date3 = new Date('2021-08-15 10:30:45');
// 输出结果:Sun Aug 15 2021 10:30:45 GMT+0800 (中国标准时间)
console.log(date3);
5.6.2 Date对象的使用
创建Date对象后,对象中存放的是一个以字符串表示的日期和时间。如果想要单独获取或设置年、月、日、时、分、秒中的某一项,可以通过调用Date对象的相关方法来实现。
获取日期和时间的方法如下。
方法 | 作用 |
---|---|
getFullYear() | 获取表示年份的4位数字,如2021 |
getMonth() | 获取月份,范围0~11(0表示1月,1表示2月,依次类推) |
getDate() | 获取月份中的某一天,范围1~31 |
getDay() | 获取星期,范围0~6(0表示星期日,1表示星期一,依次类推) |
getHours() | 获取小时数,返回0~23 |
getMinutes() | 获取分钟数,范围0~59 |
getSeconds() | 获取秒数,范围0~59 |
getMilliseconds() | 获取毫秒数,范围0~999 |
getTime() | 获取从1970-01-01 00:00:00到Date对象中存放的时间的毫秒数 |
设置日期和时间的方法如下。
方法 | 作用 |
---|---|
setFullYear(value) | 设置年份 |
setMonth(value) | 设置月份 |
setDate(value) | 设置月份中的某一天 |
setHours(value) | 设置小时数 |
setMinutes(value) | 设置分钟数 |
setSeconds(value) | 设置秒数 |
setMilliseconds(value) | 设置毫秒数 |
setTime(value) | 通过从1970-01-01 00:00:00开始计时的毫秒数来设置时间 |
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
var date = new Date();
// 设置年、月、日
date.setFullYear(2022);
date.setMonth(7 - 1);
date.setDate(1);
// 获取年、月、日
var year = date.getFullYear();
var month = date.getMonth();
var day = date.getDate();
// 输出结果
console.log(year + '年' + (month + 1) + '月' + day + '日');
</script>
</body>
</html>
5.6.3 【案例】时间差计算
我们在网上购物时,经常会看到商家推出一些抢购活动,网页上会显示活动开始时间的倒计时,如“距离活动开始还有39天19时02分11秒”,其中,“39天19时02分11秒”是一个时间差。
时间差计算,案例的实现思路如下。
定义一个函数,用于计算时间差,该函数的参数表示活动开始时间,在函数内获取当前时间,并计算当前时间到活动开始时间还有多长时间,以“x天x时x分x秒”的格式返回计算结果。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
function countDown(time) {
var nowTime = new Date();
var overTime = new Date(time);
var times = (overTime - nowTime) / 1000;
var d = parseInt(times / 60 / 60 / 24); // 天数
d = d < 10 ? '0' + d : d;
var h = parseInt(times / 60 / 60 % 24); // 小时
h = h < 10 ? '0' + h : h;
var m = parseInt(times / 60 % 60); // 分钟
m = m < 10 ? '0' + m : m;
var s = parseInt(times % 60); // 秒数
s = s < 10 ? '0' + s : s;
return d + '天' + h + '时' + m + '分' + s + '秒';
}
console.log(countDown('2021-9-25 09:00:00'));
</script>
</body>
</html>
5.7 Array对象
5.7.1 Array对象的使用
JavaScript中,Array 对象用于在单个变量中存储多个值。
Array对象提供了一些常用方法如下。
添加或删除数组元素的方法 改变数组元素顺序的方法 获取数组元素索引的方法 将数组转为字符串的方法
添加或删除数组元素的方法
方法 | 作用 |
---|---|
push(element1, ...) | 数组末尾添加一个或多个元素,会修改原数组,返回值为数组的新长度 |
unshift(element1, ...) | 数组开头添加一个或多个元素,会修改原数组,返回值为数组的新长度 |
pop() | 删除数组的最后一个元素,会修改原数组,若是空数组则返回undefined,返回值为删除的元素 |
shift() | 删除数组的第一个元素,会修改原数组,若是空数组则返回undefined,会修改原数组,返回值为删除的元素 |
splice(start[, deleteCount[, item1[, ...]]]) | 从指定索引删除或添加数组元素,会修改原数组,返回值是一个由被删除的元素组成的新数组 |
使用push()方法和unshift()方法在数组中添加元素,然后再使用pop()方法和shift()方法 删除元素。
var arr = ['星期一', '星期二', '星期三', '星期四', '星期五'];
console.log(arr.push('星期六')); // 输出结果:6
console.log(arr.unshift('星期日')); // 输出结果:7
console.log(arr.pop()); // 输出结果:星期六
console.log(arr.shift()); // 输出结果:星期日
使用splice()方法在数组的指定索引处添加或删除数组元素。
var arr = ['sky', 'wind', 'snow', 'sun'];
arr.splice(2, 2);
console.log(arr); // 输出结果:(2) ['sky', 'wind']
arr.splice(1, 1, 'snow');
console.log(arr); // 输出结果:(2) ['sky', 'snow']
arr.splice(1, 0, 'hail', 'sun');
console.log(arr); // 输出结果:(4) ['sky', 'hail', 'sun', 'snow']
改变数组元素顺序的方法
方法 | 作用 |
---|---|
reverse() | 颠倒数组中元素的索引,该方法会改变原数组,返回新数组 |
sort([compareFunction]) | 对数组的元素进行排序,返回新数组。compareFunction为可选参数,是指定元素按某种顺序进行排列的函数 |
sort()方法的解释说明如下。
sort()方法没有传参数时是将元素转换为字符串,然后根据各个字符的Unicode代码点进行排序。
为sort()方法传入compareFunction参数,可以实现元素按某种顺序排列。该参数是一个函数,会被sort()方法多次调用,每次调用时选取数组中的两个元素进行排序,直到整个数组排序完成。
通过compareFunction参数传入的函数,其语法格式如下。
function (参数1, 参数2) {
return 值;
}
参数1和参数2由sort()方法传入,表示数组中待排序的两个元素,函数的返回值决定了两个元素的排列顺序。
元素排列顺序,具体规则如下。
返回值是正数,第2个元素会被排列到第1个元素之前。
返回值是0,两个元素的顺序不变。
返回值是负数,第1个元素会被排列到第2个元素之前。
实现升序排序,思路如下。
要保证在第1个元素大于第2个元素的情况下,函数的返回值是正数。
两个元素相等的情况下,函数的返回值是0;
第1个元素小于第2个元素的情况下,函数的返回值是负数。
为了实现这个效果,可以在函数中使用return关键字返回参数1减参数2的结果。
实现降序排序,思路如下。
实现降序排序,要要保证在第2个元素大于第1个元素的情况下,函数的返回值是正数。
两个元素相等的情况下,函数的返回值是0;
第2个元素小于第1个元素的情况下,函数的返回值是负数。
为了实现这个效果,可以在函数中使用return关键字返回参数2减参数1的结果。
使用reverse()方法反转数组,示例代码如下。
// 反转数组
var arr = [10, 2, 18, 4];
arr.reverse();
console.log(arr); // 输出结果:(4) [4, 18, 2, 10]
使用sort()方法实现数组的升序和降序,示例代码如下。
// 升序排序
arr.sort(function (a, b) {
return a - b;
});
console.log(arr); // 输出结果:(4) [2, 4, 10, 18]
// 降序排序
arr.sort(function (a, b) {
return b - a;
});
console.log(arr); // 输出结果:(4) [18, 10, 4, 2]
获取数组索引的方法
方法 | 作用 |
---|---|
indexOf(searchElement[, fromIndex]) | 返回指定元素在数组中第一次出现的索引,如果不存在则返回-1 |
lastIndexOf(searchElement[, fromIndex]) | 返回指定元素在数组中的最后一次出现的索引,如果不存在则返回-1 |
参数解释: searchElement参数表示要查找的元素。 fromIndex参数为可选参数,表示从指定索引开始查找。
indexOf()方法和lastIndexOf()方法说明如下。
lastIndexOf()是逆向查找,也就是从后向前查找,当第一次找到元素时就返回其索引,此时找到的元素刚好是数组中最后一次出现的元素。
使用indexOf()方法和lastIndexOf()方法查找元素索引时,只有要查找的元素值与数组元素值全等时才查找成功。
通过代码演示indexOf()方法和lastIndexOf()方法的使用,示例代码如下。
var arr = ['red', 'green', 'blue', 'pink', 'blue'];
console.log(arr.indexOf('blue')); // 输出结果:2
console.log(arr.lastIndexOf('blue')); // 输出结果:4
将数组转为字符串的方法
方法 | 作用 |
---|---|
toString() | 把数组转换为字符串,逗号分隔数组中的每个元素 |
join([separator]) | 将数组的所有元素连接成一个字符串,默认使用逗号分隔数组中的每个元素。separator参数为可选参数,用于指定字符串的分隔符 |
当数组元素为undefined、null或空数组时,对应的元素会被转换为空字符串。
下面进行代码演示。创建数组arr,分别使用toString()和join()方法实现将数组arr转为字符串。
// 使用toString()
var arr = ['a', 'b', 'c'];
console.log(arr.toString()); // 输出结果:a,b,c
// 使用join()
console.log(arr.join()); // 输出结果:a,b,c
console.log(arr.join('')); // 输出结果:abc
console.log(arr.join('-')); // 输出结果:a-b-c
其他方法
方法 | 作用 |
---|---|
fill(value[, start[, end]) | 用一个固定值填充数组中从起始索引到终止索引内的全部元素,不包括终止索引。返回填充后的数组。value表示要填充的数组元素值,start和end为可选参数,分别表示填充的起始索引和终止索引 |
slice([begin[, end]) | 数组截取,返回被截取元素的新数组。begin和end为可选参数,表示截取的起始索引和终止索引,截取的结果不包含终止索引的值 |
concat(value1[, value2[, ...[, valueN]]) | 连接两个或多个数组,或者将值添加到数组中,不影响原数组,返回一个新数组,value为数组或值 |
下面通过代码演示fill()方法、slice()方法和concat()方法的使用。
// fill()的使用
console.log([0, 1, 2].fill(4)); // 输出结果:(3) [4, 4, 4]
console.log([0, 1, 2].fill(4, 1)); // 输出结果:(3) [0, 4, 4]
console.log([0, 1, 2].fill(4, 1, 2)); // 输出结果:(3) [0, 4, 2]
// slice()的使用
console.log([0, 1, 2].slice()); // 输出结果:(3) [0, 1, 2]
console.log([0, 1, 2].slice(1)); // 输出结果:(2) [1, 2]
console.log([0, 1, 2].slice(1, 2)); // 输出结果:[1]
// concat()的使用
console.log([0, 1, 2].concat(3)); // 输出结果:(4) [0, 1, 2, 3]
console.log([0, 1, 2].concat([3, 4])); // 输出结果:(5) [0, 1, 2, 3, 4]
5.7.2 数组类型检测
在开发中,有时候需要检测变量的类型是否为数组。例如,在函数中,要求传入的参数必须是一个数组,不能传入其他类型的值,否则会出错,所以这时候可以在函数中检测参数的类型是否为数组。
数组类型检测有两种常用的方式,分别是使用instanceof运算符和使用Array.isArray()方法,示例代码如下。
var arr = [];
var obj = {};
// 第1种方式
console.log(arr instanceof Array); // 输出结果:true
console.log(obj instanceof Array); // 输出结果:false
// 第2种方式
console.log(Array.isArray(arr)); // 输出结果:true
console.log(Array.isArray(obj)); // 输出结果:false
5.7.3 【案例】统计不及格学生的人数
期末考试结束后,老师需要统计成绩不及格的学生人数来检验这一阶段自己的教学质量以及学生的吸收程度,并且通过成绩来帮助同学们分析不及格的原因。
首先将所有学生的成绩保存到数组中。然后对数组中的每个成绩进行判断,如果成绩低于60分,就将成绩放到一个新的数组中。最后计算新数组的长度实现统计不及格人数。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
var score = [59, 66, 64, 80, 78, 90, 55, 37, 60, 52];
var failScore = []; // 创建用于保存不及格成绩的数组
for (var i = 0; i < score.length; i++) {
if (score[i] < 60) { // 判断成绩是否及格
failScore.push(score[i]); // 将不及格的成绩放到failScore
}
}
console.log(failScore);
console.log('不及格的人数为:' + failScore.length);
</script>
</body>
</html>
5.7.4 【案例】去除重复的比赛项目
学校即将组织秋季运动会,比赛项目根据各个班提交的项目来决定,但是每个班提交的比赛项目可能会重复,本案例将实现去除重复的比赛项目。
首先将每个班提交的比赛项目全部放到一个数组中。
然后定义去重函数,该函数接收需要去重的数组,通过遍历数组的方式找出不重复的比赛项目,将不重复的比赛项目保存到新数组中。
最后返回新数组。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
var arr = ['短跑', '接力', '短跑', '拔河', '跳绳', '接力', '拔河', '跳远'];
function unique(arr) {
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (newArr.indexOf(arr[i]) === -1) {
newArr.push(arr[i]);
}
}
return newArr;
}
console.log(unique(arr));
</script>
</body>
</html>
5.8 String对象
5.8.1 String对象的创建
JavaScript中,String对象表示字符串对象,使用String()构造函数来创建。在String()构造函数中传入字符串,就会在创建出来的String对象中保存传入的字符串,示例代码如下。
var str = new String('apple'); // 创建String对象
console.log(str); // 输出结果:String {"apple"}
字符串类型的变量和String对象有什么区别呢?
字符串类型的变量也可以像String对象一样访问属性和方法,但是字符串类型的变量并不是一个对象,它只是一个字符串类型的数据。
通过代码演示字符串变量和String对象的区别,示例代码如下。
var str = 'apple';
var str1 = new String('apple');
console.log(str.length); // 输出结果:5
console.log(str1.length); // 输出结果:5
console.log(typeof (str)); // 输出结果:string
console.log(typeof (str1)); // 输出结果:object
5.8.2 String对象的使用
String对象提供了一些常用的方法用于对字符串进行处理,如根据字符串返回索引的方法、根据索引返回字符的方法以及字符串截取、连接、替换和大小写转换的方法。
根据字符串返回索引的方法
方法 | 作用 |
---|---|
indexOf(searchValue[, fromIndex]) | 获取searchValue在字符串中首次出现的索引,如果找不到则返回-1。可选参数fromIndex表示从指定索引开始向后搜索,默认为0 |
lastIndexOf(searchValue[, fromIndex]) | 获取searchValue在字符串中最后出现的索引,如果找不到则返回-1。可选参数fromIndex表示从指定索引开始向前搜索,默认为最后一个元素的索引 |
通过代码演示indexOf()方法和lastIndexOf()方法的使用。
查找字符串'HelloWorld'中,'o'首次出现的索引和最后出现的索引,示例代码如下。
var str = 'HelloWorld';
str.indexOf('o'); // 获取'o'在字符串中首次出现的索引,返回结果:4
str.lastIndexOf('o'); // 获取'o'在字符串中最后出现的索引,返回结果:6
根据索引返回字符串的方法
方法 | 作用 |
---|---|
charAt(index) | 获取index索引的字符,字符串第1个字符的索引为0 |
charCodeAt(index) | 获取index索引的字符的ASCII码 |
通过代码演示charAt()方法和charCodeAt()方法的使用。
查找字符串'Apple'中索引为2的字符,以及索引为0的字符的ASCII码,示例代码如下。
var str = 'Apple';
console.log(str.charAt(2); // 输出结果:p
console.log(str.charCodeAt(0)); // 输出结果:65(字符A的ASCII码为65)
字符串截取、连接、替换和大小写转换的方法
方法 | 作用 |
---|---|
concat(str1[, str2, str3…]) | 连接一个或多个字符串 |
slice(start[, end]) | 截取从起始(start)索引到终止(end)索引之间的1个子字符串,若省略end则表示从起始(start)索引开始截取到字符串末尾 |
substring(start[, end]) | 截取从起始(start)索引到终止(end)索引之间的1个子字符串,基本和slice相同,但是不接收负值 |
substr(start[, length]) | 截取从起始(start)索引开始到length长度的子字符串,若省略length则表示从起始(start)索引开始截取到字符串末尾 |
toLowerCase() | 获取字符串的小写形式 |
toUpperCase() | 获取字符串的大写形式 |
split([separator[, limit]) | 使用separator(分割符)将字符串分割成数组,limit用于限制数量 |
replace(str1, str2) | 使用str2替换字符串中的str1,返回替换结果,只会替换第一次出现的str1 |
使用concat()方法连接字符串'Hello'和'World',示例代码如下。
var str = 'Hello';
var str1 = 'World';
console.log(str.concat(str1)); // 输出结果:HelloWorld
分别使用slice()、substring()以及substr()方法从字符串'HelloWorld'中截取出字符串'el'和'World',示例代码如下。
var str = 'HelloWorld';
// 利用slice()方法实现
console.log(str.slice(1, 3)); // 输出结果:el
console.log(str.slice(5)); // 输出结果:World
// 利用substring()方法实现
console.log(str.substring(1, 3)); // 输出结果:el
console.log(str.substring(5)); // 输出结果:World
// 利用substr()方法实现
console.log(str.substr(1, 2)); // 输出结果:el
console.log(str.substr(5)); // 输出结果:World
使用toLowerCase()和toUpperCase()方法将字符串'HelloWorld'转成小写形式和大写形式,示例代码如下。
var str = 'HelloWorld';
console.log(str.toLowerCase()); // 输出结果:helloworld
console.log(str.toUpperCase()); // 输出结果:HELLOWORLD
使用split()方法将字符串'HelloWorld'以字符'l'切割,示例代码如下。
var str = 'HelloWorld';
console.log(str.split('l')); // 输出结果:(4) ["He", "", "oWor", "d"]
console.log(str.split('l', 3)); // 输出结果:(3) ["He", "", "oWor"]
使用replace()方法将字符串'RainyDay and SunnyDay'中的第1个'Day'替换成'天',示例代码如下。
var str = 'RainyDay and SunnyDay';
console.log(str.replace('Day', '天')); // 输出结果:Rainy天 and SunnyDay
5.8.3 【案例】判断用户名是否合法
在开发用户注册和登录功能时,经常需要对用户输入的用户名进行格式验证。本案例要求用户名长度在3~10范围内,不允许出现敏感词admin的任何大小写形式。
首先接收用户输入的用户名。 然后利用选择结构语句判断用户输入的用户名是否合法,其中判断用户名是否为敏感词的任何大小写形式时,可以先将用户名全部转换为大写形式或小写形式再进一步判断。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
var username = prompt('请输入用户名');
if (username.length < 3 || username.length > 10) {
alert('用户名长度必须在3~10范围内');
} else if (username.toLowerCase().indexOf('admin') !== -1) {
alert('用户名中不能包含敏感词:admin');
} else {
alert('恭喜您,该用户名可以使用');
}
</script>
</body>
</html>
5.9 查阅MDN Web文档
该如何查询所需内置对象的使用方法呢?
在日常开发中,若需要使用其他内置对象,可以在MDN Web 文档中查询所需内置对象的使用方法。
在MDN Web 文档中查询内置对象有两种方式。
通过链接查找内置对象
MDN Web 文档提供了所有内置对象的链接,通过单击某个内置对象的链接即可进入到某个内置对象的页面下进行查看, 具体步骤如下。
打开MDN Web文档网站,在网站的导航栏中单击“Technologies”-“JavaScript”,如下图所示。
(JavaScript 基础 - 学习 Web 开发 | MDNJavaScript 是一门编程语言,可为网站添加交互功能(例如:游戏、动态样式、动画以及在按下按钮或收到表单数据时做出的响应等)。本文介绍了 JavaScript 的精彩之处和主要用途。https://developer.mozilla.org/zh-CN/docs/Learn/Getting_started_with_the_web/JavaScript_basics )
JavaScript 基础 - 学习 Web 开发 | MDN
5.10 动手实践:统计出现次数最多的字符
掌握动手实践:统计出现次数最多的字符的实现方法,能够找到出现次数最多的字符并统计出现的次数
定义一个变量用于接收用户的输入。
利用循环实现统计每个字符出现的次数,将结果存入对象。
利用对象的遍历找到出现次数最多的字符,在页面中弹出警告框提示用户出现次数最多的字符以及该字符出现的次数。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
var str = prompt('请输入字符串:');
// 统计每个字符的出现次数
var o = {};
for (var i = 0; i < str.length; i++) {
var chars = str.charAt(i); // 利用chars保存字符串中的每一个字符
if (o[chars]) { // 利用对象的属性来方便查找元素
o[chars]++;
} else {
o[chars] = 1;
}
}
var max = 0; // 保存出现次数最大值
var ch = ''; // 保存出现次数最多的字符
// 遍历对象
for (var k in o) {
if (o[k] > max) {
max = o[k];
ch = k;
}
}
alert('出现次数最多的字符是:' + ch + ',共出现了' + max + '次')
</script>
</body>
</html>
本章小结
本章首先讲解了什么是对象,然后讲解了对象的创建、对象的遍历、值类型和引用类型以及Math对象、Date对象、Array对象、String对象,最后讲解了如何查阅MDN Web文档。学习完本章后,希望读者能够利用JavaScript中的对象来完成实际开发中的需求。