现实生活中:万物皆可对象,对象是一个具体的事物,看得见摸不着的事物,例如:一本书、一辆汽车、一个人都可以是“对象,一个数据库、一张网页、一个远程服务器的连接也可以是“对象”
在 JavaScript 中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等
对象是由属性和方法组成的
保存一个值时,可以使用变量,保存多个值(一组值)时,可以使用数组。如果要保存一个人的完整信息呢?
例如,将“张三疯”的个人的信息保存在数据中的方式为:
var arr = ['张三疯', '男', 128, 154];
JS 中的对象表达结构更清晰,更强大。张三疯的个人信息在对象中的表达结构如下:
person.name = '张三疯';
person.sex = '男';
person.age = 128;
person.height = 154;
对象字面量:就是花括号 {} 里面包含了表达这个具体事务(对象)的属性和方法
创建一个空对象:
var obj = {};
以下是实例:
var obj = {
uname: '张三疯',
age: 18,
sex: '男',
sayHi: function() {
console.log('hi~');
}
}
一些需要注意的小细节:
如何使用对象呢?调用对象的属性,我们采取: "对象名.属性名" 里面的那个 (.) 我们理解为 (的) 比如:对象的名字
console.log(obj.uname);
结果:张三疯
调用属性还有一种方法:对象名['属性名'];
console.log(obj['age']);
调用对象 sayHi 的方法:对象名.方法名
obj.sayHi();
千万别忘记添加小括号
跟前面学的 new Array() 原理一致
var obj = new Object();
obj.uname = '张三疯';
obj.age = 18;
obj.sex = '男';
obj.sayHi = function() {
console.log('Hi');
}
一些需要注意的小细节:
调用的方法还是和之前一样:
console.log(obj.uname);
console.log(obj['sex']);
obj.sayHi();
变量和属性都是用来存放数据的
1.变量是单独声明并赋值,使用的时候直接写变量名,单独存在
var num = 10;
var obj = {
age: 18
}
console.log(obj.age);
属性在对象里面不需要声明,使用的时候必须是: "对象.属性" 如果直接输入属性就会报错
2.函数和方法的相同点都是实现某种功能,做某件事
var obj = {
age: 18,
fn: function() {
}
}
function fn() {
}
console.log(obj.age);
函数是单独声明并且调用的: "函数名()" 单独存在的
方法在对象里面,调用的时候: "对象.方法()"
因为我们一次创建一个对象,里面很多属性和方法是大量相同的,我们只能复制
因此我们可以利用函数的方法重复这些相同的代码。我们把这个函数成为构造函数
又因为这个函数不一样,里面封装的不是普通代码,而是对象
构造函数就是把我们对象里面一些相同的属性和方法抽象出来封装到函数里面
构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋值初始值,它总与 new 运算符一起使用。我们可以把对象中一些公共属性和方法抽取出来,然后封装到这个函数里面。
构造函数的语法格式:
function 构造函数名() {
this.属性 = 值;
this.方法 = function() {}
}
new 构造函数名();
这是一个构造函数:
function Star(uname, age, sex) {
this.name = uname;
this.age = age;
this sex = sex;
}
new Star('刘德华', 18 '男');
可以直接赋值给变量:
var ldn = new Star('刘德华' 18, '男');
调用函数返回的是一个对象
创建多个对象并且输出:
function Star(uname, age, sex) {
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function(sang) {
console.log(sang);
}
}
var ldh = new Star('刘德华', 18, '男');
var zxy = new Star('张学友', 19, '男');
console.log(ldh.name);
console.log(zxy['name']);
zxy.sing('李香兰')
结果:刘德华 张学友 李香兰
我们只需要 new Star() 调用函数就创建一个对象 ldh {}
注意事项:
(1) new 构造安徽念书可以在内存中创建一个空的对象
(2) this 就会指向刚才创建的空对象
(3) 执行构造函数里面的代码给这个空对象添加属性和方法
(4) 返回这个对象 (所以构造函数不需要 return)
一个一个属性输出很麻烦:
var obj = {
name: 'pink老师',
age: 18,
sex: '男'
}
console.log(obj.name);
console.log(obj.age);
console.log(obj.sex);
如果要输出20行代码呢?是不是很麻烦?
for...in 语句用于对数组或者对象属性进行循环操作
语法格式:
for (变量 in 对象) {
}
实例:
var obj = {
name: 'pink老师',
age: 18,
sex: '男'
}
for (var k in obj) {
console.log(k);
}
结果:name age sex
输出的是属性名
当然,也是可以输出属性值的:
var obj = {
name: 'pink老师',
age: 18,
sex: '男'
}
for (var k in obj) {
console.log(obj[k]);
}
结果:pink老师 18 男
方法也可以遍历出来,这里不做演示 (因为这种方法很少用)
注意: 这个 console.log(obj[k]); 是不需要加引号的,这是一个变量
1. 对象可以让代码结构更清晰
2. 对象复杂数据类型 object
3. 本质:对象就是一组无序的相关属性和方法的集合
4. 构造函数泛指某一大类,比如苹果,不管是红色苹果还是绿色苹果,都统称为苹果
5. 对象实例特指一个事物,比如这个苹果、正在给你们讲课的老师等
6. for...in 语句用于对对象的属性进行循环操作
学习一个内置对象的使用,只要学会其常用成员的使用即可,我们可以通过查文档学习,可以通过 MDN/W3C 来查询。
Mozilla 开发者网络 (MDN) 提供了有关开放网络技术 (OpenWeb) 的信息,包括 HTML、CSS 和万维网及 HTML5 应用的 API
MDN: https://developer.mozilla.org/zh_CN
Math 数学对象不是一个构造函数,所以我们不需要 new 来调用,而是直接使用里面的属性和方法即可
输出一个属性圆周率:
console.log(Math.PI);
结果:3.141592653589793
求数字最大值:
console.log(Math.max(1, 99, 3));
结果:99
绝对值方法:
console.log(Math.abs(1));
console.log(math.abs(-1));
console.log(Math.abs('-1'));
console.log(Math.abs('pink');)
结果:1 1 1 1 NaN
Math.floor() 往下取整,割掉小数点:
console.log(Math.floor(1.1));
console.log(Math.floor(1.9));
结果:1 1
Math.ceil() 网上取整:
console.log(Math.ceil(1.1));
console.log(Math.ceil(1.9));
结果:2 2
Math.round() 四舍五入:
console.log(Math.round(1.1));
console.log(Math.round(1.5));
console.log(Math.round(1.9));
console.log(Math.round(-1.1));
console.log(Math.round(-1.5));
结果:1 2 2 -1 -1
小学知识:其他数字都是四舍五入,但是 .5 特殊,它往大了取
random() 返回一个随机的小数
console.log(Math.random());
结果:0.927546064911247 (此数值不是固定的)
我们想要得到两个数之间的随机整数,并且包含这两个整数
Math.floor(Math.random() * (max - min + 1)) + min;
这样就可以求出 1-10 之间的整数
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(getRandom(1, 10));
这样就可以做一个随机点名的案例了:
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var arr = ['正一', '王二', '张三', '李四', '韩五'];
console.log(arr[getRandom(0, arr.length - 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;
}
}
Date() 日期对象是一个构造函数,必须使用 new 来调用创建我们的日期对象
使用 Date:
var date = new Date();
console.log(date);
结果:Thu Apr 21 2022 15:0:0 GMT+0800 (中国标准时间)
这个结果会随着时间改变,所以不是固定的
参数常用的写法:数字型 2022, 4, 21 或者是 字符串型 '2022-4-21 14:57:0'
var date1 = new Date(2022, 4, 21);
console.log(date1);
或者是这个:
var date2 = new Date('2022-4-21 15:0:0');
console.log(date2);
我们想要 2022-4-21 15:0:0 格式的日期,要怎么办?
需要获取日期指定部分,所以我们要手动的得到这种格式
| 方法名 | 说明 | 代码 |
|---|---|---|
| getFullYear() | 获取当年 | dObj.getFullYear() |
| getMonth() | 获取当月 (0-11) | dObj.getMonth() |
| getDate() | 获取当天日期 | dObj.getDate() |
| getDay() | 获取星期几 (周日0 到周六6) | dObj.getDay() |
| getHours() | 获取当前小时 | dObj.getHours() |
| getMinutes() | 获取当前分钟 | dObj.getMinutes |
| getSeconds() | 获取当前秒钟 | dObj.getSeconds() |
返回当前年月日:
var date = new Date();
console.log(date.getFullYear());
console.log(date.getMonth() + 1);
console.log(date.getDate());
console.log(date.getDay());
结果:2022 4 21 4
需要注意的两个事项:
(1) 月份需要 +1 否则会小一个月份
(2) 周日返回的结果是 0 因为老外就是这样看的
以下方法可以输出一个正确的年月日:
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1;
var dates = date.getDate();
var day = date.getDay();
var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
console.log('今天是' + year + '年' + month + '月' + dates + '日' + ' ' + arr[day]);
结果:今天是2022年4月21日 星期四
接下来是小时分钟还有秒:
function getTime() {
var time = new Date();
var h = time.getHours();
h = h < 10 ? '0' + h : h;
var m = time.getMinutes();
m = m < 10 ? '0' + m : m;
var s = time.getSeconds();
s = s < 10 ? '0' + s : s;
return h + ':' + m + ':' + s;
}
console.log(getTime());
结果:17:07:00 (结果会变)
Date 对象是基于 1970 年 1 月 1 日 (世界标准时间) 起的毫秒数
我们经常利用总的毫秒数来计算时间,因为它更准确
获得 Date 总的毫秒数不是当前时间的毫秒数,而是距离1970年1月1号过了多少毫秒数
1. 通过 valueOf() 和 getTime()
输出现在的时间距离1970年1月1日总的毫秒数
var date = new Date();
console.log(date.valueOf());
console.log(date.getTime());
结果:1650532747618 (随时变化)
2. 简单的写法:
var date = +new Date();
console.log(date);
结果还是:1650532747618
3. H5 新增的获得总的毫秒数
console.log(Date.now());
结果居然还是:1650532747618
但是注意:这个 Date 需要大写
做一个倒计时效果
案例分析:
转换公式如下:
1. 利用数组字面量
var arr = [1, 2, 3];
console.log(arr[0]);
2. 利用 new Array()
创建一个空数组:
var arr1 = new Array();
如果括号里面只写一个二代表创建一个长度为 2 的空数组:
var arr1 = new Array(2);
如果这样写在括号里等于 [2, 3] 也就是创建一个数组,里面包含 2 和 3:
var arr1 = new Array(2, 3);
console.log(arr1);
结果:2 | 3
(1) instanceof 运算符,它可以用来检测是否为数组
var arr = [];
console.log(arr instanceof Array);
结果:true
如果它不是数组则返回 false
var obj = {};
console.log(obj instanceof Array);
结果:false
(2) Array.isArray(参数); 也可以检测是不是数组
var arr = [];
consoel.log(Array.isArray(arr));
结果:true
var obj = {};
console.log(Array.isArray(obj));
结果:false
注意: 方法二时 H5 新增的方法,ie9 版本以上才支持
添加数组元素和删除数组元素的方法:
| 方法名 | 说明 | 返回值 |
|---|---|---|
| push(参数1....) | 末尾添加一个或多个元素,注意修改原数组 | 并返回新的长度 |
| pop() | 删除数组最后一个元素,把数组长度减 1 无参数、修改原数 | 返回它删除的元素的值 |
| unshift(参数1...) | 向数组的开头添加一个或更多元素,注意修改原数组 | 并返回新的长度 |
| shift() | 删除数组的第一个元素,数组长度减 1 无参数、修改原数组 | 并返回第一个元素的值 |
1. push() 在我们数组的末尾添加一个或多个数组元素 push 推
var arr = [1, 2, 3];
arr.push(4);
console.log(arr);
结果:1 | 2 | 3 | 4
也可以添加更多元素哦
var arr = [1, 2, 3, 4];
arr.push(5, 6);
console.log(arr);
结果:1 | 2 | 3 | 4 | 5 | 6
2. unshift 在我们数组的开头添加一个或多个数组元素
var arr = [1, 2, 3];
arr.unshift('red');
console.log(arr);
结果:'red' | 1 | 2 | 3
当然,也可以添加更多
var arr = [1, 2, 3];
arr.unshift('red', 'pink');
console.log(arr);
结果:'red' | 'pink' | 1 | 2 | 3
3. pop() 它可以删除数组的最后一个元素,但那是一次只能删一个
var arr = [1, 2, 3, 4];
arr.pop();
console.log(arr);
结果:1 | 2 | 3
但是它的返回值有些意外
var arr = [1, 2, 3, 4];
console.log(arr.pop());
结果:4
也就是删除哪个元素就返回哪个元素
4. shift() 它可以删除数组的第一个元素
var arr = [1, 2, 3, 4];
console.log(arr.shift());
console.log(arr);
结果:2 | 3 | 4
它的返回值也是删除的数组元素
有一个包含工资的数组 [1500, 1200, 2000, 2100, 1800],要求把数组中工资超过 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]);
}
}
console.log(newArr);
结果:1500 | 1200 | 1800
实例:
| 方法名 | 说明 | 是否修改原数组 |
|---|---|---|
| reverse() | 颠倒数组中元素的顺序,无参数 | 该方法会改变原来的数组,返回新数组 |
| sort() | 的数组的元素进行排序 | 该方法会改变原来的数组,返回新数组 |
reverse() 翻转数组
var arr = ['pink', 'red', 'blue'];
arr.reverse();
console.log(arr);
结果:blue | red | pink
sort() 可以排列数组
var arr1 = [3, 4, 7, 1];
arr1.sort();
consle.log(arr1);
结果:1 | 3 | 4 | 7
但是如果数字是个位数就无法实现排序效果
var arr1 = [13, 4, 77, 1, 7];
arr1.sort();
console.log(arr1);
结果:1 | 13 | 4 | 7 | 77
但是这是有方法解决的,以下方法完美解决问题,但是代码固定,所以要记住
var arr1 = [13, 4, 77, 1, 7];
arr1.sort(function(a, b){
return a - b;
});
console.log(arr1);
结果:1 | 4 | 7 | 13 | 77
当然,如果 b - a 会返回降序
var arr1 = [13, 4, 77, 1, 7];
arr1.sort(function(a, b){
return b - a;
});
console.log(arr1);
结果:77 | 13 | 7 | 4 | 1
| 方法名 | 说明 | 返回值 |
|---|---|---|
| indexOf() | 数组中查询给定元素的第一个索引 | 如果存在返回索引号,如果不存在,则返回 -1 |
| lastIndexOf() | 在数组中的最后一个索引 | 如果存在返回索引号,如果不存在,则返回 -1 |
indexOf() 返回数组元素索引号方法
var arr = ['red', 'green', 'blue', 'pink'];
console.log(arr.indexOf('blue'));
结果是:2
他只会返回第一个满足条件的索引号
var arr = ['red', 'green', 'blue', 'pink', 'blue'];
console.log(arr.indexOf('blue'));
结果还是:2
但是如果结果没有 'blue' 呢?
var arr = ['red', 'green', 'pink'];
console.log(arr.indexOf('blue'));
结果:-1
只要找不到该元素结果就是 -1
lastIndexOf() 查找的方法是从后往前查找
var arr = ['red', 'green', 'blue', 'pink', 'blue'];
console.log(arr.indexOf('blue'));
结果:4
有一个数组 ['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b'],要求去除数组中重复的元素
案例分析:
代码:
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(['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b']);
console.log(demo);
| 方法名 | 说明 | 返回值 |
|---|---|---|
| toString() | 把数组转换成字符串 | 返回一个字符串 |
| join('分隔符') | 方法用于把数组中的所有元素转换为一个字符串 | 返回一个字符串 |
toString() 将我们的数组转换为字符串
var arr = [1, 2, 3];
console.log(arr.toString());
结果:'1, 2, 3'
join(分隔符) 它更加强大,可以加分隔符,但是默认是 (,) 隔开
var arr1 = ['green', 'blue', 'pink'];
console.log(arr1.join());
结果:'green, blue, pink'
如果在括号里面加一个 (-) 它就会用 (-) 分隔
var arr1 = ['green', 'blue', 'pink']; conosle.log(arr1.join('-'));
结果:'green-blue-pink'
当然,还可以用其他符号,比如说:& * .
这行代码的输出长度结果结果让人出乎意料
var str = 'andy';
console.log(str.length);
结果是:4
简单数据类型为什么会有 lenght 属性呢?
基本包装类型:就是把简单数据类型包装成为了复杂数据类型
(1) 把简单数据类型包装为复杂数据类型
var temp = new String('andy');
(2) 把临时变量的值给 str
str = temp;
(3) 销毁这个临时变量
temp = null;
为了方便操作基本数据类型,JavaScript 还提供了三个特殊引用类型:String、Number 和 Boolean
基本包装类型就是把简单数据类型包装成为复杂数据类型,这样基本数据类型就有了属性和方法
指的是里面的值不可变,虽然看上去可以改变内容,但其实是地址变,内存中新开辟了一个内存空间
所以说不要总是用新的值赋值给旧的值,因为它们会越加越多,知道内存爆满
var str = '';
for (var i = 1; i <= 114514114514; i++) {
str += i;
}
console.log(str);
上述的代码会使电脑卡死
字符串所有方法,都不会修改字符串本身(字符串是不可变的),操作完成会返回一个新的字符串
| 方法名 | 说明 |
|---|---|
| indexOf('要查找的字符' 开始的位置) | 返回指定内容在元字符串中的位置,如果找不到就返回 -1,开始的位置是 index 索引号 |
| lastIndexOf() | 从后往前找,只找第一个匹配的 |
首先是 indexOf()
var str = '改革春风吹满地';
console.log(str.indexOf('春'));
结果:2
字符串对象根据字符返回位置 str.indexOf('要查找的字符'.[起始的位置])
var str = '改革春风吹满地,春天来了';
console.log(str.indexOf('春', 3)); // 从起始位置为 3 的地方开始查找
结果:8
lastIndexOf() 也就是从后往前查找
查找字符串"abcoefoxyozzopp"中所有o出现的位置以及次数
代码:
var str = 'abcoefoxyozzopp';
var index = str.indexOf('o');
num = 0;
while (index !== -1) {
console.log(index);
num++;
index = str.indexOf('o', index + 1);
}
console.log('o出现的次数是' + num + '次');
结果:3 | 6 | 9 | 12 | o出现的次数是4次
实例:
| 方法名 | 说明 | 使用 |
|---|---|---|
| charAt(index) | 返回指定位置的字符(index 字符串的索引号) | str.charAt(0) |
| charCodeAt(index) | 获取指定位置处字符的ASCII码 (index索引号) | str.charCodeAt(0) |
| str[index] | 获取指定位置处字符 | HTML5, IE8+支持和 charAt() 等效 |
(1) charAt(index) 根据位置返回字符
var str = 'andy';
console.log(str.charAt(3));
结果:y
遍历所有字符
var str = 'andy';
for (var i = 0; i < str.lenght; i++) {
console.log(str.charAt(i));
}
结果:a | n | d | y
(2) charCodeAt(index) 返回相应索引号的字符 ASCII 值。目的:判断用户按下了哪个键
var str = 'andy';
console.log(str.charCodeAt(0));
结果:97
(3) str[index] H5 新增的,但是呢,它跟 charCodeAt(index) 用起来是一模一样的
可以通过 对象['属性名']
var o = {
age: 18;
}
if (o['age']) {
console.log('里面有该属性');
} else {
console.log('里面没有该属性');
}
结果:里面有该属性
判断一个字符串'abcoefoxyozzopp'中出现次数最多的字符,并统计其次数
代码:
var str = 'abcoefoxyozzopp';
var o = {};
for (var i = 0; i < str.length; i++) {
var chars = str.charAt(i);
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;
}
}
console.log('最多的字符是' + ch);
案例:
| 方法名 | 说明 |
|---|---|
| concat(str1, str2, str3...) | concat() 方法用于连接两个或多个字符串。拼接字符串,等效于+, +更常用 |
| substr(start, lenght) | 从 strart 位置开始 (索引号),lenght 取的是个数,重点要记住这个 |
| slice(start, end) | 从 start 位置开始,截取到 end 位置,end 取不到(它们俩都是索引号) |
| substring(start, end) | 从 start 位置开始,截取到 end 位置,end 取不到 基本和 slice 相同,但是不接受负值 |
字符串操作方法
1. concat('字符串1', '字符串2'....)
var str = 'andy';
console.log(str.concat('red'));
结果:'andyred'
2. substr('截取的起始位置', '截取几个字符');
var str1 = '改革春风吹满地';
console.log(str1.substr(2, 2));
第一个2是索引号的2,从第几个开始,第二个2是取几个字符
1. 替换字符 replace('被替换的字符', '替换为的字符') 注意:它只会替换第一个字符
var str = 'andy';
console.log(str.replace('a', 'b'));
结果:bndy
可以利用循环和这个字符来替换,有一个字符串“abcoefoxyozzopp”要求把里面所有的 o 替换为 *
var str1 = 'abcoefoxyozzopp';
while (str1.indexOf('o') !== -1) {
str1 = str1.replace('o', '*');
}
console.log(str1);
结果:abc*ef*xy*zz*pp
2. 字符串转换为数组 split('分隔符') 前面我们学过 join 把数组转换为字符串
var str2 = 'red, pink, blue';
console.log(str2.split(','));
结果:['red', 'pink', 'blue'] 数组版
toUpperCase() 是转换大写,toLowerCase() 是转换小写
自己查去!这边略了!