前言
引用类型的值是引用类型的一个实例,引用类型是一种数据结构,用于将数据和功能组织到一起。它通常被称为类。引用类型有时候也被称为对象定义。对象是某个引用类型的实例。新对象是使用new操作符后跟一个构造函数创建(构造函数本身就是一个函数)。
1. Object类型
目前看到大多数引用类型都是Object类型的实例。object类型在应用程序中存储和传输数据而言,是一个理想的选择。
创建Object实例的方式有两种。第一种是使用new操作符后跟一个构造函数。第二种是使用对象字面量的形式创建。如下:
//1. new 操作符后跟构造函数创建Object实例
var person = new Object()
person.name = 'nike'
person.age = '25'
//2. 对象字面量的形式创建Object实例,在通过对象字面量的方式定义对象时,实际上是不会调用Object构造函数。
var person = {
name: 'nike',
age: 29 //注意这里后面不能加逗号了,因为会在IE7和Opera中导致错误
}
2. Array类型
JavaScript中,数组存储的是一组有序列表,与其他语言不同的是Js中数组的每一项是可以存储任何类型的数据。而且Js中数组的大小(长度)是可以动态调整。
创建数组的基本方式有两种:第一种是通过Array构造函数的方式,第二种是是通过数组字面量的方式进行创建。如下:
var arr = new Array() //创建了一个空数组存储到变量arr中 : []
var arr = new Array(4) //创建了一个数组长度为5,每个元素为undefined的数组: [undefined,undefined,undefined,undefined,undefined]
var arr = new Array(1,2,3) //创建一个长度为3,数组元素分别为1,2,3的数组:[1,2,3]
注意,在使用构造函数创建数组的时候可以省略掉new操作符:
var colors = Array(3)
var names = Array('gray')
再看下数组字面量的方式创建数组:
var colors = ['red','blue','yellow']
var arr = []
var value = [1,2,]//这样可能会创建长度为2或3的数组,不支持这样!!
var opt = [,,,,,]//这样可能会创建长度为5或6的数组,不支持这样!!
在只用数组字面量的形式创建数组时和对象一样,也不会调用Array构造函数。
数组中的项数是可以动态改变的,看下下面的例子及说明:
var arr = [1,2,3]
arr[5] = 5
console.log(arr) //'[1,2,3,undefined,undefined,5]'
var arr = [1,2,3]
arr.length = 2
console.log(arr) // [1, 2]
var arr = [1,2,3]
arr.lenght = 5
console.log(arr) //'[1,2,3,undefined,undefined,undefined]'
- 检测数组
第一种通过instanceof操作符:
arr instanceof Array
第二种通过 Array.isArray()方法,这个方法最终确定某个值到底是不是数组,而不管它是在哪个全局环境中创建的。
Array.isArray(arr)
- 转换方法
所有对象都具有 toLocaleString(), toString(), valueOf()方法。其中调用数组的 toString() 方法会返回由数组中每个值的字符串形式拼接而成的一个由逗号分隔的字符串,而调用valueOf()返回的还是数组。实际上为了创建这个字符串会调用数组每一项的toString()方法。
var colors = ['red', 'blue', 'green']
console.log(colors.toString()) //"red, blue, green"
console.log(colors.valueOf()) //['red', 'blue', 'green']
console.log(colors) //["red", "blue", "green"]
alert(colors)// alert接受字符串为参数,所有在后台会调用toString方法
toLocaleString()方法经常也会返回和toString()和valueOf()方法相同的值,当调用数组的toLocaleString()方法时,它会创建一个数组值得以逗号分隔的字符串。而与前两个方法不同的是它是调用每一项的toLocaleString()方法,而不是toString方法。
var person1 = {
toLocaleString: function(){ return 'nike'},
toString: function () {return 'lining'}
}
var person2 = {
toLocaleString: function(){ return 'apple'},
toString: function () {return 'orange'}
}
var arr = [person1, person2]
alert(arr) // 'lining, orange'
alert(arr.toString()) 'lining, orange'
alert(arr.toLocaleString()) //'nike, apple'
join()方法可以将组数组合并为一组字符串然后返回。
var arr = [1,2,3]
var a = arr.join() //"1,2,3"
var b = arr.join('|') // "1|2|3"
注意:如果数组中某一项是null或者undefined,那么该值在join(),toLocaleString(), toString()和valueOf()方法返回的结果中用空字符串表示。
- 栈方法
push(), pop()分别是在数组最后添加元素和从末尾移除最后一项,然后修改数组的长度。
首先看下push()方法,可以从数组后推入任意项,且可以为任意数据类型。
var arr = [1,2,3,4]
var res = arr.push(5)
console.log(arr) //[1,2,3,4,5]
console.log(res) // 5
var arr2 = [1,2,3]
var res = arr2.push(4,5)
console.log(arr2) // [1,2,3,4,5]
console.log(res) // 5
var arr3 = [1,2,3]
var res = arr3.push([1,2])
console.log(arr3) // [1,2,3, [1,2]]
console.log(res) // 4
在看下pop()方法,会移除数组最后一项,并返回移除项。
var arr = [1,2,3,4,5]
var res = arr.pop() //5
注意:以上的push()和pop()方法都会改变原数组的数据结构。
- 队列方法
数组的队列方法有shift()和unshift()。shift()方法是从数组前端移除一项并返回该项。unshift()是在数组前端添加任意项,并返回数组长度。
var arr = [1,2,3,4]
var res = arr.unshift(1)
console.log(arr) // [1,1,2,3,4]
console.log(res) // 5
var arr1 = [1,2,3,4]
var res = arr.unshift(1,2)
console.log(arr1) //[1,2,1,2,3,4]
console.log(res) //6
var arr2 = [1,2,3]
var res = arr2.unshift([1,2])
console.log(arr2) //[[1,2], 1, 2, 3]
console.log(res) // 4
再看下shift()方法,从数组最前面移除一项,然后返回该项:
var arr = [1,2,3,4]
var res = arr.shift()
console.log(arr) //[2,3,4]
console.log(res) // 1
- 重排序方法
数组中有两个排序方法reverse()和sort()。reverse()是反转数组项的顺序,会改变原数组。
var arr = [1,2,3,4]
arr.reverse() //[4,3,2,1]
console.log(arr) //[4,3,2,1]
sort()方法默认是按照升序排列数组项,sort方法会调用每一项的toString方法,然后比较得到的字符串,以确定如何排序。
var val = [0,1,5,10,15]
val.sort()
console.log(val) //[0,1,10,15,5]
然而,sort可以接受一个比较函数作为参数,以便指定哪个值位于哪个值前面或者后面,比较函数接受两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回0,如果第一个参数位于第二个参数后,则返回正数。
- 操作方法
1. concat()
关于数组的操作方法有很多,除了上面说的几个方法外,这里要介绍一些常用的方法。
首先看下 concat() 这个方法,该方法会基于当前数组的所有项再创建一个新的数组,具体的说就是该方法会创建一个当前数组副本,然后将接受到的数据添加到这个副本末尾,最后返回新的数组。在没有个concat方法传参数的情况下,它只是复制当前数组并返回副本,如果传递给concat方法的是一个或者多个数组,则该方法是将这些数组中的每一项都添加到结果数组中,如果传递的不是数组,这些值就会简单的被添加到数组末尾。
var arr= [1,2,3,4]
var arr2 = arr.concat('yellow', ['blue', 'red'])
console.log(arr) //[1,2,3,4]
console.log(arr2) //[1,2,3,4,'yellow', 'blue', 'red']
2. slice()
再看下第二个方法slice()它能基于当前数组的一个或者多个项创建一个新数组。slice()可以接受一个或者两个参数,即要返回项的起始和结束位置,只有一个参数的情况下,slice会返回从该参数指定位置开始到当前数组末尾的所有项。如果是两个参数,会返回起始位置到结束位置之间的项(不包括结束位置)。注意,slice也不会影响原数组。
var arr = [1,2,3,4,5,6,7]
var res1 = arr.slice(1) //[2,3,4,5,6,7]
var res2 = arr.slice(1,4)//[2,3,4]
看下几个特殊情况:
var arr = [1,2,3,4,5,6]
var res1 = arr.slice(-3) //[4,5,6]
var res2 = arr.slice(-6, -3) //[1,2,3]
var res3 = arr.slice(4, 3) //[]
如上,如果传的是负数的话是从后往前数,如果第二个参数比第一个小的话则返回空数组。
3. splice()
这个方法可以对数组进行删除,插入,替换操作。注意该方法会改变原数组
首先看下删除功能:
var arr = [1,2,3,4,5]
var res = arr.splice(0, 2) //从下标0开始删除2个元素
console.log(arr) //[3,4,5]
console.log(res) //[1,2]
再看下插入功能, 可以向指定位置插入任意数量的项:
var arr = [1, 2, 3, 4, 5]
var res = arr.splice(0, 0, 1,2,3) //可以插入多个和单个数据
console.log(arr) //[1,2,3,1,2,3,4,5]
console.log(res) //[],返回的是一个空数组
接下来再看下替换功能了,相信大家也知道该怎么去操作了:
var arr = [1,2,3,4,5]
var res = arr.splice(0, 3, 'a','b','c')
console.log(arr) //["a", "b", "c", 4, 5]
console.log(res) //[1, 2, 3]
splice始终会返回一个数组,该数组包含从原数组中删除的项,如果没有删除则返回一个空数组。
- 位置方法
数组中位置查找的方法有两个 indexOf和lastIndexOf() ,这两个方法都接受两个参数,要查找的项和查找的起始位置。第二个参数是可选的,如果不传分别表示从数组的开头和结束进行查找。这两个方法会返回查找到的项的位置下标,如果没有找到的话则返回-1,在查找的时候会使用严格等于进行查找(===)。
var arr = [1,2,3,4,5]
console.log(arr.indexOf(1)) //返回0
console.log(arr.indexOf("1")) //返回-1, 因为是基于严格等于的。
var arr = [1, 2, 3, 4, 5, 1]
arr.lastIndexOf(1) // 5 , 因为是从最后开始查找
- 迭代方法
数组的迭代方法有5种,每个方法都接受两个参数:要在每一项上运行的函数和运行该函数的作用于对象(可选,影响this的值)。在每项上运行的函数可以接受三个参数:数组的每一项,当前项的下标,数组对象本身。
(1). 第一个迭代方法every():对数组的每一项运行给定函数,如果该函数对每一项都返回true,则返回true
var arr = [1, 2, 3, 4, 5]
var res = arr.every(function(item, index, array) {
if(item == 1 || item == 2) {
return true
}else {
return false
}
})
console.log(res) //false
var arr = [1, 2, 3, 4, 5]
var res = arr.every(function(item, index, array) {
return true
})
console.log(res) //true
(2). 第二个迭代filter()方法,对数组的每一项运行给定函数,返回该函数会返回true的项。
var arr = [1, 2, 3, 4, 5]
var res = arr.filter(function(item, index, array){
if(item == 1 || item == 3 || item == 5){
return true
}
})
console.log(res) //[1, 3, 5]
(3). 第三个迭代方法forEach(),对数组的每一项运行给定函数,没有返回值。
var arr = [1, 2, 3, 4, 5]
var res = arr.forEach(function(item, index, array) {
return item+1
})
console.log(res) //undefined
(4). 第四个迭代方法map():对数组的每一项运行函数,返回函数每次调用的结果组成的数组。
var arr = [1, 2, 3, 4, 5, 6]
var res = arr.map(funtion(item, index, array) {
return item + '元'
})
console.log(res) // ["1元", "2元", "3元", "4元", "5元", "6元"]
(5). 第五个迭代方法some():对数组的每一项执行函数,如果函数对任意一项返回true则返回true。
var arr = [1,2,3,4,5,6]
var res = arr.some(function(item, index, array){
if(item > 3) {
return true
}else {
return false
}
})
console.log(res) //true
- 归并方法
这里还有两个归并数组的方法:reduce() 和reduceRight() ,这两个方法会迭代数组中所有的项,然后返回一个最终的值。其中reduce()方法从数组的第一项开始遍历直到数组的最后一项。而reduceRight() 则是从数组最后面开始遍历到第一项。
这两个方法都有两个参数:在每一项上调用的函数和作为归并基础的初始值。然后在每一项上都会执行的函数会接受到四个参数:前一个值,当前值,项的索引,数组对象。这个函数返回的任何值都会作为第一个参数自动传给下一项。第一次迭代发生做数组的第2项上,所以第一个参数是数组的第一项,第二个参数就是数组的第二项。
var arr = [1, 2, 3, 4, 5]f
var sun = arr.reduce(function(pre, next, index, arr) {
return pre+next
})
console.log(sun) //15
reduceRight() 只不过是从数组的后面开始进行,其他的操作都是一样的。