精简《JavaScript高级程序设计》五、引用类型(上)

第五章概况

在这里插入图片描述

5.1 Object类型

引用类型是一种数据结构,用于将数据和功能组织在一起。对象是某个特定引用类型的实例

创建Object实例的方式有两种:

  1. new+Object构造函数
var person = new Object()
  1. 使用对象字面量
var person = {
	name:"fur",
	age:"1"
}
//或者
var person = {}
person.name = "fur"
person.age = "1"

注意:属性名也可以为字符串,但是数值属性名会自动转换为字符串 eg

let person = {
"name":"fur",
"age":"1",
5:true  //5自动转换为字符串
}
//console.log(person.5)直接打印报错
console.log(typeof person[5])//只能用方括号的形式
//验证数字5 被 转换为字符串
for (let i in person) {
    console.log(i + ' 类型是:'+ typeof i )
}

运行结果如图:

在这里插入图片描述

访问对象属性的方式两种:

点表示法:简单常用

方括号表示法:可以通过遍历访问属性,常用于遍历,或者不能用点表示法时候

let person = {
"name":"fur",
"age":"1",
5:true  //5自动转换为字符串
"first name" : "jiang"
}
//以下只能用方括号表示,不提倡这样定义
console.log(typeof person[5])
console.log(typeof person["first name"])

5.2 Array类型

创建数组的方式两种:

第一种 使用Array构造函数,new可以省略

let arr = new Array()
let arr = new Array(20)
let arr = new Array("fur","frufur")

第二种,数组字面量表示法

let arr = []
let arr = ["fur","furfur"]

注意:数组长度不是一个只读属性,可以被修改

验证:

let arr = ['fur','furfur','furfur-jiang']
console.log(arr[2])//furfur-jiang
arr.length = 2
console.log(arr[2])//undefined

可以方便的句末添加属性

let arr = ['fur','furfur','furfur-jiang']
arr[arr.length]= "fur1"
arr[arr.length]= "fur2"
console.log(arr)
//Array(5) [ "fur", "furfur", "furfur-jiang", "fur1", "fur2" ]

注意:数组上限4294967295项

Array.isArray()用于检测是否为数组,当网页包含多个框架,存在不同版本的Array构造函数时,通过这个方法确定是不是数组

let arr = ['fur','furfur','furfur-jiang']
console.log(Array.isArray(arr))//true

转换方法

所有对象都具有toLocaleString(),toString(),valueOf()

toLocaleString(),toString()输出以逗号隔开的字符串

valueOf()返回一个数组

注意:alert默认会调用toString方法,所有输出的都是字符串

join()可以用不同分隔符构建字符串,只接受一个参数

let arr = ['fur','furfur','furfur-jiang']
console.log(arr.join("!!!"))//fur!!!furfur!!!furfur-jiang
console.log(arr.join("___"))//fur___furfur___furfur-jiang

如果数组中间某一项是null或者undefined,在toLocaleString(),toString(),join()返回的结构中以空字符串表示,而valueOf()会返回对应元素(valueOf()运行结果与书里的解释不同,书中将其与前面三种方法归为一类)

let arr = ['fur',null,undefined,'furfur-jiang']
arr[5] = "fur0"
console.log(arr.toString())//fur,,,furfur-jiang,,fur0
console.log(arr.toLocaleString())//fur,,,furfur-jiang,,fur0
console.log(arr.join(","))//fur,,,furfur-jiang,,fur0
console.log(arr.valueOf())
//火狐结果
//Array(6) [ "fur", null, undefined, "furfur-jiang", undefined, "fur0" ]
//谷歌结果
//(6) ["fur", null, undefined, "furfur-jiang", empty, "fur0"]

栈方法

栈方法是一种LIFO(Last-In-First-Out,后入先出)的数据结构,栈中项的插入(推入)和移除(弹出),只发生在栈的顶部。对应push()pop()方法

push()接受任意数量的参数,把他们逐个添加到数组末尾,并返回修改后的数组长度

pop()从数组末尾移除最后一项并返回

let arr = ['fur',"furfur",'furfur-jiang']
console.log(arr.push("fur1","fur2"))//5
console.log(arr.pop())//fur2
console.log(arr.length)//4

