什么是数组对象
JavaScrip中的数组对象可以使用new Array或字面量“[]”来创建,在创建以后,就可以调用数组对象提供的一些方法来实现对数组额度操作了。数组对象用于在单个变量中存储多个值,JavaScript的数组是弱类型的,所以允许数组中含有不同类型的元素,数组元素甚至可以是对象或者其他数组。
数组类型检测
数组类型检测有两种常用的方式,分别是使用instanceof运算符和使用Array.isArray()方法。
示例代码
var arr = []
var obj = {}
//第一种方式
console.log(arr instanceof Array) //输出结果:true
console.log(obj instanceof Array) //输出结果:false
//第二种方式
console.log(Array.isArray(arr)) //输出结果:true
console.log(Array.isArray(obj)) //输出结果:false
添加或删除数组元素
JavaScript数组对象提供了添加或删除元素的方法,可以实现在数组的末尾或开头添加新的数组元素,或在数组的末尾或开头移除元素。
方法如下:
方法名 | 功能描述 | 返回值 |
---|---|---|
push(参数1…) | 数组末尾添加一个或多个元素,会修改原数组 | 返回数组的新长度 |
unshift(参数1…) | 数组开头添加一个或多个元素(把数组长度-1,无参数),会修改原数组 | 返回数组的新长度 |
pop() | 删除数组的最后一个元素,若是空数组则返回undefined,会修改原数组 | 返回删除的元素的值 |
shift() | 删除数组的第一个元素,若是空数组则返回undefined,会修改原数组 | 返回第一个元素的值 |
示例代码
//push
var arr = ['pink', 'black', 'white', 'yellow']
console.log(arr.push('red')) //返回的是数组长度 输出结果为:5
console.log(arr) //修改了原来的数组 输出结果为['pink', 'black', 'white', 'yellow', 'red']
//unshift
var arr = ['pink', 'black', 'white', 'yellow']
console.log(arr.unshift('red', 'blue')) //返回的是数组长度 输出结果为:6
console.log(arr) //修改了原来的数组 输出结果为['pink', 'black', 'white', 'yellow', 'red', 'blue']
// pop
var arr = ['pink', 'black', 'white', 'yellow']
console.log(arr.pop());// 返回的是删除的元素 输出结果为:yellow
console.log(arr);// 修改了原来的数组 输出结果为['pink', 'black', 'white']
// shift
var arr = ['pink', 'black', 'white', 'yellow']
console.log(arr.shift());// 返回的是删除的元素(第一个) 输出结果为:pink
console.log(arr);// 修改了原来的数组 输出结果为['pink', 'black', 'white']
//注意
//push()和unshift()方法的返回值是新数组的长度,而pop()和shift()方法返回的是移除的数组元素。
案例
筛选数组
案例需求:要求在包含工资的数组中,剔除工资达到2000或以上的数据,把小于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]) //相当于:newArr[newArr.length] = arr[i]
}
}
console.log(newArr)
数组排序
JavaScript数组对象提供了数组排序的方法,可以实现数组元素排序或者颠倒数组元素的顺序等。
方法如下:
方法 | 功能描述 |
---|---|
reverse() | 颠倒数组中元素的位置,该方法会改变原数组,返回新数组 |
sort() | 对数组的元素进行排序,该方法会改变原数组,返回新数组 |
示例代码
//reverse
var arr = ['red', 'blue', 'green']
console.log(arr.reverse());//输出的结果为:['green', 'blue', 'red']
console.log(arr);// 改变原数组['green', 'blue', 'red']
//sort
//sort有两种情况:
//如果调用该方法时没有使用参数,按照字符编码的顺序进行排序
var arr1 = [1, 4, 5, 6, 73, 32, 22, 15]
//1.不传参数
console.log(arr1.sort()) //输出的结果为:[1, 15, 22, 32, 4, 5, 6, 73]
//2.传参数:参数是用来指定按某种顺序进行排列的函数
// 即a和b是两个将要被比较的元素
arr1.sort(function(a, b) {
return b - a //降序[73, 32, 22, 15, 6, 5, 4, 1]
return a - b //升序[1, 4, 5, 6, 15, 22, 32, 73]
})
console.log(arr1)
//注意
//reverse()和sort()方法的返回值是排序后的数组
//sort如果调用该方法时没有使用参数,按照字符编码的顺序进行排序
数组索引
在开发中,若要查找指定的元素在数组中的位置,可以利用Array对象提供的检索方法。
方法如下:
方法 | 功能描述 |
---|---|
indexOf() | 返回在数组中可以找到给定值的第一个索引,如果不存在,则返回-1 |
lastindexOf() | 返回指定元素在数组中的最后一个索引,如果不存在,则返回-1 |
示例代码
//indexOf()
- 参数1:要查找的元素
- 参数2:开始查找的位置
//注意:如果第二个参数是-1,表示从最后一个元素开始查找,-2表示从倒数第二个元素开始查找,以此类推。
var beasts = ['ant', 'bison', 'camel', 'duck', 'bison']
console.log(beasts.indexOf('bison')) //输出结果为:1
//找到第二个bison的索引
console.log(beasts.indexOf('bison', 2)) //输出结果为:4
console.log(beasts.indexOf('giraffe')) //查找不到'giraffe' 输出结果为:-1
//lastindexOf()
- 如果该值大于或等于数组的长度,则整个数组会被查找。
- 如果为负值,将其视为从数组末尾向前的偏移。即使该值为负,数组仍然会被从后向前查找。
- 如果该值为负时,其绝对值大于数组长度,则方法返回 -1,即数组不会被查找。
var animals = ['Dodo', 'Tiger', 'Penguin', 'Dodo'];
console.log(animals.lastIndexOf('Dodo')) // 输出结果为:3
console.log(animals.lastIndexOf('Tiger')) // 输出结果为:1
//注意
//默认都是从指定数组索引的位置开始检索,并且检索方式与运算符“===”相同,即只有全等时才会返回比较成功的结果。
案例
数组去重
案例需求:要求在一组数据中,去除重复的元素
//声明数组
function unique(arr){
var newArr = []
//遍历数组
for (var i = 0; i < arr.length; i++){
//判断新数组中是否有原数组中的元素
//indexOf结果为-1表示没有该元素
if (newArr.indexOf(arr[i]) === -1){
//没有的话就把该元素push到新数组中
newArr.push(arr[i])
}
}
return newArr;
}
//调用数组
var res = unique([1, 2, 3, 4, 3, 2])
console.log(res)
数组转换为字符串
在开发中,可以利用数组对象的join()和toString()方法,将数组转换为字符串。
方法如下:
方法 | 功能描述 |
---|---|
toString() | 把数组转换为字符串,逗号分隔每一项 |
join(‘分隔符’) | 将数组的所有元素连接到一个字符串中 |
示例代码
//toString()
var arr = ['a', 'b', 'c']
console.log(arr.toString()) //输出结果为:a,b,c
//join
- 参数可选:指定一个字符串来分隔数组的每个元素
- 如果需要,将分隔符转换为字符串()小括号里面填写的是指定的分隔符
- 如果省略,数组元素用逗号(,)分隔
- 如果separator是空字符串(''),则所有元素之间都没有任何字符
console.log(arr.join()) //输出结果为:a,b,c
console.log(arr.join('')) //输出结果为:abc
console.log(arr.join('-')) //输出结果为:a-b-c
其他方法
JavaScript还提供了很多其他常用的数组方法。例如,填充数组、连接数组、截取数组元素等。
方法如下:
方法名 | 功能描述 |
---|---|
fill() | 用一个固定值填充数组中指定下表范围内的全部元素 |
splice() | 通过删除或替换现有元素或者原地添加新的元素来修改数组,返回被删除项目的新数组 |
slice() | 数组截取,参数为slice(begin, end),包含 begin,但不包含end,返回被截取项目的新数组 |
concat() | 连接两个或多个数组,不影响原数组,返回一个新数组 |
注意:slice()和concat()方法在执行后返回一个新的数组,不会对原数组产生影响,剩余的方法在执行后皆会对原数组产生影响。
示例代码
//fill()
- 参数:value start end
- value:用来填充数组元素的值
- start:基于零的索引,从此开始填充,转换为整数。
- end:基于零的索引,在此结束填充,转换为整数。fill()填充到但不包含end索引。
const array = [1, 2, 3, 4]
//填充0,从数组索引2(包含)开始到4(不包含)结束
console.log(array.fill(0, 2, 4)) //输出结果为:Array[1, 2, 0, 0]
//填充5,从数组索引1(包含)开始
console.log(array.fill(5, 1)) //输出结果为:Array[1, 5, 5, 5]
//填充6
console.log(array.fill(6)) //输出结果为:Array[6, 6, 6, 6]
//splice()
- 参数:start deleteCount item1...
- start:执行修改的开始位置(从0计数)
- deleteCount:整数,表示要移除的数组元素的个数
- item1:要添加进去数组的元素
//从索引2的位置开始删除0个元素,插入“小红”
var myFriend = ["小米", "小明", "小张", "小李"]
var removed = myFriend.splice(2, 0, "小红")
console.log(myFrieng)
console.log(removed)
//运算后的myFriend: ["小米", "小明", "小红", "小张", "小李"]
//被删除的元素:[], 没有元素被删除
//从索引2的位置开始删除0个元素,插入“小刚”和“小蔡”
var myFriend = ["小米", "小明", "小张", "小李"]
var removed = myFriend.splice(2, 0, '小刚', '小蔡')
console.log(myFriend)
console.log(removed)
//运算后的myFriend: ["小米", "小明", "小刚", "小蔡", "小张", "小李"]
//被删除的元素:[], 没有元素被删除
//从索引3的位置开始删除1个元素
var myFriend = ["小米", "小明", "小刚", "小蔡", "小张", "小李"]
var removed = myFriend.splice(3, 1)
console.log(myFriend)
console.log(removed)
//运算后的myFriend: ['小米', '小明', '小刚', '小张', '小李']
//被删除的元素:['小蔡']
//从索引2的位置开始删除1个元素,插入“小兰”
var myFriend = ["小米", "小明", "小刚", "小蔡", "小张", "小李"]
var removed = myFriend.splice(2, 1, "小兰")
console.log(myFriend)
console.log(removed)
//运算后的myFriend: ['小米', '小明', '小兰', '小蔡', '小张', '小李']
//被删除的元素:["小刚"]
//从索引0的位置开始删除2个元素,插入"小兰"、"小蔡"和"小刚"
var myFriend = ["小米", "小明", "小张", "小李"]
var removed = myFriend.splice(0, 2, '小兰', '小蔡', '小刚')
console.log(myFriend)
console.log(removed)
//运算后的myFriend: ['小兰', '小蔡', '小刚', '小张', '小李']
//被删除的元素:['小米', '小明']
//从索引2的位置开始删除2个元素
var myFriend = ['小兰', '小蔡', '小刚', '小张', '小李'];
var removed = myFriend.splice(myFriend.length - 3, 2)
console.log(myFriend)
console.log(removed)
//运算后的myFriend: ['小兰', '小蔡', '小李']
//被删除的元素:['小刚', '小张']
//从索引2的位置开始删除所有元素
var myFriend = ['小兰', '小蔡', '小刚', '小张', '小李'];
var removed = myFriend.splice(2)
console.log(myFriend)
console.log(removed)
//运算后的myFriend: ['小兰', '小蔡']
//被删除的元素:['小刚', '小张', '小李']
//slice
- 参数:begin end
- begin:从该索引开始提取原数组元素(包含)
- end:在该索引处结束提取原数组元素(不包含)
//从索引2的位置开始截取
var array = ['小兰', '小蔡', '小刚', '小张', '小李']
var getArr = array.slice(2)
console.log(array)
console.log(getArr)
//运算后的array:['小兰', '小蔡', '小刚', '小张', '小李'];
//被截取的元素: ['小刚', '小张', '小李']
//从索引2的位置开始,截取到索引4的位置(包含2,不包含4)
var array = ['小兰', '小蔡', '小刚', '小张', '小李']
var getArr = array.slice(2, 4)
console.log(array)
console.log(getArr)
//运算后的array:['小兰', '小蔡', '小刚', '小张', '小李']
//被截取的元素: ['小刚', '小张']
//从索引2的位置开始,截取到数组的倒数第一个元素(不包含)
var array = ['小兰', '小蔡', '小刚', '小张', '小李']
var getArr = array.slice(2, -1)
console.log(array)
console.log(getArr)
//运算后的array:['小兰', '小蔡', '小刚', '小张', '小李']
//被截取的元素: ['小刚', '小张']
//截取后两个元素
var array = ['小兰', '小蔡', '小刚', '小张', '小李']
var getArr = array.slice(-2)
console.log(array)
console.log(getArr)
// 运算后的array:['小兰', '小蔡', '小刚', '小张', '小李']
// 被截取的元素: ['小张', '小李']
//concat
//连接两个数组
const letters = ['a', 'b', 'c']
const numbers = [1, 2, 3]
const concatArr = letters.concat(numbers)
console.log(letters) //['a', 'b', 'c']
console.log(concatArr) //['a', 'b', 'c', 1, 2, 3]
//连接三个数组
const num1 = [1, 2, 3]
const num2 = [4, 5, 6]
const num3 = [7, 8, 9]
const numArr = num1.concat(num2, num3);
console.log(numArr) //[1, 2, 3, 4, 5, 6, 7, 8, 9]
//将值连接到数组
const arr = ['a', 'b', 'c']
const newArr = letters.concat(1, [2, 3])
console.log(newArr) //['a', 'b', 'c', 1, 2, 3]
练习
var url = ‘http://www.martinhan.com/login?name=zs&age=18’
最后的输出结果为{name:zs;age:18}
var url = 'http://www.martinhan.com/login?name=zs&age=18'
function getParams(url){
//1.首先把网址分为2部分,用?分割
//2.得到?+1的索引位置
var index = url.indexOf('?') + 1
//3.得到?后面的字符串
var params = url.substr(index)
console.log(params) //name=zs&age=18
//4.把得到这串字符继续用&分隔开
var arr = params.split('&')
console.log(arr)
var o = {}
//5.把数组里面的每一项,继续用=分割
for(var i = 0; i < arr.length; i++){
var newArr = arr[i].split('=')
console.log(newArr)
//完成赋值操作
o[newArr[0]] = newArr[1]
}
return o
}
console.log(getParams(url))
什么是字符串对象
字符串对象使用new String()来创建,在String构造函数中传入字符串,这样就会在返回的字符串对象中保存这个字符串。字符串对于保存以文本形式表示的数据很有用。一些最常用的字符串操作是检查他们的长度,使用+和+=字符串操作符构建和连接它们,使用indexOf()方法检查子字符串的存在或者位置,或使用?>substring()方法提取子字符串。
语法
var str = new String('送你一朵小红花')
console.log(str)
console.log(str.length) //输出结果为:7
//看不到常见的属性和方法
var str1 = '送你一朵小红花'
console.log(str1)
根据字符串返回位置
字符串对象提供了用于检索元素的属性和方法。
方法如下:
方法 | 功能描述 |
---|---|
indexOf(‘要查找的值’,开始的位置) | 返回指定内容在原字符串中的位置,如果找不到就返回 -1;开始的位置是index索引号;参数2可选,规定在字符串中开始检索的位置。它的合法取值是0到string Object.length - 1。如省略该参数,则将从字符串的首字符开始检索 |
lastIndexOf(‘要查找的值’,开始的位置) | 从后往前找,只找第一个匹配的,如果没有找到匹配字符串则返回-1;参数2可选,规定在字符串中开始检索的位置。它的合法取值是0到string Object.length - 1。如省略该参数,则将从字符串的最后一个字符处开始检索 |
示例代码
//indexOf
//参数1:要搜索的子字符串
//参数2:可选
var str = new String('送你一朵小红花,送你一朵小红花')
//查找花首次出现的位置
var res = str.indexOf('花')
//从第七个位置查找花第一次出现的位置
var res2 = str.indexOf('花', 7)
console.log(str.length) //7
console.log(res) //输出结果:6
console.log(res2) //输出结果:14
//lastIndexOf
//参数1:要搜索的子字符串
//参数2:可选
var str1 = new String('to be or not to be')
//查找e从最后一个字符开始,第一次出现的位置
var res1 = str1.lastIndexOf('e')
//查找e从第8个位置开始倒数,第一次出现的位置
var res3 = str1.lastIndexOf('e', 8)
console.log(str1.length) //15
console.log(res1) //输出结果:17
console.log(res3) //输出结果:4
//注意
//indexOf和lastIndexOf都区分大小写
案例
案例需求:要求在一组字符串中,找到所有指定元素出现的位置以及次数。
var str = new String('To be, or not to be, that is the question.')
var index = str.indexOf('e')
console.log(index) //输出e出现的位置,此处输出结果为:4(首次出现)
var num = 0
while(index != -1){ //index != -1表示可以找到o的时候
console.log(index) //输出e出现的位置,此处输出结果为:4 18 31 35
index = str.indexOf('e', index + 1) //indexOf('要查找的对象',位置)
//从第一次出现的位置之后开始查找,再赋值给index
num++
}
console.log('e出现的次数是:' + num)
根据位置返回字符串
字符串对象提供了用于获取字符串中的某一个字符的方法。
方法如下:
成员 | 作用 |
---|---|
charAt(index) | 获取index位置的字符,位置从0开始计算 |
charCodeAt(index) | 获取index位置的字符的ASCII码 |
str[index] | 获取指定位置处的字符(HTML5新增)和charAt等效 |
示例代码
var str = 'andy'
//获取index位置的字符
console.log(str.charAt(0)) //输出的结果为;a
//获取index位置的字符的ASCII码
console.log(str.charCodeAt(0)) //输出结果为:97(a的ASCII码是97)
for(var i = 0; i < str.length; i++){
//获取指定位置处的字符
console.log(str[i])
}
案例
案例需求:使用charAt()方法通过程序来统计字符串中出现最多的字符和次数。
var str = 'Apple'
//第1步,统计每个字符出现的次数
var o = {}
for(var i = 0; i < str.length; i++){
var chars = str.charAt(i)
if(o[chars]){
o[chars]++
}else{
o[chars] = 1
}
}
console.log(o) //输出结果:{A: 1, p: 2, l: 1, e: 1}
var max = 0 //保存出现次数最大值
var ch = '' //保存出现次数最多的字符
for(var k in o){
if(o[k] > max){
max = o[k]
ch = k
}
}
//输出结果:"出现最多的字符是:p,共出现了2次"
console.log('出现最多的字符是:' + ch + ',共出现了' + max + '次')
字符串操作方法
字符串对象提供了一些用于截取字符串、连接字符串、替换字符串的属性和方法。
方法如下:
方法 | 作用 |
---|---|
concat(str1, str2, str3…) | concat()方法用于连接两个或多个字符串。拼接字符串,等效于+,+更常用该方法没有改变原有字符串,会返回连接两个或多个字符串新字符串 |
slice(start, [end]) | 截取从start位置到end(不包含end)位置之间的一个子字符串可提取字符串的某个部分,并以新的字符串返回被提取的部分 |
substring(start, [end]) | 截取从start位置到end位置之间的一个子字符串,基本和slice相同,但是不接收负值 |
substr(start, [length]) | 截取从start位置开始到length长度的子字符串从起始索引号提取字符串中指定数目的字符 |
toLowerCase() | 获取字符串的小写形式 |
toUpperCase() | 获取字符串的大写形式 |
split([separator, [limit]) | 使用separator分隔符将字符串分隔成数组,limit用于限制数量separator可选;limit可选,该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度 |
replace(str1, str2) | 使用str2替换字符串中的str1,返回替换结果,只会替换第一个字符 |
示例代码
var str = 'HelloWord'
//concat
var res = str.concat('!!')
console.log(res) //HelloWord!!
//slice
var res1 = str.slice(1, 5)
console.log(res1) //ello
//substring
var res2 = str.substring(3) //截取从下标为3开始,之后的内容
console.log(res2) //loWord
var res3 = str.substring(3, 7) //截取从下标为3开始,到7结束的内容(不包含7)
console.log(res3) //loWo
//substr
var res4 = str.substr(2, 5)
console.log(res4) //lloWo
//toLowerCase
var res5 = str.toLocaleLowerCase()
console.log(res5) //helloword
//toUpperCase
var res6 = str.toLocaleUpperCase()
console.log(res6) //HELLOWORD
//split
var str1 = 'How are you doing today?'
var res7 = str1.split(' ')
console.log(res7) //['How', 'are', 'you', 'doing', 'today?']
var res8 = str1.split()
console.log(res8) //['How are you doing today?']
var res9 = str1.split(' ', 3)
console.log(res9) //['How', 'are', 'you']
//replace
var res10 = str1.replace(' ', ',')
console.log(res10) //How,are you doing today?
案例
案例需求:用户名长度在3~10范围内,不能出现敏感词admin的任何大小写形式。
var res = prompt('请您输入用户名')
if(res.length < 3 || res.length > 10){
alert('用户名长度为3—10位,请您重新输入')
}else if(res.toLocaleLowerCase().indexOf('admin') != -1 || res.toUpperCase().indexOf('admin') != -1){
alert('不能出现敏感词admin')
}else{
alert('恭喜您,该用户名可以使用')
}
值类型与引用类型
在JavaScript中,简单数据类型(如字符串型、数字型、布尔型、undefined、null)又称为值类型,在存储时,变量中存储的是值本身,因此叫做值类型。
复杂数据类型(对象)又称为引用类型。引用类型的特点是,变量中保存的仅仅是一个引用的地址,当对变量进行赋值时,并不是将对象复制了一份,而是将两个变量指向了同一个对象的引用。
示例代码
字符串的不可变指的是里面的值不可变, 看上去可以改变内容,其实是地址变了,新开辟了一个内存空间。
var str = 'abc'
str = 'hello'
//当重新给str赋值的时候,常量'abc'不会被修改,依然在内存中
//重新给字符串赋值,会重新在内存中开辟空间,这个特点就是字符串的不可变
//由于字符串的不可变,在大量拼接字符串的时候会有效率问题
var str = ''
for(var i = 0; i < 100000; i++){
str += i
}
console.log(str) //这个结果需要花费大量时间来显示,因为需要不断的开辟新的空间
案例
obj1和obj2指向了同一个对象。
//创建一个对象,并赋值给变量obj1
var obj1 = {name: '小明', age: 18}
//此时并没有复制对象,而是obj2和obj1两个变量引用了同一个对象
var obj2 = obj1;
//比较两个变量是否引用同一个对象
console.log(obj2 === obj1) //输出结果:true
//通过obj2修改对象的属性
obj2.name = '小红'
//通过obj1访问对象的name属性
console.log(obj1.name) //输出结果:小红
上述代码运行后,obj1和obj2两个变量引用了同一个对象,此时,无论是使用obj1操作对象还是使用obj2操作对象,实际操作的都是同一个对象。
当obj1和obj2两个变量指向了同一个对象后,如果给其中一个变量(如obj1)重新赋值为其他对象,或者重新赋值为其他值,则obj1将不再引用原来的对象,但obj2仍然在引用原来的对象。
var obj1 = {name: '小明', age: 18}
var obj2 = obj1
//obj1指向了一个新创建的对象
obj1 = {name: '小红', age: 17}
//obj2仍然指向原来的对象
console.log(obj2.name) //输出结果:小明
注意:
当一个对象只被一个变量引用的时候,如果这个变量又被重新赋值,则该对象就会变成没有任何变量引用的情况,这时候就会由JavaScript的垃圾回收机制自动释放。
如果在函数的参数中修改对象的属性或方法,则在函数外面通过引用这个对象的变量访问时的结果也是修改后的。
function change(obj){
obj.name = '小红' //在函数内修改了对象的属性
}
var stu = {name: '小明', age: 18}
change(stu)
console.log(stu.name) //输出结果:小红
在上述代码中,当调用change()函数后,在change()函数中修改了obj.name的值。修改后,在函数外面通过stu变量访问到的结果是修改后的值,说明变量stu和参数obj引用的是同一个对象。