一、概述 1.1、什么是对象 现实生活中:万物皆对象,对象是一个具体的事物,看得见摸得着的实物。例如,一本书、一辆汽车、一个人都是“对象”。
1.2、为什么需要对象 我们知道,JavaScript编程语言,程序开发就是要对现实生活进行模拟,那么在JavaScript中,该如何去描述现实生活中的对象呢?
在 JavaScript 中,对象是一组无序的相关属性 和方法 的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。
对象是由属性和方法组成的。
属性:事物的特征, 在对象中用属性 来表示(常用名词)
方法:事物的行为, 在对象中用方法 来表示(常用动词)
1.3、数组和对象的对比 保存一个值时,可以使用变量, 保存多个值(一组值,比如说手机的大小,颜色等)时,可以使用数组。 如果要保存一个人的完整信息呢?例如,将”张三疯”的个人的信息保存在数组中的方式为:
JS 中的对象表达结构更清晰,更强大。张三疯的个人信息在对象中的表达结构如下:
二、创建对象的方式 2.1、概述 在 JavaScript 中,现阶段我们可以采用三种方式创建对象(object):
字面量方式
利用new Object方式
构造函数方式
2.2、字面量方式 2.2.1、对象定义 对象字面量:就是花括号 { }
里面包含了表达这个具体事物(对象)的属性和方法。{ }
里面采取键值对的形式表示。
键:相当于属性名
值:相当于属性值,可以是任意类型的值(数字类型、字符串类型、布尔类型,函数类型等)
1 2 3 4 5 6 7 8 9 10 11 <script > var obj = { username : '张三' , age : 12 , sayHi : function ( ) { console .log ("Hi......" ); } } </script >
2.2.2、对象调用
对象里面的属性调用 : 对象.属性名 ,这个小点 . 就理解为“ 的 ”
对象里面属性的另一种调用方式 : 对象[‘属性名’], 注意方括号里面的属性必须加引号,我们后面会用
对象里面的方法调用:对象.方法名() , 注意这个方法名字后面一定加括号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <script > var obj = { username : '张三' , age : 12 , sayHi : function ( ) { console .log ("Hi......" ); } } console .log (obj.username ); console .log (obj['age' ]); obj.sayHi (); </script >
2.3、new Object方式 2.3.1、案例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <script > var obj = new Object (); obj.username = "张三丰" ; obj['age' ] = 23 ; obj.sayHi = function ( ) { console .log ("Hi" ); } console .log (obj['username' ]); console .log (obj.age ); obj.sayHi (); </script >
2.3.2、注意点
Object() :第一个字母大写
new Object() :需要 new 关键字
使用的格式:对象.属性 = 值;
2.4、构造函数方式 2.4.1、为什么需要构造函数方式 1 # 原因: 就是因为我们前面两种创建对象的方式一次只能创建一个对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <script > var zhangsan = { username : '张三' , age : 34 , eat : function ( ) { console .log ('吃饭' ); } } var lisi = { username : 'lisi' , age : 23 , eat : function ( ) { console .log ('吃饭' ); } } </script >
2.4.2、利用构造函数创建对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <script > function Person (username, age, sex ) { this .username = username; this .age = age; this .sex = sex; this .sayHi = function ( ) { alert ('名字叫:' + this .username + ',年龄:' + this .age + ',性别:' + this .sex ); } } var zhangsan = new Person ("张三" , 10 , "男" ); console .log (zhangsan.username ); console .log (zhangsan['sex' ]); zhangsan.sayHi (); var lisi = new Person ("李四" , 20 , "女" ); console .log (lisi.username ); console .log (lisi['sex' ]); lisi.sayHi (); </script >
注意
构造函数约定首字母大写。
函数内的属性和方法前面需要添加 this ,表示当前对象的属性和方法。
构造函数中不需要 return 返回结果,其实当我们new的时候,函数已经将当前的this进行了return。
当我们创建对象的时候,必须用 new 来调用构造函数。
2.4.3、总结 构造函数 : 是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。
在 js 中,使用构造函数要时要注意以下两点:
构造函数用于创建某一类对象,其首字母要大写
构造函数要和 new 一起使用才有意义
2.4.5、构造函数和对象的区别
构造函数,如 Person(),抽象了对象的公共部分,封装到了函数里面,它泛指某一大类(class)
对象,如 new Person(),特指某一个,通过 new 关键字创建对象的过程我们也称为对象实例化
2.4.6、new 关键字的执行过程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <script > function Person (username, age, sex ) { this .username = username; this .age = age; this .sex = sex; this .sayHi = function ( ) { alert ('我的名字叫:' + this .username + ',年龄:' + this .age + ',性别:' + this .sex ); } } var zhangsan = new Person ("张三" , 10 , "男" ); console .log (zhangsan.username ); console .log (zhangsan['sex' ]); zhangsan.sayHi (); </script >
2.5、遍历对象属性 2.5.1、说明 for…in 语句用于对数组或者对象的属性进行循环操作。
语法:
2.5.2、案例 1 2 3 4 5 6 7 8 9 10 11 12 13 <script > var person = { username : 'HelloWorld' , age : 10 , sex : '男' }; for (var key in person) { console .log (key + ":" + person[key]); } </script >
2.6、小结
对象可以让代码结构更清晰
对象是复杂数据类型object。
本质:对象就是一组无序的相关属性和方法的集合。
构造函数泛指某一大类,比如苹果,不管是红色苹果还是绿色苹果,都统称为苹果。
对象实例特指一个事物,比如这个苹果、正在路上飞奔的那辆红色轿车等。
for…in 语句用于对对象的属性进行循环操作。
三、内置对象 3.1、说明
JavaScript 中的对象分为3种:自定义对象 、内置对象、 浏览器对象
前面两种对象是JS 基础 内容,属于 ECMAScript; 第三个浏览器对象属于我们JS 独有的, 后面讲
内置对象 就是指 JS 语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)
内置对象最大的优点就是帮助我们快速开发
JavaScript 提供了多个内置对象:Math、 Date 、Array、String等
3.2、Math对象 3.2.1、说明 Math 对象不是构造函数,所以不需要new来调用。它具有数学常数和函数的属性和方法。跟数学相关的运算(求绝对值,取整、最大值等)可以使用 Math 中的成员。
3.2.2、最大值 1 2 3 4 5 <script > console .log (Math .PI ); console .log (Math .max (10 , 23 , 18 )); console .log (Math .max (1 , 2 , 'abc' )); </script >
3.2.3、绝对值 1 2 3 4 5 6 <script > console .log (Math .abs (-10 )); console .log (Math .abs (10 )); console .log (Math .abs ('-20' )); console .log (Math .abs ('abc' )); </script >
3.2.4、取整 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <script > console .log (Math .floor (1.1 )); console .log (Math .floor (1.9 )); console .log (Math .floor (-1.1 )); console .log (Math .floor (-1.9 )); console .log (Math .ceil (1.1 )); console .log (Math .ceil (1.9 )); console .log (Math .ceil (-1.1 )); console .log (Math .ceil (-1.9 )); console .log (Math .round (1.1 )); console .log (Math .round (1.9 )); console .log (Math .round (-1.1 )); console .log (Math .round (-1.9 )); console .log (Math .round (-1.5 )); </script >
3.2.5、随机数 random() 方法可以随机返回一个小数,其取值范围是 [0,1),左闭右开 0 <= x < 1
得到一个两数之间的随机整数,包括两个数在内:
1 2 3 4 5 6 7 8 9 10 11 <script > function getRandom (min, max ) { return Math .floor (Math .random () * (max - min + 1 )) + min; } console .log (getRandom (2 , 13 )); </script >
1 2 3 4 5 6 7 8 9 10 <script > function getRandom (min, max ) { return Math .floor (Math .random () * (max - min + 1 )) + min; } var arrs = ['张三' , '李四' , '王五' , '赵六' , '麻七' ]; console .log (arrs[getRandom (0 , arrs.length - 1 )]); </script >
3.3、日期对象 3.3.1、说明
Date 对象和 Math 对象不一样,是一个构造函数,必须使用new,所以我们需要实例化后才能使用
Date 实例用来处理日期和时间
3.3.2、方法的使用 1 2 3 4 5 <script > var date = new Date (); console .log (date); </script >
1 2 3 4 5 <script > var date = new Date (2021 , 10 , 8 ); console .log (date); </script >
1 2 3 4 5 <script > var date = new Date ('2021-10-08 12:12:12' ); console .log (date); </script >
如果Date()不写参数,就返回当前时间
如果Date()里面写参数,就返回括号里面输入的时间
3.3.3、日期格式化
1 2 3 4 5 6 7 <script > var date = new Date (); console .log (date.getFullYear ()); console .log (date.getMonth () + 1 ); console .log (date.getDate ()); console .log (date.getDay ()); </script >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <script > var date = new Date (); var year = date.getFullYear (); var month = date.getMonth () + 1 ; var dates = date.getDate (); var day = date.getDay (); var arrs = ['星期日' , '星期一' , '星期二' , '星期三' , '星期四' , '星期五' , '星期六' ]; var result = year + "年 " + month + " 月 " + dates + " 日 " + arrs[day]; console .log (result); </script >
1 2 3 4 5 6 7 <script > var date = new Date (); console .log (date.getHours ()); console .log (date.getMinutes ()); console .log (date.getSeconds ()); </script >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <script > function getTime ( ) { var date = new Date (); var h = date.getHours (); h = h < 10 ? '0' + h : h; var m = date.getMinutes (); m = m < 10 ? '0' + m : m; var s = date.getSeconds (); s = s < 10 ? '0' + s : s; return h + ":" + m + ":" + s; } console .log (getTime ()); </script >
3.3.4、获取毫秒数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <script > var date = new Date (); console .log (date.valueOf ()); console .log (date.getTime ()); var date1 = +new Date (); console .log (date1); console .log (Date .now ()); </script >
3.3.5、案例 倒计时效果。
1 2 3 4 5 6 7 8 9 # 思路 1. 输入的时间减去现在的时间就是剩余的时间,即倒计时 ,但是不能拿着时分秒相减,比如 05 分减去25分,结果会是负数的。 2. 用时间戳来做。用户输入时间总的毫秒数减去现在时间的总的毫秒数,得到的就是剩余时间的毫秒数。 3. 把剩余时间总的毫秒数转换为天、时、分、秒 (时间戳转换为时分秒) 4. 转换公式如下: d = parseInt(总秒数/ 60/60 /24); // 计算天数 h = parseInt(总秒数/ 60/60 %24) // 计算小时 m = parseInt(总秒数 /60 %60 ); // 计算分数 s = parseInt(总秒数%60); // 计算当前秒数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <script > function timeDown (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 + '秒' ; } console .log (timeDown ('2021-10-09 17:53:00' )); </script >
3.4、数组对象 3.4.1、检测一个对象是否是数组类型
instanceof 运算符,可以判断一个对象是否属于某种类型
Array.isArray()用于判断一个对象是否为数组,isArray() 是 HTML5 中提供的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 <script > var arrs = []; var obj = {}; console .log (arrs instanceof Array ); console .log (obj instanceof Array ); console .log (Array .isArray (arrs)); console .log (Array .isArray (obj)); </script >
3.4.2、添加删除数组元素的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <script > var arrs = [1 , 2 , 3 , 4 ]; console .log (arrs.push (5 , 'Hello' )); console .log (arrs); console .log (arrs.unshift ('javascript' )); console .log (arrs); console .log (arrs.pop ()); console .log (arrs); console .log (arrs.shift ()); console .log (arrs); </script >
3.4.3、数组排序的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <script > var arrs = [1 , 2 , 3 , 4 , 5 ]; arrs.reverse (); console .log (arrs); var arrs2 = [11 , 3 , 21 , 16 , 34 , 1 ]; arrs2.sort (function (a, b ) { return a - b; }); console .log (arrs2); </script >
3.4.4、数组索引的方法
1 2 3 4 5 6 7 8 9 10 11 <script > var arrs = ['HTML' , 'CSS' , 'JavaScript' , 'Hello' , 'CSS' ]; console .log (arrs.indexOf ('CSS' )); console .log (arrs.lastIndexOf ('CSS' )); </script >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <script > function getUnique (arrs ) { var newArrs = []; for (var i = 0 ; i < arrs.length ; i++) { if (newArrs.indexOf (arrs[i]) === -1 ) { newArrs.push (arrs[i]); } } return newArrs; } var arrs = ['c' , 'a' , 'z' , 'a' , 'x' , 'a' , 'x' , 'c' , 'b' ]; var result = getUnique (arrs); console .log (result); </script >
3.4.5、数组转换为字符串
1 2 3 4 5 6 7 8 9 10 <script > var arrs = [1 , 2 , 3 ]; console .log (arrs.toString ()); var result = arrs.join ('_' ); console .log (result); </script >
3.4.6、数组的其他方法
1 2 3 4 5 6 7 8 9 <script > var arrs1 = [1 , 2 , 3 ]; var arrs2 = [4 , 5 , 6 ]; var arrs3 = [7 , 8 , 9 ]; var result = arrs1.concat (arrs2, arrs3); console .log (result); </script >
1 2 3 4 5 6 7 8 <script > var arrs = [1 , 2 , 3 , 'Java' , 'Hello' , 'js' , 7 , 9 ]; var result = arrs.slice (2 , 5 ); console .log (arrs); console .log (result); </script >
1 2 3 4 5 6 7 8 <script > var arrs = [1 , 2 , 3 , 'Java' , 'Hello' , 'js' , 7 , 9 ]; var result = arrs.splice (2 , 5 ); console .log (arrs); console .log (result); </script >
3.5、字符串对象 3.5.1、根据字符返回位置 字符串所有的方法,都不会修改字符串本身(字符串是不可变的),操作完成会返回一个新的字符串。
1 2 3 4 5 6 <script > var str = '改革春风吹满地,春天来了' ; console .log (str.indexOf ('春' )); console .log (str.indexOf ('春' , 3 )); </script >
3.5.2、根据位置返回字符
1 2 3 4 5 6 7 8 9 10 11 12 <script > var str = 'JavaScript' ; console .log (str.charAt (3 )); console .log (str.charCodeAt (1 )); console .log (str[6 ]); </script >
3.5.3、字符串的其他方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <script > var str = 'JavaScript' ; console .log (str.substr (3 , 6 )); console .log (str.substring (3 , 6 )); console .log (str.replace ('a' , 'A' )); var str2 = 'Hello,java,Spring' ; var arrs = str2.split (',' ) console .log (arrs); </script >
四、简单类型与复杂类型 4.1、概述 简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型。
值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型
string ,number,boolean,undefined,null
引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型
通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等
4.2、堆和栈 堆栈空间分配区别:
1、栈:存储的是函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;
简单数据类型存放到栈里面
2、堆:存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
复杂数据类型存放到堆里面
4.3、简单类型的内存分配
值类型(简单数据类型): string ,number,boolean,undefined,null
值类型变量的数据直接存放在变量(栈空间)中
4.4、复杂类型的内存分配
引用类型(复杂数据类型):通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等
引用类型变量(栈空间)里存放的是地址,真正的对象实例存放在堆空间中
4.5、简单数据类型传参 函数的形参也可以看做是一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量。
1 2 3 4 5 6 7 8 9 10 11 <script > var x = 10 ; function fn (a ) { a++; console .log (a); } fn (x); console .log (x); </script >
4.6、复杂数据类型传参 函数的形参也可以看做是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <script > function Person (name ) { this .name = name; } function f1 (x ) { console .log (x.name ); x.name = "张学友" ; console .log (x.name ); } var p = new Person ("刘德华" ); console .log (p.name ); f1 (p); console .log (p.name ); </script >