push进行推入操作,操作结束后返回数组长度,pop进行移除操作,操作结束后返回被移除的那一项,数组长度减一

队列方法

栈方法是一种LIFO(First-In-First-Out,先入先出)的数据结构,队列的末端添加项,从队列前端移除项,对应push()shift()方法

shift() 移除数组第一项并返回该项

let arr = ['fur',"furfur",'furfur-jiang']
console.log(arr.push("fur1","fur2"))//5
console.log(arr.shift())//fur
console.log(arr.length)//4

unshift()能在数组前端添加任意个项并返回新数组长度

总结:

  • unshift()push()都是添加任意元素,前者在数组前端添加,后者在数组末尾添加
  • shift()pop()都是移除一个元素,前者在数组前端移除,后者在数组末尾移除

重排序方法

数组已经存在reverse()sort()两个方法

reverse()具有从反转数组项的顺序

let arr = ['fur','furfur-jiang',"furfur"]
console.log(arr.reverse())
//Array(3) [ "furfur", "furfur-jiang", "fur" ]

sort()按升序排列数组项,每个数组项调用toString()方法,也就是比较的其实是字符串,即使数组内的元素都是数字

let arr = ['fur','aaa',"abc"]
console.log(arr.sort())
// Array(3) [ "aaa", "abc", "fur" ]

let arr = [5,16,11]
console.log(arr.sort())
// Array(3) [ 11, 16, 5 ]

所以sort()正确使用方式是接受一个比较函数作为参数

let arr = [5,16,11]
//升序
function compareUp (value1,value2){
    return value1 - value2;
}
//降序
function compareDown (value1,value2){
    return value2 - value1;
}
console.log(arr.sort(compareUp))
//Array(3) [ 5, 11, 16 ]
console.log(arr.sort(compareDown))
//Array(3) [ 16, 11, 5 ]

操作方法

concat()slice()splice()三种方法

concat()可以基于当前数组中的所有项创建新数组,如果传递的是一个或多个数组,会将这些数组的每一项添加到结果数组里;如果不是数组,则简单添加到结果数组末尾,不会干扰原来的数组。

let arr = ['fur',"furfur"]
console.log(arr.concat("furfur-jiang"))
//[ "fur", "furfur", "furfur-jiang" ]
console.log(arr.concat(['fur1',"fur2"]))
//[ "fur", "furfur", "fur1", "fur2" ]

