第九章 常用得存值结构
1. 字符串和字符串API
字符串不会修改原数据。
字符串是不能轻易修改得,只能提取。(因为包装对象的存在)
str = str + asd.左边的改变,等号右边的str不会改变。
length属性
返回字符串中字符得长度
let str = 'asd ';
str.length = 1;//无法手动修改,只读
console.log(str.length);//4
获取字符串中得下标得值,也不可修改charAt或者[]
返回字符串下标得值,下标从0开始
let str = "asdf";
str[0];//"a" 低版本ie不兼容
str[5]; //undefined
str.charAt(0);//"a"
str.charAt(5); //"" 访问不到对应的字符则返回空字符串,保证类型一致
charAt:绝对会返回字符串,而且传入值不准确的时候他会进行转换
字符串拼接 concat或者+
返回新得字符串
let str1 = "asd",
str2 = "fgh";
let str3 = str1.concat(str2,"j");//"asdfghj"
let str4 = str1+str2+"j";//"asdfghj"
在字符串中查询某字符是否存在,存在返回下标,不存在返回-1;
返回第一次出现得下标indexOf
let str = "asdfgh";
str.indexOf("d");//2
str.indexOf("A");//-1
返回最后一次出现得下标lastIndexOf
let str = "大家好,我是渣渣辉";
str.lastIndexOf("辉");//8
str.lastIndexOf(",");//-1
- 返回单个字符得unicode编码 和通过编码返回单个字符
charCodeAt:返回当前字符的ASCII码
let str = "银时";
str.charCodeAt(0);//38134
str.charCodeAt(1);//26102
String.fromCharCode:通过ASCII码转换为对应的字符。可以传入若干个ASCII码,返回对应的字符。
String.fromCharCode(38134,26102);
字符串裁切
slice,从下标哪开始,结束,可以有至少1个参数最多两个参数。参数为0则整体提取。
let str = "box-1";
let str2 = str.slice(0,3);
//"box" 从下标0开始到下标3结束,一共3个字符,区间[0,3)
str2 = str.slice(2);//"x-1" 从第2位开始,到结束
str3 = str.slice(-1);//"1" 从最后一位开始到结束,可以是负数 -3则最后3位,2的话则除了前2位
-1最后一位。0第一位
"abcd".slice(2,-2) //""
substring和substr
substring接受两个参数,起始下标和结束下标(不支持负数)
substr接受两个参数,起始下标(可正可负)和长度
replace:替换满足条件的第一个元素。(需要修改的内容,修改的结果)
toUpperCase:所有字母变大写
toLowerCase:所有字母变小写
自行测试
字符串切割
split,返回一个数组:传入一个参数,表示切得方法
let str = "1,2,3";
let arr = str.split("");//["1",",","2",",","3"]
arr = str.split(",");//["1","2","3"] 以逗号作为分隔切分
复杂得切分方法用正则,后面讲
- trim 删除字符串前面和后面得空格,返回
let str = " asdasd asd ";
str.trim();//"asdasd asd"
2. 数组和数组API
new array()生成的array创世神
数组是一种特殊得对象:可以通过下标访问数组中得每一项,并且每一项下标从0开始递增,不存在得下标返回undefined
可以修改原数组,字符串不可以(包装数组)
对原数组进行操作。
- length同字符串,返回数组长度
var arr = [1,2,3];
console.log(arr.length);//3
arr.length = 6
arr //[1,2,3,empty*3]
arr.length = 2
arr //[1,2] //改小了之后,超出的部分会直接消失,下次改回来都访问不到
- 拼接数组,类似于字符串concat,返回拼接得数组,原数组不变,多个参数拼接添加
let arr = [1,2];
arr.concat(3,[4,5],[6]);//[1,2,3,4,5,6]
- every对每一个项判断,都满足返回true,接受一个回调函数(以参数形式传入得函数,此函数依次接收数组每一项作为参数,返回true/false)
let arr = [1,2,4];
arr.every(function(i){
return i>0
})//true 返回一个结果,对1,2,4判断,都大于0就返回true
//等价写法
arr.every(i=>i>0);//true 用箭头函数返回
- indexOf 等同于str的获取下标,传入一个参数,返回相等的元素的下标,没有返回-1
- lastIndexOf同理
- 往数组末尾传入若干个元素push,原数组改变
const arr = [1,2];//常量数组,没有直接赋值,但是可以对引用操作
arr.push({},[1,2,3]);//[1, 2, {…}, Array(3)]
- 删除数组最后一个元素并返回删除的元素,原数组改变 pop
let arr = [1,2,3];
arr.pop();//3
console.log(arr);//[1, 2]
- 从数组开始位置之前添加若干元素unshift
let arr = [1,2,3];
arr.unshift(...[2,3,4]);//[2, 3, 4, 1, 2, 3] 将数组[2, 3, 4]拆分成三个数据依次传入
- 删除数组第一个元素并返回删除的元素,原数组改变shift
let arr = [1,2,3,5];
arr.shift();//1
console.log(arr);//[2,3,5]
- 数组截取slice,第一个参数传入开始截取下标,第二个参数传入结束截取下标(可以不写,表示到结尾),原数组不变,左闭右开
let arr = [0,1,2,3,4,5];
arr.slice(2,3);//[2]
- 翻转数组reverse并返回,改变原素组
let arr = [1,2,3];
arr.reverse();//[3, 2, 1]
console.log(arr);//[3, 2, 1]
- 数组转字符串拼接join,并返回,传入一个参数,拼接方法,不写默认为","
let arr = [3,1,2];
arr.join();//"3,1,2"
arr.join("");//"312"
arr.join("+");//"3+1+2"
数组截取或者中途添加,改变原数组 splice,返回被截取的数组。
接受三个参数
第一个:必须,从哪个位置开始截取
第二个:非必须,截取长度,不写就是截取完
第三个及以后:非必需,在截取的位置添加。
let arr = ["原","始","数","据"];
arr.splice(2,2,"新","的","数","据");//
- 将数组转化成字符串,类似于join,不改变原数组
let arr = [1,2,3,4];
arr.toString()//"1,2,3,4"
排序sort
数组的排序都是需要数组里的值两两比较
接受的参数:回调函数(接受两个参数),一个是任意一个数a,一个是任意另一个数b
a:数组里靠前的数
b;数组里靠后的数
回调函数有返回值,参数a-b:则是从小到大排列,
参数b-a:则是从大到小排列
对数字正确排序,但是对字符根据每位字符排序.
虽然确实严格将数组进行了排序,但是是按照各自每一位的ascii码进行排序的。元素转换成为了字符串进行排序。
自己也可以定义排序的方法:从大到小,从小到大,瞎拍
[1,4,7,8,5,2].sort();//[1, 2, 4, 5, 7, 8]
["s","as","ad"].sort();//["ad", "as", "s"]
let arr = [11,22,5,4,32,7,8]
let newArr = arr.sort(function(a,b){
return a-b
// return b-a //反向排列
})
console.log(newArr) //4,5,7,8,11,22
数组乱排:.sort(()=>Math.random( ) - .5)
返回一个-0.5到0.5直间的数
let arr = [1,2,3,4,5,6,7,8,9]
let newArr = arr.sort(()=>Math.random)
console.log(newArr)
//排序会改变原数组,并且返回的就是原数组
//数组乱排
冒泡排序:性能比较差
//实现以下从小到大,挨个两两比较,最大的永远在最后面,进行数组长度次的比较,所有元素归为冒泡
let arr = [3,5,2,6,1,7,9,8,4,10]
for(let j = 0;j < arr.length;j++){
for(let i =0;i < arr.length -1;i++){
if(arr[i] > arr[i + 1]){ //如果前面的大于后面的则交换位置
let temp = arr[i]
arr[i] = arr[i+1]
arr[i+1] = temp
}
}
}
//1,2,3,4,5,6,7,8,9,10
//for i 中,代表的是第一次冒泡的结果
//for j 中,代表的是n次完成,每次冒泡完成之后的结果
3. 引用类型对象和值类型对象
数据得保存类型分为两种:按存储方式分为值类型和引用类型
先说结论:只有对象为引用类型数据。其余都是值类型
引用类型有: 数组 对象 函数。
引用类型在储存得时候储存得是它得地址,在内存中只需要修改变量得引用位置就行了
let arr1 = [],
arr2 = [];
console.log(arr1==arr2);//false
为什么是false,这段代码做了什么?创建了一个数组,将数组得地址赋值给arr1,再创建一个数组,将数组得地址赋值给arr2,比较这两个变量指向得地址得对象是不是同一个,所以不会相等
let obj = {};//{}被obj引用
obj=null;//清除obj引用{},此时{}没人引用,辣鸡,被清理
let a = {"name":"Gin"}
function change(o){
o.age={};
return o;
}
change(a)===a;//true
let a = b = {};
b.a = 12
console.log(a);// {a:12}
自己得属性里也可以引用自身
let a ={}
a.b = a;
console.log(a);//{b:{b:{...}}}
这里不会报错是因为只是建立了一个引用关系。
4. JSON 格式对象
JSON全称JavaScript对象格式(JavaScript Object Notation)。是JS原生的数据存储格式。书写方式和对象非常类似,并且更加严格。尤其是属性名需要加引号,属性之间以逗号分隔。最后一个属性不加逗号,值可以是数组可以是对象嵌套,获取以及修改的方式。
存储在JSON格式的文件中。
{
"name":"Gin",
"own":[
"apple",
"banana",
"pen"
],
"type":{
"age":18,
"intrests":[
"1",
"2",
"3"
]
}
}
本质上json和对象或者数组没有本质区别,json有对应的变字符串和转json方法
let myjson = {
"name":"Gin",
"own":[
"apple",
"banana",
"pen"
],
"type":{
"age":18,
"intrests":[
"1",
"2",
"3"
]
}
}
let jsonString = JSON.stringify(myjson);
//"{"name":"Gin","own":["apple","banana","pen"],"type":{"age":18,"intrests":["1","2","3"]}}"
let json = JSON.parse(jsonString);//转化成对应的对象结构
5.foreach方法(遍历数组)除了for循环
直接使用数组方法进行数组遍历.
for循环代码成本高,有了foreach就不用for循环了。
forEach 循环每一个元素,
是一个foreach函数,传入的参数是什么?
接受一个参数,这个参数是一个回调函数。根据数组的长度执行了相同次数的回调函数。
也可以接受两个参数,一个是回调函数,一个是回调函数的this指向。若没有第二个参数,则回调函数默认指向window,
当回调函数是箭头函数的时候,遵循箭头函数绑定的法则,指向上下文,这时第二个参数回调函数的this指向不会起作用。即使使用call也不会起作用。
如果一个函数在参数位置,那这个函数叫回调函数。可以保证代码执行顺序
回调函数(callback)
//回调函数
function say(callback){ //callback回调函数,用来接收回调函数
console.log("睡觉")
callback && callback() //只有callback存在才可以执行
}
function happy(){
console.log("出去玩")
}
function unHappy(){
console.log("葛优躺")
}
say(happy) //回调
// 睡觉
//出去玩
//分装
let arr = ["大","家","好"]
//实现效果 arr.forEach(console.log)
console.log(arr.foreach(item,index,array))
}
//"大" 0 array3
//"家" 1 array3
//"好" 2 array3
foreach功能:遍历数组。
接受参数:回调函数(必须)
接受三个参数:每一项,下标,数组本身
this主体(可选):有了则是有的,没有则是window
foreach执行完成之后,默认不返回内容
foreach的分装 实现效果:arr.foreach(console.log) //打印出每一项,下标和数组本身 //console.log即使不传回调函数的参数,也会默认添加
用arr.myforeach
arr.myForEach = function(callback,thisArg){ //参数1:回调函数 参数2:回调函数this主体
if(typeOf callback !== "function"){
throw new Error("callback要是函数")
}
thisArg = thisArg || window //如果写了指向对象就用指向对象否则就是window
//搞到要遍历的数组 arr 即this 因为arr调用了myforeach这个方法
for(let i = 0;i<this.length;i++){
//this[i]是数组的每一项
//i是数组的下标
//this是需要遍历的数组
//需要执行回调函数 callback
callback.call(thisArg,this[i],i,this)
}
}
arr.myForEach(function(item,index,array){
//console.log(item,index,array)
//console.log即使不传回调函数的参数,也会默认添加
console.log(this)
},document)
//指向document的数组
6.find方法 (返回回调函数为true的哪一项)
通过filter可找出全部符合条件的内容,而find只能找出一项(满足条件的第一个元素)
回调函数:判断是否找到了这个元素的作用,三个参数。
返回值:布尔类型
find方法返回的内容:执行结果。如果有结果就返回结果,如果没有结果返回undefined
//寻找一个小与0的数
let array = [1,2,3,-1,-2,5]
array.find(function (item){
return item<0
//-1
})
含义find接受1个参数,是回调函数,回调函数接受三个参数(每一项,下标,数组本身)。回调函数如果返回true,表示找到了这个元素find直接结束,并且整体返回那个结果。回调函数如果返回false继续判断下一项。
//寻找一个水仙花数
let array = [137,225,316,153,449]
function checkSXH(num){
num = num + "" //转换成字符串
if(num[0]*num[0]*num[0]+num[1]*num[1]*num[1]+num[2]*num[2]*num[2] === num*1) {
return true
}else{
return false
}
}
console.log(array.find(checkSXH)) //153
7.数组方法
1.使用foreach
//打印出奇数位,遍历数组每一项,然后判断当前这一项是不是奇数项。
let arr = [0,1,2,3,4,5,6,7,8,9,10]
let foo = function(item,index,array){
if(index %2 === 0){
console.log(item)
}
arr.foreach(foo)
2.every方法:判断数组里面所有的内容是否都满足条件,接受一个回调函数
let teachers = [
{
name:"12",
sex:"男" //第一项就不满足,所以只执行了一次。只要一次不满足就放回false
},
{
name:"34",
sex:"女"
},
{
name:"56",
sex:"女"
},
]
//判断一下这个数组里的老师是否都是女的
let result = teachers.every(function(item,index,array){
if(teachers.sex === "女"){
return true
}else{
return false
}
})
console.log(result) //false
可将上面代码整合为:
let result = teachers.every(teacher =>teacher.sex === "女")
console.log(result)
细节:如果在某一次中返回了false那么后面的潘丹就没有必要了,直接结束了
3.some方法:与every方法相反:判断数组里面至少有一个满足条件的,整体就是true.
//问:是否有成年人
let teachers = [
{
name:"12",
sex:"男" ,
age:12
},
{
name:"34",
sex:"女",
age:18 //在这里执行了两次,只要执行到true的就结束
},
{
name:"56",
sex:"女" ,
age:17
},
]
let result = teachers.some(function(teacher){
return teacher.age >= 18
})
console.log(result) //true 因为有一个满足,则整体满足。
如果整体为false,则为false