在JavaScript中,对象是一种数据类型,它是由属性和方法组成的一个集合。属性是指事物的特征,使用“对象.属性名”访问;方法是指事物的行为,使用“对象.方法名()”进行访问。
//手机对象p1
var p1 = {
color: '黑色',
weight: '188g',
screenSize: '6.5',
call: function(num) { console.log('打电话给' + num);},
sendMessage: function(num, message) {},
playVideo: function() { console.log('播放视频'); },
playMusic: function() { console.log('播放音乐'); }
}
//访问p1的属性和方法
console.log(p1.color);
console.log(p1.weight);
console.log(p1.screenSize);
p1.call('123');
p1.sendMessage('123', 'hello');
p1.playVideo();
p1.playMusic();
对象的字面量就是用花括号“{ }”来包裹对象中的成员,每个成员使用 “key: value” 的形式来保存,key表示属性名或方法名,value表示对应的值。多个对象成员之间用“,”隔开。
//创建一个学生对象
var stu1 = {
name: '小明', // name属性
age: 18, // age属性
sex: '男', // sex属性
// sayHello方法
sayHello: function() { console.log('Hello'); } };
创建好学生对象之后,接下来访问该对象的属性和方法:
stu1.name // 方式1,输出结果为:小明
stu1['age'] // 方式2,输出结果为:18
stu1.sayHello() // 方式1,输出结果为:Hello
stu1.['sayHello']() // 方式2,输出结果为:Hello
var obj = {
'name-age': '小明-18'
};
console.log(obj['name-age']); // 输出结果:“小明-18”
手动赋值属性或方法来添加成员:
var stu2 = {}; // 创建一个空对象
stu2.name = 'Jack'; // 为对象增加name属性
stu2.introduce = function() { // 为对象增加introduce方法
alert('My name is ' + this.name); // this代表当前对象
};
alert(stu2.name); // 访问name属性,输出结果:Jack
//用new Object创建对象
var obj = new Object(); // 创建了一个空对象
obj.name = '小明'; // 创建对象后,为对象添加成员
obj.age = 18;
obj.sex = '男';
obj.sayHello = function() {
console.log('Hello');
};
使用构造函数创建对象的语法为 “new 构造函数名()”,在小括号中可以传递参数给构造函数,如果没有参数,小括号可以省略。
// 编写构造函数
function 构造函数名() {
this.属性 = 属性;
this.方法 = function() {
// 方法体
}
}
// 使用构造函数创建对象
var obj = new 构造函数名();
使用for…in语法可以遍历对象中的所有属性和方法,示例代码如下:
// obj为待遍历的对象
var obj = { name: '小明', age: 18, sex: '男' };
// 遍历obj对象
for (var k in obj) {
// 通过k可以获取遍历过程中的属性名或方法名
console.log(k); // 依次输出:name、age、sex
console.log(obj[k]); // 依次输出:小明、18、男
}
使用in运算符判断一个对象中的某个成员是否存在。
var obj = {name: 'Tom', age: 16};
console.log('age' in obj); // 输出:true,表示对象成员存在console.log('gender' in obj); // 输出:false ,表示对象成员不存在
JavaScript提供了很多常用的内置对象,包括数学对象Math、日期对象Date、数组对象Array以及字符串对象String等。我们以Mozilla开发者网络(MDN)为例,演示如何查阅JavaScript中的内置对象的使用。
//案例要求:封装一个数学对象myMath,实现求出数组中的最大值。
var myMath = {
PI: 3.141592653589793,
max: function() {
var max = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
};
Math对象用来对数字进行与数学相关的运算,不需要实例化对象,可以直接使用其静态属性和静态方法,Math对象的常用属性和方法如下表。
Math.random(): 用来获取随机数,每次调用该方法返回的结果都不同。该方法返回的结果是一个很长的浮点数,其范围是0~1(不包括1)。
// 表示生成大于或等于min且小于max的随机值
Math.random() * (max - min) + min;
// 表示生成0到任意数之间的随机整数
Math.floor(Math.random() * (max + 1));
// 表示生成1到任意数之间的随机整数
Math.floor(Math.random() * (max + 1) + 1);
案例需求: 使程序随机生成一个1~10之间的数字,并让用户输入一个数字,判断这两个数的大小,如果用户输入的数字大于随机数,那么提示“你猜大了”,如果用户输入的数字小于随机数,则提示“你猜小了”,如果两个数字相等,就提示“恭喜你,猜对了”,结束程序。
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
var random = getRandom(1, 10);
while (true) {
var num = prompt('猜数字,范围在1~10之间。');
if (num > random) { alert('你猜大了'); }
else if (num < random) { alert('你猜小了')}
else { alert('恭喜你,猜对了'); break; }
}
JavaScript中的日期对象需要使用new Date() 实例化对象才能使用,Date()是日期对象的构造函数。Date()构造函数可以传入一些参数,示例代码如下。
// 方式1:没有参数
var date1 = new Date(); // 输出:Wed Oct 16 2019 10:57:56 GMT+0800 (中国标准时间)
// 方式2:传入年、月、日、时、分、秒(月的范围是0~11)
var date2 = new Date(2019, 10, 16, 10, 57, 56);// 输出:Sat Nov 16 2019 10:57:56 GMT+0800 (中国标准时间
// 方式3:用字符串表示日期和时间
var date3 = new Date('2019-10-16 10:57:56');// 输出:Wed Oct 16 2019 10:57:56 GMT+0800 (中国标准时间)
时间戳是获取从1970年1月1日0时0分0秒开始一直到当前UTC时间所经过的毫秒数。
获取时间戳的常见方式如下:
// 方式1:通过日期对象的valueof()或getTime()方法
var date1 = new Date();
console.log(date1.valueOf()); // 示例结果:1571196996188
console.log(date1.getTime()); // 示例结果:1571196996188
// 方式2:使用“+”运算符转换为数值型
var date2 = +new Date();
console.log(date2); // 示例结果:1571196996190
// 方式3:使用HTML5新增的Date.now()方法
console.log(Date.now()); // 示例结果:1571196996190
==案例需求:==在一些电商网站的活动页上会经常出现折扣商品的倒计时标记,显示离活动结束还剩X天X小时X分X秒。
倒计时的核心算法是输入的时间减去现在的时间,得出的剩余时间就是要显示的倒计时时间,这需要把时间都转化成时间戳(毫秒数)来进行计算,把得到的毫秒数转换为天数、小时、分数、秒数。
function countDown(time) {
var nowTime = +new Date();
var inputTime = +new Date(time);
var times = (inputTime - 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 + '秒';
}
// 示例结果:05天23时06分10秒
console.log(countDown('2019-10-22 10:56:57'));
数组类型检测有两种常用的方式,分别是使用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
JavaScript数组对象提供了添加或删除元素的方法,可以实现在数组的末尾或开头添加新的数组元素,或在数组的末尾或开头移出数组元素。方法如下:
注意
push() 和 unshift() 方法的返回值是新数组的长度,而 pop() 和 shift() 方法返回的是移出的数组元素。
案例需求:要求在包含工资的数组中,剔除工资达到2000或以上的数据,把小于2000的数重新放到新的数组里面。
var arr = [1500, 1200, 2000, 2100, 1800];
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] < 2000) {
newArr.push(arr[i]); // 相当于:newArr[newArr.length] = arr[i];
}
}
console.log(newArr); // 输出结果:(3) [1500, 1200, 1800]
JavaScript数组对象提供了数组排序的方法,可以实现数组元素排序或者颠倒数组元素的顺序等。排序方法如下:
注意: reverse()和sort()方法的返回值是新数组的长度。
在开发中,若要查找指定的元素在数组中的位置,可以利用Array对象提供的检索方法。检索方法如下:
注意: 默认都是从指定数组索引的位置开始检索,并且检索方式与运算符“===”相同,即只有全等时才会返回比较成功的结果。
案例需求:要求在一组数据中,去除重复的元素。
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;
}
var demo = unique(['blue', 'green', 'blue']);
console.log(demo); // 输出结果:(4) ["blue", "green"]
在开发中,可以利用数组对象的 join() 和 toString() 方法,将数组转换为字符串。方法如下:
// 使用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
JavaScript还提供了很多其他常用的数组方法。例如,填充数组、连接数组、截取数组元素等。方法如下:
注意: slice()和concat()方法在执行后返回一个新的数组,不会对原数组产生影响,剩余的方法在执行后皆会对原数组产生影响。
字符串对象使用new String() 来创建,在String构造函数中传入字符串,这样就会在返回的字符串对象中保存这个字符串。
var str = new String('apple'); // 创建字符串对象
console.log(str); // 输出结果:String {"apple"}
console.log(str.length); // 获取字符串长度,输出结果:5
字符串对象提供了用于检索元素的属性和方法,字符串对象的常用属性和方法如下:
var str = 'HelloWorld';
str.indexOf('o'); // 获取“o”在字符串中首次出现的位置,返回结果:4
str.lastIndexOf('o'); // 获取“o”在字符串中最后出现的位置,返回结果:6
案例需求: 要求在一组字符串中,找到所有指定元素出现的位置以及次数。字符串为 ’ Hello World, Hello JavaScript '。
var str = 'Hello World, Hello JavaScript';
var index = str.indexOf('o');
var num = 0;
while (index != -1) {
console.log(index); // 依次输出:4、7、17
index = str.indexOf('o', index + 1);
num++;
}
console.log('o出现的次数是:' + num); // o出现的次数是:3
字符串对象提供了用于获取字符串中的某一个字符的方法。方法如下:
var str = 'HelloWorld';
var str = 'Apple';
console.log(str.charAt(3)); // 输出结果:1
console.log(str.charCodeAt(0)); // 输出结果:65(字符A的ASCII码为65)
console.log(str[0]); // 输出结果:A
案例需求:使用charAt()方法通过程序来统计字符串中出现最多的字符和次数。
var str = 'Apple';
// 第1步,统计每个字符的出现次数
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; }
}
console.log(o); // 输出结果:{A: 1, p: 2, l: 1, e: 1}
// 第2步, 统计出现最多的字符
var max = 0; // 保存出现次数最大值
var ch = ''; // 保存出现次数最多的字符
for (var k in o) {
if (o[k] > max) {
max = o[k];
ch = k;
}
}
// 输出结果:“出现最多的字符是:p,共出现了2次”
console.log('出现最多的字符是:' + ch + ',共出现了' + max + '次');
字符串对象提供了一些用于截取字符串、连接字符串、替换字符串的属性和方法。字符串对象的常用属性和方法如下:
var str = 'HelloWorld';
str.concat('!'); // 在字符串末尾拼接字符,结果:HelloWorld!
str.slice(1, 3); // 截取从位置1开始包括到位置3的范围内的内容,结果:el
str.substring(5); // 截取从位置5开始到最后的内容,结果:World
str.substring(5, 7); // 截取从位置5开始到位置7范围内的内容,结果:Wo
str.substr(5); // 截取从位置5开始到字符串结尾的内容,结果:World
str.substring(5, 7); // 截取从位置5开始到位置7范围内的内容,结果:Wo
str.toLowerCase(); // 将字符串转换为小写,结果:helloworld
str.toUpperCase(); // 将字符串转换为大写,结果:HELLOWORLD
str.split('l'); // 使用“l”切割字符串,结果:["He", "", "oWor", "d"]
str.split('l', 3); // 限制最多切割3次,结果:["He", "", "oWor"]
str.replace('World', '!'); // 替换字符串,结果:"Hello!"
案例需求:用户名长度在3~10范围内,不能出现敏感词admin的任何大小写形式。
var name = prompt('请输入用户名');
if (name.length < 3 || name.length > 10) {
alert('用户名长度必须在3~10之间。');
} else if (name.toLowerCase().indexOf('admin') !== -1) {
alert('用户名中不能包含敏感词:admin。');
} else {
alert('恭喜您,该用户名可以使用');
}
在JavaScript中,简单数据类型(如字符串型、数字型、布尔型、undefined、null)又称为值类型.
复杂数据类型(对象)又称为引用类型。引用类型的特点是,变量中保存的仅仅是一个引用的地址,当对变量进行赋值时,并不是将对象复制了一份,而是将两个变量指向了同一个对象的引用。
举例说明:代码中的obj1和obj2指向了同一个对象。
// 创建一个对象,并通过变量obj1保存对象的引用
var obj1 = { name: '小明', age: 18 };
// 此时并没有复制对象,而是obj2和obj1两个变量引用了同一个对象
var obj2 = obj1;
// 比较两个变量是否引用同一个对象
console.log(obj2 === obj1); // 输出结果:true
// 通过obj2修改对象的属性
obj2.name = '小红';
// 通过obj1访问对象的name属性
console.log(obj1.name); // 输出结果:小红
上述代码运行后,obj1和obj2两个变量引用了同一个对象,此时,无论是使用obj1操作对象还是使用obj2操作对象,实际操作的都是同一个对象。如下图:
当obj1和obj2两个变量指向了同一个对象后,如果给其中一个变量(如obj1)重新赋值为其他对象,或者重新赋值为其他值,则obj1将不再引用原来的对象,但obj2仍然在引用原来的对象。
var obj1 = { name: '小明', age: 18 };
var obj2 = obj1;
// obj1指向了一个新创建的对象
obj1 = { name: '小红', age: 17 };
// obj2仍然指向原来的对象
console.log(obj2.name); // 输出结果:小明
注意:
当一个对象只被一个变量引用的时候,如果这个变量又被重新赋值,则该对象就会变成没有任何变量引用的情况,这时候就会由JavaScript的垃圾回收机制自动释放。
如果在函数的参数中修改对象的属性或方法,则在函数外面通过引用这个对象的变量访问时的结果也是修改后的。
function change(obj) {
obj.name = '小红'; // 在函数内修改了对象的属性
}
var stu = { name: '小明', age: 18 };
change(stu);
console.log(stu.name); // 输出结果:小红