slice()可以基于当前数组在的一个或多个项创建一个新数组,接受一或两个参数,返回项的起始和结束位置。如果只有一个参数即从这个参数到数组末尾所有项。返回对应的值,包括起始位置而不包括结束位置的元素(包头不包尾

let arr = ['fur',"furfur","furfur-jiang","fur1"]
console.log(arr.slice(1))
//[ "furfur", "furfur-jiang", "fur1" ]
console.log(arr.slice(1,3))
//[ "furfur", "furfur-jiang" ]

splice()主要用于向数组中部插入项,返回删除的元素,会影响原数组,使用方法有如下三种

  • 删除:只需指定两个参数,要删除的第一项和要删除的项数
  • 插入:只需指定3个参数:起始位置,0(要删除的项数),要插入的项
  • 替换:向指定位置插入任意数量的项,同时删除任意数量的项,只需指定三个参数:起始位置,要删除的项数,要插入的任意数量的项
//删除操作,第一项furfur开始删除,删除两个
let arr1 = ['fur',"furfur","furfur-jiang","fur1"]
console.log(arr1.splice(1,2))
//[ "furfur", "furfur-jiang" ]
console.log(arr1)
// [ "fur", "fur1" ]

//插入操作,从第一项furfur开始插入,插入两个元素
let arr2 = ['fur',"furfur","furfur-jiang","fur1"]
console.log(arr2.splice(1,0,"fur2","fur3"))
//[]
console.log(arr2)
// [ "fur", "fur2", "fur3", "furfur", "furfur-jiang", "fur1" ]

//替换操作,从第一项furfur开始插入,插入两个同时删除原来的两个的位置
let arr3 = ['fur',"furfur","furfur-jiang","fur1"]
console.log(arr3.splice(1,2,"fur2","fur3"))
//[ "furfur", "furfur-jiang" ]
console.log(arr3)
//[ "fur", "fur2", "fur3", "fur1" ]

位置方法

indexOf()lastIndexOf()两个方法都接收两个参数:要查找的项和(可选的)表示要查找起点位置的索引。

其中indexOf()从数组开头开始向后查找,lastIndexOf()表示从数组的末尾向前查找。两个方法都返回查找项在数组的位置,没找到返回-1。

注意:要求查找的项必须严格相等(就像使用===一样)

let arr = ['fur',"furfur","furfur-jiang"]
console.log(arr.indexOf("furfur"))//1
console.log(arr.indexOf("furfur",1))//1
console.log(arr.indexOf("furfur",2))//-1

console.log(arr.lastIndexOf("furfur",2))//1
console.log(arr.lastIndexOf("fur-fur"))//-1

迭代方法

ES5定义了五个迭代的方法,每个方法就收两个参数:要在每一项上运行的函数和(可选的)运行该函数的作用域对象–影响this的值,其中传入的函数接受三个参数:数组项的值,该项在数组中的位置和数组对象本身,数组对象本身

every(),对数组的每一项运行给定函数,如果该函数对每一项都返回true,则返回true

filter(), 对数组的每一项运行给定函数,返回该函数会返回true的项组成的数组

forEach() ,对数组的每一项运行给定函数,则这个没有返回值,参照我的另一篇文章

map(), 对数组的每一项运行给定函数,返回每次函数调用的结果组成的数组

some(),对数组的每一项运行给定函数,如果该函数对任一项返回true,则返回true,不再继续

以上函数不会修改原数组包含的值

let arr = [1,2,3,4,5,6,3]

console.log(arr.every(function(item,index,array){
    return (item >2)
}))//false
console.log(arr.some(function(item,index,array){
    return (item >2)
}))//true
console.log(arr.filter(function(item,index,array){
    return (item >2)
}))//[ 3, 4, 5, 6, 3 ]
console.log(arr.map(function(item,index,array){
    return (item * 2)
}))//[ 2, 4, 6, 8, 10, 12, 6 ]

归并方法

reduce()reduceRight()都会迭代数组的所有项,然后构造一个最终返回的值。区别在于reduce() 是从数组第一项,reduceRight()是从数组最后一项,向前遍历。

接收两个参数:一个在每一项是调用的函数和(可选的)作为归并基础的初始值

传给这两个方法的函数接受四个参数:前一个值,当前值,项的索引,数组对象

这个函数返回的任何值都会作为第一个参数自动传给下一项,第一次迭代发生在数组第二项上,因此第一个参数是数组的第一项,第二个参数是数组的第二项

let arr = [1,2,3,4,5,6,3]

let sum1 = arr.reduce(function(pre,cur,index,array){
    console.log("pre:"+pre+",cur:"+cur) 
    return pre + cur
})
console.log(sum1)//24
let sum2 = arr.reduceRight(function(pre,cur,index,array){
    console.log("pre:"+pre+",cur:"+cur)
    return pre + cur
})
console.log(sum2)//24

在这里插入图片描述

5.3 Date类型

Date基本方法

Date.parse() ,Date.UTC(),Date.now()

Date.parse()会接受一个表示日期的字符串,然后尝试根据这个字符串返回相应日期的毫秒数。

console.log(new Date(Date.parse("Jan 23,2020")))
//Date Thu Jan 23 2020 00:00:00 GMT+0800 (中国标准时间)
console.log(new Date("Jan 23,2020"))
//Date Thu Jan 23 2020 00:00:00 GMT+0800 (中国标准时间)

Date构造函数会在后台调用Date,parse(),所以上面两种写法是相同的

当输入的字符串不能表示日期,谷歌和火狐会输出Invalid Date,(运行结果与书上不同,书上说是NaN或者其他奇怪的结果)

console.log(new Date("Jan 32,2020"))//Invalid Date

Date.UTC()接受的参数年份,基于0的月份,月中的哪一天(1到31),小时数(0到23),分钟,秒以及毫秒数,这些参数只有前两个参数(年和月)是必需的。其他参数统统假设为0。

var utc = Date.UTC(y,m,d,h,M,s);
//这里,y、m、d、h、M、s分别代表步骤2中获取的年、月、日、时、分、秒数值。

UTC + 时区差 = 本地时间

  • 时区差格式为 符号+ 24小时制数字 + 分钟,如:北京与UTC时差记为+0800
  • 时区差东为正,西为负。

整个地球分为二十四时区,每个时区都有自己的本地时间。在国际无线电通信场合,为了统一起见,使用一个统一的时间,称为通用协调时(UTC, Universal Time Coordinated)。UTC与格林尼治平均时(GMT, Greenwich Mean Time)一样,都与英国伦敦的本地时相同。

看个例子:

console.log(new Date(Date.UTC(2020,0,23,9,55,55)))
//Thu Jan 23 2020 17:55:55 GMT+0800 (中国标准时间)

注意:

  • 月份输入会比输出-1,因为月是基于0 的,所以输入0输出Jan
  • UTC = 本地时间 - 0800 = 1755-0800 = 0155 中国位于伦敦以东,为正,所以减去对应时区差,求出UTC时间,与运行结果一致

(这一部分书上讲得很少,几乎都是自己理解+参考别人博客)

Date.now()返回表示调用这个方法时的日期和时间的毫秒数,在不支持这写法可以使用下面第二种写法获取时间戳,结果相同;一般用于计算运行速度

let now = Date.now()
console.log(now)//1579781768327
console.log(+new Date())//1579781768327
doSome() //执行某些函数

let result = +new Date() - now

继承方法

Date类型重写了toLocaleString()toString()valueOf(),具体结果依据浏览器不同而不同,valueOf()一般用来比较日期值

这里以火狐和谷歌为例:(两者相同)

console.log(new Date(2020,0,23).toString())
//Thu Jan 23 2020 00:00:00 GMT+0800 (中国标准时间)
console.log(new Date(2020,0,23).toLocaleString())
//2020/1/23 上午12:00:00
let a = new Date(2020,0,23).valueOf()
console.log(a)
//1579708800000
let b = new Date(2020,1,23).valueOf()
console.log(b)
//1582387200000
console.log(a < b)
//true

日期格式化方法

toDateString()–以特定于实现的格式显示星期几、月、日和年

toTimeString()–以特定于实现的格式显示时,分,秒,时区

toLocaleDateString()–以特定于地区的格式显示星期几、月、日和年

toLocaleTimeString()–以特定于地区的格式显示时,分,秒

toUTCString()–以特定于实现的格式完整的UTC日期

console.log(new Date(2020,0,23,20,55,55).toDateString())
//Thu Jan 23 2020
console.log(new Date(2020,0,23,20,55,55).toTimeString())
//20:55:55 GMT+0800 (中国标准时间)
console.log(new Date(2020,0,23,20,55,55).toLocaleDateString())
//2020/1/23
console.log(new Date(2020,0,23,20,55,55).toLocaleTimeString())
//下午8:55:55
console.log(new Date(2020,0,23,20,55,55).toUTCString())
//Thu, 23 Jan 2020 12:55:55 GMT

日期/时间组件方法

getTime()–返回日期的毫秒数,于valueOf()方法返回的值相同

getFullYear() --取4位数的年份(2020)

getMonth()–返回日期的月份,0表示1月份

getDate()–返回日期的天数,(1-31)

getDay()–返回日期中星期的星期几(0表示星期日,6表示星期六)

getHours()–返回日期的小时数(0-23)

getMinutes()–返回日期的分钟数(0-59)

getSeconds()–返回日期的秒数(0-59)

console.log(new Date(2020,0,23,20,55,55).getTime())
//1579784155000
console.log(new Date(2020,0,23,20,55,55).getFullYear())
//2020
console.log(new Date(2020,0,23,20,55,55).getMonth())
//0
console.log(new Date(2020,0,23,20,55,55).getDate())
//23
console.log(new Date(2020,0,23,20,55,55).getDay())
//4
console.log(new Date(2020,0,23,20,55,55).getHours())
//20
console.log(new Date(2020,0,23,20,55,55).getMinutes())
//55
console.log(new Date(2020,0,23,20,55,55).getSeconds())
//55

上一篇第四章

《JavaScript高级程序设计》目录

posted on 2020-01-23 00:05  furfur-jiang  阅读(188)  评论(0编辑  收藏  举报