JavaScript高级程序设计之引用类型(上)
引用类型是比较复杂的一种类型。在面向对象的编程中,会经常用到引用类型,可以说它是编程语言的核心。在JS中内置了几种引用类型,下边会进行一一的介绍。
内置引用类型
Object类型
1、声明方式:直接使用new操作符(const Data = new Object())和使用对象字面量(const Data = {})两种方式。使用对象字面量方式声明的话,花括号内可以写属性和方法,也可以什么都不写。需要注意的是虽然什么都不写,但对象并不是空对象,它会包含一些默认的属性和方法。
2、访问值:可以使用对象名直接点属性名访问值(const Data = {name:123}; console.log(Data.name)),也可以对象名方块号,方括号内写属性名访问值(const Data = {name:123}; console.log(Data["name"]))。使用方括号访问时,方括号内可以写变量。
Array类型
JS的数组和其它编程语言数组有些不同,它的值可以是任何类型,字符串、数值、对象都可以,而且它的长度是动态的,会随着值得增加而动态调整。声明数组的方式也分两种(数组最多包含4294967295个值),第一种使用构造函数(const a = new Array()),第二种使用字面量(const a = [])。使用构造函数的方式创建数组,可以传参,也可以不传参,不传参的话,数组将是一个长度为零的数组,传参的话,共支持两种传参方式,例:
1 //构造函数创建方式 2 let b = () =>{ 3 const a = new Array(); //不传参,创建length为零的数组 4 5 console.log(a) 6 } 7 8 b = () =>{ 9 const a = new Array(3); //创建长度为3的数组 10 11 console.log(a[2]); //由于没有值,所以为undefined 12 } 13 14 b = () =>{ 15 const a = new Array("blue","green","red"); //创建长度3并且含有3个值得数组 16 17 console.log(a[2]); //由于有值,所以值为red 18 }
字面量创建方式例:
1 //字面量创建方式 2 b = () =>{ 3 let a = ["3","5","6"]; //创建一个数组 4 5 a = [1,2,]; //创建两个值得数组,ie创建三个值得数组 6 7 a = [,,,,,,]; //由于没有写具体值,数组里边的值都是undefined 8 9 a.length = 3; //修改长度会改变数组,所以可以通过修改长度来删除值。 10 11 a[7] = 5 //给数组新增一个值。长度变8,间隔之间的部分会被undefined代替。 12 13 console.log(a[1]); //访问数组的中第2个值 14 }
数组检测
JS数组提供了两种检测数组的方式,第一种是用Instanceof操作符,来判断变量是否是Array的实例。不过这种检测方式存在一个问题,就是当时用多个框架的时候,另一个框架也拥有自己封装的Array构造函数,这时候就会出现问题,你无法去确定变量是否是原生的Array。第二种使用ES5的新API,Array.isArray()方法。ES5之所以提出这个方法,就是为了解决第一种方法存在的问题。例:
1 const a = ()=>{ 2 const b = [3,2,4,1]; 3 //instanceof操作符检测 4 const c = b instanceof Array; //返回true 5 6 //Array.isArray 7 8 const d = Array.isArray(b); //返回true 9 }
转换方法
数组的转换方式有toString()、toLocalString()、valueOf()、join()几种。toString()会把数组变为以逗号分隔的字符串,转换时,后台会调用每个值自己的toString()方法。toLocalStirng()转换的结果和toString()的结果一般是相同的,也是一逗号分隔的字符串,不同的是,转换时,后台调用的是每个值得toLocalString()方法。valueOf()返回数组。join()接收一个参数,指定数组以什么字符,作为连接符,来把数组连接成字符串。参数如果不传或是undefined的话,会默认以逗号连接各项值。例:
1 const ah = () =>{ 2 const b = [3,2,4,1]; 3 4 const c = { 5 toString:()=>{return "y"}, 6 toLocaleString:()=>{ return "y" } 7 }, 8 d = { 9 toString:() =>{return "x"}, 10 toLocaleString:()=>{ return "x"} 11 }, 12 f = [c,d]; 13 14 b.toString() // "3,2,4,1" 15 16 b.toLocaleString() //"3,2,4,1" 17 18 b.valueOf() //3,2,4,1 19 20 b.join("-")//"3-2-4-1" 21 //由于后台会调用每个值得toString方法,所以值为"y,x" 22 f.toString() //"y,x" 23 24 f.toLocaleString() //"y,x" 25 }
栈方法(pop和push)
栈是一种后进先出的数据结构,而pop和push实现了它的这种特点。例:
1 //栈方法 2 const strack = ()=>{ 3 let a = [1,2]; 4 5 a.push(3) //后进,在数组的尾部添加元素,并返回新长度 6 7 a.pop() //先出,在数组的尾部删除一个元素,并返回被删除的项 8 }
队列方法(shift)
队列是一种先进先出的数据结构,JS中通过push和shift模拟队列,通过unshift和pop实现反向队列。下边请看具体例子:
1 //队列方法 2 3 const queque = () =>{ 4 let a = [3,4]; 5 6 //正向队列 7 a.push(5); //向数组尾部添加元素 8 a.shift(); //在数组头部删除元素,并返回删除的项 9 10 //反向队列 11 a.unshift(3) //在数组的头部添加元素,并返回新长度 12 a.pop() //从尾部删除元素,并返回被删除的项 13 }
排序方法(reverse 和 sort)
1 //排序方法 2 const sort = ()=>{ 3 let a = [4,3,5]; 4 5 //reverse 和 sort都换把排完序的新数组返回出来 6 a.reverse() //翻转数组顺序 7 8 a.sort() //会把每个项的值转成字符串进行比较,因此排序结果不尽如意,通常是传入回调函数来实现排序。 9 10 a.sort((val1,val2)=>val1>val2); //3,4,5 11 }
操作方法(concat 、slice和splice)
1 //操作方法 2 const dos = ()=>{ 3 let b = [3,5,3]; 4 //把传入的数组货值,连接生成一个新的数组并返回 5 let d = b.concat() //由于没有传参数,返回的是原数组的一个副本 6 d = b.concat("5",["9","10"]) //返回值[3,5,3,5,9,10] 7 //在数组指定位置开始截取,返回截取后生成的新数组。 两个参数start and end, 8 //只传start,会一直截取到末尾。 参数支持负值。参数为负值的话,会通过数组长度加上 9 //参数值,来确定位置 10 b.slice(1) //[5,3] 11 b.slice(1,2) //[5] 12 b.slice(-1) //[3] 13 b.slice(-3,-1)//[3,5] 14 b.slice(-1,-2) //起始位置大于结束位置,返回空数组 15 //会根据其传入的参数,来确定是删除、插入和替换操作.第一个参数为起始位置 16 //第二个参数为删除几个。第三个参数为要插入的新值 17 //splice会改变原数组 18 b.splice(0,1) //删除操作 返回[3] 19 b.splice(0,0,4) //插入操作 [4,3,5,3] 20 b.splice(0,1,4)//替换操作 [4,5,3】 21 22 }
位置方法(indexOf 和 lastIndexOf)
1 const position = () =>{ 2 const pos = [4,3,2]; 3 //查找数组内是否存在该元素,存在返回元素位置,不存在返回-1.查找规则,按===比较。 4 pos.indexOf(3) // 返回1 5 6 //与indexOf相似,不同之处,lastIndexOf在数组的末尾开始查找。 7 pos.lastIndexOf(3) //返回1 8 }
迭代方法
1 //迭代方法 2 const fors = () =>{ 3 const d = [3,4,5,6]; 4 //判断结果都为true是返回true。参数为回调函数,回调函数有三个参数,1当前项。2索引。3数组对象 5 d.every(e=>e>5); 6 //判断结果有一个为true,返回true。使用方式与every相同 7 d.some(e=>e>5) 8 //返回符合条件的值,并生成一个新数组 9 d.filter(e=>e>5) 10 //返回运算后的值,并生成一个新数组 11 d.map(e=>e-1) 12 //单纯执行迭代操作 13 d.forEach(e=>console.log(e)) 14 }
1 const c = ()=>{ 2 const f = [3,4,5,6]; 3 //对数组进行累加(减、乘、除)操作,并返回其结果。回调函数有两个参数,第一个为上一次元素的结果,第二个为当前项 4 f.reduce((sum,val)=>sum + val); 5 //与reduce相同,但是从末尾到开始进行循环 6 f.reduceRight((sum,val)=>sum + val); 7 }