目录
2.1.3String.fromCharCode(num1,num2...)
2.1.4 indexOf(searchValue[,fromIndex]):
2.1.5 lastIndexOf(searchValue[,fromIndex]):
2.2.2substr(start[,length]) 并不推荐使用,未来可能被移除
2.2.4 slice()和substring()的相同点和区别:
3.3.1 sort( function( a , b ){} )
3.5.1 forEach(callback(ele,index,array)[,thisArg])循环数组
3.5.2 filter(callback(ele,index,array)[,thisArg])数组筛选
3.5.3 map(callback(ele,index,array)[,thisArg])改变数组中每一位的值
3.5.4 reduce(callback(result,ele,index,array)[,initiaValue])累计器
3.5.5 some(callback(ele,index,array)[,thisArg])
3.5.6 every(callback(ele,index,array)[,thisArg])
6.2.1 取整相关方法Math.ceil(x)/Math.floor(x)/Math.round(x)
6.2.3最大值与最小值Math.min()/Math.max()
1.字符串的两种创建方式
字符串的两种创建方式:字符串字面量,字符串对象。
- 通过字符串字面量创建字符串:其typeof后类型是string
//字符串字面量
var str1 = "kaikeba";
console.log("字符串str1:"+str1);
console.log("字符串str1的类型"+(typeof str1));//string
结果:
- 通过字符串对象创建字符串:其typeof后类型是object
//字符串对象创建方式
var str2 = new String("kaikeba");
console.log("字符串str2:"+str2);
console.log("字符串str2的类型"+(typeof str2));//object
结果:
- 字符串可以通过下标对其字符进行获取
//可以通过字符串的下标获取字符串的字符
console.log("字符串str1的第2个字符"+(str1[1]));
console.log("字符串str2的第3个字符"+(str2[2]));
结果:
为什么可以通过下标获取字符串的字符?因为通过字符串对象创建的字符串是一种类数组。其实字符串就是类数组,类数组和数组长得非常像,但并不是数组,不具备数组的所有方法。类数组里面有很多方法,可以通过console.dir看到其所有的属性和方法。通过字面量的方式创建的字符串虽然不是类数组,但是也可以调用字符串对象上的方法,其实在内部是调用的是字符串对象上的方法。就像Date()和new Date()一样。
- 发现调用Date()方法会得到日期格式的字符串;
- 通过new Date()得到的是日期对象(具有和日期相关的操作方法)
//这种方式类似数组通过下标获取元素
var arr = [1,true,2,5,"3"];
console.log("获取数组arr的第三个元素:"+(arr[1]));
//通过字符串对象创建的字符串和数组
console.log(str2,arr);
//其实字符串就是类数组,类数组即和数组长得非常像,但并不是数组,不具备数组的所有方法
//类数组里面有很多方法,可以通过console.dir看到其所有的属性和方法
console.dir(str1);//kaikeba
console.dir(str2);//返回类数组
//通过字面量的方式也可以调用字符串对象上的方法,其实在内部是调用的是字符串对象上的方法
结果:
2.字符串方法
2.1查找类字符串方法
通过str[index]下标获取某一位这种方法取值是有兼容问题的,在IE8以下是无法使用。所以字符串上有专门的取值方法。
- str.charAt(index):index为字符串下标索引值。返回特定位置的字符。index为0到length-1,默认0,超出length或小于0返回空字符。
- str.charCodeAt(index):返回指定位置字符的Unicode编码。index为0到length-1,默认0,超出或小于0返回NaN。
- String.fromCharCode(num1,num2...):返回指定的Unicode码对应的字符。可填入多个Unicode码。
- indexOf(searchValue[,fromIndex]):返回首个被发现的指定值的索引,没有找到返回-1。该方法区分大小写。searchValue为要查找的值,fromIndex表示指定开始查找的位置,默认为0,如果小于0等同0进行操作,如果大于length返回-1。
- lastIndexOf(searchValue[,fromIndex]):返回最后一个被发现的指定的值的索引,没有找到则返回-1,查找顺序从后往前。fromIndex指定开始查找的位置,如果不给fromIndex,默认返回str.length。如果超出str.length,则以str.length进行操作。如果小于0,则从0开始操作。
2.1.1str.charAt(index):
可以通过str[index]的方式查找某个字符在某个字符串中的索引位置。但是该方法在IE8及其以下有兼容问题,所以需要使用charAt()。
index为字符串下标索引值。返回特定位置的字符。index为0到length-1,默认0,超出length或小于0返回空字符。
<script>
var str = "kaikeba";
console.log("charAt默认index:"+str.charAt());
console.log("charAt index 为0:"+str.charAt(0));
console.log("charAt index 为2:"+str.charAt(2));
console.log("charAt index 超出str.length:"+str.charAt(12));
console.log("charAt index 小于0:"+str.charAt(12));
</script>
结果:charAt()index默认为0,index超出length-1或者<0时,返回空字符串
2.1.2str.charCodeAt(index):
字符串比较大小是按照字典顺序比较其Unicode码的值,虽然可以查找,但是查找起来很麻烦。所以可以通过charCodeAt()方法直接获取某个字符对应的Unicode编码的值。
返回指定位置字符的Unicode编码。index为0到length-1,默认0,超出或小于0返回NaN。
var china1 = "中";
var china2 = "国家";
console.log("中的字符编码:"+china1.charCodeAt());
console.log("国的字符编码:"+china2.charCodeAt());
console.log("比较中和国的字符编码大小:"+(china1.charCodeAt()>china2.charCodeAt()));
console.log("家的字符编码:"+china2.charCodeAt(1));
console.log("超出length:"+china2.charCodeAt(3));//NaN
console.log("<0:"+china2.charCodeAt(-2));//NaN
结果:
2.1.3String.fromCharCode(num1,num2...)
获取对应Unicode编码对应的字符串。注意这里使用的是String对象
返回指定的Unicode码对应的字符。可填入多个Unicode码。
//fromCharCode()
var str2 = "我爱你";
var arr = [];
for (var i = 0; i < str2.length; i++) {
arr[i] = str2.charCodeAt(i);
}
console.log(String.fromCharCode(arr[0],arr[1],arr[2]));
结果:
2.1.4 indexOf(searchValue[,fromIndex]):
返回首个被发现的指定值的索引,没有找到返回-1。该方法区分大小写。searchValue为要查找的值,fromIndex表示指定开始查找的位置,默认为0,如果小于0等同0进行操作,如果大于length返回-1。
//indexOf(searchValue[,fromIndex])
var str3 = "kaikeba";
console.log("从0开始查找k第一次出现的位置:"+(str3.indexOf("k")));
console.log("小于0时:"+(str3.indexOf("k",-2)));//小于0时等同于0操作
console.log("从3开始查找k第一次出现的位置:"+(str3.indexOf("k",3)));
console.log("不存在字符时:"+(str3.indexOf("vv")));//-1
console.log("超出length时:"+(str3.indexOf("k",10)));//-1
console.log("找大写的K时:"+(str3.indexOf("K")));//-1
console.log("---------------------------------------");
结果:
自己写一个方法让其具备indexOf()的功能:通过charAt()实现
indexOf的所有功能:查找某个字符在另一个字符中的索引位置
1,查找某个字符在另一个字符中的索引位置
2,默认从0开始查找
3,查找到一次后不再继续查找
4,查找位置<0 等同于0进行查找
5,超出被查找的字符串长度直接返回-1
6,查找不到,返回-1
注意此方法只能单个字符逐一进行匹配,不能使用“ke”类似的多个字符进行匹配,所以,这就体现出indexOf()方法的强大之处
<script>
/*
indexOf的所有功能:查找某个字符在另一个字符中的索引位置
1,查找某个字符在另一个字符中的索引位置
2,默认从0开始查找
3,查找到一次后不再继续查找
4,查找位置<0 等同于0进行查找
5,超出被查找的字符串长度直接返回-1
6,查找不到,返回-1
str:被查找的字符串
searchValue:要查找的字符串
fromIndex:查找开始的位置
*/
var str = "kaikeba";
var searchValue = "k";
var fromIndex = "3";
var index = getIndex(str,searchValue,fromIndex);
console.log("字符所在的位置:"+index);
function getIndex(str,searchValue,fromIndex){
//fromIndex没有会返回undefined,默认从0开始;fromIndex<0时也等同于0开始查找
if(fromIndex === undefined || fromIndex<0){
fromIndex = 0;
}
//如果查找的开始位置超过str,返回-1
if(fromIndex>str.length){
return -1;
}
//开始位置为fromIndex
for (var i = fromIndex; i < str.length; i++) {
if( searchValue === str.charAt(i)){
return i;
}
}
//整个for循环中都没有找到searchValue,则返回-1
return -1;
}
</script>
结果:
2.1.5 lastIndexOf(searchValue[,fromIndex]):
返回从后往前第一个被发现的指定的值的索引(字符串最后面匹配的,找到不再继续查找),没有找到则返回-1,查找顺序从后往前。如果不给fromIndex,默认返回str.length。如果超出str.length,则以str.length进行操作。如果小于0,则从0开始搜索。
注意:这里返回的索引位置还是字符串str本身的索引位置,而不是,从后往前的从新开始计算的位置。
如这里的kaiebka,是从kaiebka的最后一位,即a开始,从后往前查找k,最后k的索引还是表示在kaiebka中的本身的索引位置。
//lastIndexOf(searchValue[,fromIndex])
//没有找到则返回-1,查找顺序从后往前。如果不给fromIndex,默认返回str.length。如果超出str.length,则以str.length进行操作。如果小于0,则从0开始搜索。
var str4 = "kaiebka";
console.log("从最后一位开始查找k第一次出现的位置:"+(str4.lastIndexOf("k")));//5
console.log("小于0时:"+(str4.lastIndexOf("k",-2)));//小于0时等同于0操作 0
console.log("从3开始查找k第一次出现的位置:"+(str4.lastIndexOf("k",3)));//0 注意:这里返回的索引位置还是字符串str本身的索引位置,而不是,从后往前的从新开始计算的位置。
console.log("不存在字符时:"+(str4.lastIndexOf("vv")));//-1
console.log("超出length时:"+(str4.lastIndexOf("k",10)));//5 如果超出str.length,则以str.length进行操作
console.log("找大写的K时:"+(str4.lastIndexOf("K")));//-1
结果:
2.2 字符串截取类方法
字符串截取类都是返回一个新的字符串,不会对原字符串进行操作。
- slice(begin[,end]):
- 截取一个字符串区域,并返回一个新字符串。
- begin表示截取的起始位置,不填默认到字符串结尾。
- begin如果是负数,则会从右向左查找字符截取。begin如果遇到了负数,length+(begin)=>length-begin。如var str = "kaikeba"; str.slice(-5); 即为7-5=2,从索引2开始;
- begin的负数一旦超出lenth,默认从0开始
- end表示结束截取的位置,如果省略不写,默认到字符串最后一位
- end如果是负数,同样从右向左查找最后一位字符位置;
- 截取字符串包含begin不包含end位置;
- 如果end超出最大索引值,或者end大于或者等于begin,都会返回空字符串。
- substr(start[,length]):返回从指定位置开始,到指定字符数的字符。start:开始提取字符的位置,如果为负数,则从右向左查找字符串截取;length:提取的字符串数,默认到字符串末尾;不推荐使用,可能会被移除;
- substring(begin[,end]):返回字符串中指定两个下标之间的字符。begin:截取的起始索引位置,小于0则等于0;end:截取的结束索引位置,包前不包后,大于length则等于length。
2.2.1 slice(begin[,end])
begin如果遇到了负数,length+(begin)=>length-begin。如var str = "kaikeba"; str.slice(-5); 即为7-5=2,从索引2开始
//slice()方法
// begin表示从该索引开始提取字符形成新的字符串
//begin如果是负数(负数一旦超出lenth,默认从0开始),则会从右向左查找字符截取;
//end表示结束截取的位置,如果省略不写,默认到字符串最后一位,如果是负数,同样从右向左查找最后一位字符位置;
//如果超出最大索引值,或者end大于begin,或者end等于begin,都会返回空字符串。
var str = "kaikeba";
//包前不包后;
console.log("2,5:"+str.slice(2,5));//ike
//begin如果是负数(负数一旦超出lenth,默认从0开始),则会从右向左查找字符截取;
console.log("begin为负数:"+str.slice(-2));//ba
//begin如果遇到了负数,length+(begin)=>length-begin。如var str = "kaikeba"; str.slice(-5); 即为7-5=2,从索引2开始
console.log("-5:"+str.slice(-5));//ikeba
//负数一旦超出lenth,默认从0开始 kaikeba
console.log("begin负数超出lenth:"+str.slice(-8));//kaikeba
//end如果是负数,同样从右向左查找最后一位字符位置;
console.log("end为负数:"+str.slice(2,-1));//-1的位置为从后往前的b ikeb
//如果超出最大索引值,或者end大于begin,都会返回空字符串。
console.log("超出最大索引值:"+str.slice(9));
console.log("end大于begin:"+str.slice(-2,5));
结果:
2.2.2substr(start[,length]) 并不推荐使用,未来可能被移除
substr(start[,length]) 截取从start开始的字符。
- 参数
- start:截取的起始位置,如果是负数,则从右向左查找字符串截取
- length:提取的字符串个数,默认到字符串末尾。length超过字符串长度时,默认为到字符串结尾位置,length为负数,返回空
通常想要截取一个字符串的最后几位,就可以通过substr(截取的位数的负数)的到
var str = "kaikeba";
//start为负数,就从右向走开始查找 length + start = length +(-start)的值作为起始位置
console.log(str.substr(-5));//起始位置为7-5=2,即起始位置为2 ikeba
//length为负数,则返回空字符串
console.log(str.substr(2,-4));// ""
//通常想要截取一个字符串的最后几位,就可以通过substr(截取的位数的负数)的到
//想得到str的最后4位
console.log(str.substr(-4));//keba
结果:
2.2.3 substring(begin[,end]):
返回字符串中指定两个下标之间的字符
- 参数
- begin:截取的起始索引位置,如果小于0,则等于0;
- end:截取的结束索引位置,该位置的字符不包含在截取范围内,如果大于length,则等于length
- 如果begin大于end,会将小的end作为起始值,较大的begin作为结束值
- 如果begin等于end,则返回空字符串
var str = "kaikeba";
console.log(str.substring(-2));// kaikeba start为负数,当做0处理
console.log(str.substring(2,2));// ""
console.log(str.substring(5,2));//ike start大于end时,以end为起始位置,start为结束位置
2.2.4 slice()和substring()的相同点和区别:
相同点:
- 默认都到字符串结尾;
- 都返回一个新的字符串;
- begin等于end时都会返回空字符串;
- 截取的字符串都是包含begin的索引,不包含end的索引
不同点:
- begin为负数时:slice()的begin小于0时,从右往左查找字符串,如果小于数超过length,当做0操作;substring() 的begin小于0直接当0操作;
- begin大于end时:slice()返回空字符串;substring()会以end为起始位置,begin为结束位置
- end为负数:slice() end如果是负数,同样从右向左查找最后一位字符位置;substring()的end为负数时当做0操作,如果此时小于strat会作为起始位置
substr的第二个参数为截取的字符长度,slice()和substring()的第二个参数为截取字符串的结束索引位置
2.3其他常用方法
- split(separator[,num]) 将字符串分割成字符串数组
- separator:
- 决定分隔的字符;
- 不传参数时,得到的数组只有一个元素即当前字符串。
- 分割符“”时,分隔开每个字符。
- 分割字符在字符串的首尾位置,会有一个空字符串(可通过此方法知道当前字符在字符串中出现了几次:str.split("当前字符").length-1)
- num:分隔的个数
- separator:
var str = "kaikeba";
console.log(str.split("k"));//(3) ["", "ai", "eba"]
console.log(str.split("k").length-1);//2
- concat(性能不如+ 、+=):将一个或多个字符串与原字符串合并,并返回新字符串
- toLowerCase():将字符串转成小写并返回新的字符串
- toUpperCase():将字符串转成大写并返回新的字符串
- trim():去除首尾空格
3.数组方法
数组可以通过下标位存储值;
可以通过length来获取长度;
数组独特之处:JS中只有数组的length的值可以进行改变。但一般不操作数组的length属性。
最快清空数组的方式:arr.length = 0,就会返回arr为空数组
注意以下不是清空数组:arr和arr2根本就不是一个数组。
3.1基础添加和删除
- push():将一个或多个元素添加到数组的结尾,并返回该数组被修改后的长度。该方法会改变原数组。
- pop():删除数组中的最后一位,并返回删除的元素。如果用在一个空数组上会返回undefined。
- unshift():将一个或多个元素添加到数组的开头,并返回给更改后的该数组的新长度。
- shift():删除数组中的第一位,并返回删除的值。如果用在一个空数组上会返回undefined。
var arr = [1,2,3,4];
console.log("原数组:");
console.log(arr);//[1, 2, 3, 4]
console.log("push()后的数组:");
console.log(arr.push(3,4,5));//push方法返回值添加后的元素个数
console.log(arr);//[1, 2, 3, 4, 3, 4, 5]
console.log("pop()后的数组:");
console.log(arr.pop());//pop方法返回值为被删除的元素 5
console.log(arr);//[1, 2, 3, 4, 3, 4]
console.log("unshift()后的数组:");
console.log(arr.unshift(7,8,9));//unshift方法返回值为添加后的元素个数
console.log(arr);//[7, 8, 9, 1, 2, 3, 4, 3, 4]
console.log("shift()后的数组:");
console.log(arr.shift());//shift方法返回值被删除的元素 7
console.log(arr);// [8, 9, 1, 2, 3, 4, 3, 4]
结果:
图片切换案例:https://mp.csdn.net/postedit/96905483
3.2 进阶删除、添加、替换方法splice()
splice(start[,num,item1,item2...]) 具有删除,添加和替换多种功能。
- 可以用于删除指定位置的元素,并在该位置上添加新的元素
- 返回删除的元素组成的数组,并且会改变原数组。如果没有删除任何元素,将会得到空数组,原数组不会改变。
- 参数
- start:必填,不填不会删除任何元素;指定修改的起始位置,如果超出长度,默认为从数组末尾开始;如果是负数(超过length,则为length),从右往左查找起始位置(length+(-start))。
- num:表示要删除数组元素中的个数,默认到数组的结束位置,如果是0或者负数,则不移除元素。
- item1,item2...:要添加到数组里面的内容
3.2.1 删除:
- start:删除的起始位置
- num:可选,默认删除到数组末尾。表示删除的个数。
- 返回的是被删除的元素组成的新数组,并且会改变原数组
var arr = [1,2,3,4,5,6];
//删除 返回值为删除后的元素组成的新数组
console.log("删除前的数组:");
console.log(arr);//[1, 2, 3, 4, 5, 6]
console.log("splice()删除后的数组:");
console.log(arr.splice(0));// [1, 2, 3, 4, 5, 6]
console.log(arr);// []
var arr = [1,2,3,4,5,6];
//删除 返回值为删除后的元素组成的新数组
console.log("删除前的数组:");
console.log(arr);//[1, 2, 3, 4, 5, 6]
// console.log("splice()删除后的数组:");
// console.log(arr.splice(0));// [1, 2, 3, 4, 5, 6]
// console.log(arr);// []
console.log("splice(2,3)删除后的数组:");
console.log(arr.splice(2,3));// [3, 4, 5] start表开始删除的位置,num表删除的数组元素个数。
console.log(arr);// [1, 2, 6]
3.2.2 替换:
根据参数item1,item2...进行操作。num表示替换几位。会在对应位置先删除元素,再添加上对应元素。不需要一对一进行替换,可以num为1,替换的元素为多个。如果num为0就直接添加。
var arr = [1,2,3,4,5,6];
//删除 返回值为删除后的元素组成的新数组
console.log("删除前的数组:");
console.log(arr);//[1, 2, 3, 4, 5, 6]
//替换 将从1开始的三个元素替换成'a','b','c'
console.log("splice(1,3,'a','b','c')替换后的数组:");
console.log(arr.splice(1,3,'a','b','c'));// [2, 3, 4] 返回被删除后的元素组成的数组
console.log(arr);//[1, "a", "b", "c", 5, 6]
3.2.3 添加
splice()方法第二个参数num如果是0或者负数,则不移除元素。如果不删除元素,参数item1,item2...有存在,就会是添加功能。因为是添加元素,所以返回空数组[]。
var arr = [1,2,3,4,5,6];
//删除 返回值为删除后的元素组成的新数组
console.log("删除前的数组:");
console.log(arr);//[1, 2, 3, 4, 5, 6]
//添加 从第3为开始,添加4个元素
console.log(arr.splice(2,0,'A','B','C','D'));//[]
console.log(arr);//[1, 2, "A", "B", "C", "D", 3, 4, 5, 6]
3.3 sort排序方法
3.3.1 sort( function( a , b ){} )
- 可选参数。默认根据字符串的unicode码进行排序
var arr = [5,6,2,4,1];
arr.sort();
console.log(arr);//[1, 2, 4, 5, 6]
var arr1 = [20,4,23,78,90];
arr1.sort();
console.log(arr1);//[20, 23, 4, 78, 90]
- 如果不提供任何参数,则根据默认规则(Unicode码)进行排序。
- 如果提供参数(此参数是一个函数),可以指定排序的规则。
- 根据return返回值,决定是否交换a和b的位置
排序规则:如果 a-b的结果(a和b代表两个在比较的值):
- 大于0 :b 排到 a 前面
- 小于0:a 排到 b 前面
- 等于0:a 和 b 的位置不变
- 即大于等于0时不颠倒位置,小于0时,交换a和b位置(从大到小排)
执行的比较次数是根据数组里的数据决定。根据排序规则,如果想要从小到大排序,return a-b; 如果想要从大到小排序,return b-a;
规则:
- 从大到小排序:n2-n1
- 从小到大排序:n1-n2
[20,4,23,78];传入的是相邻的两位,n1为后面一位,n2为前面一位,如第一次时,n1为4,n2为20
// var arr1 = [20,4,23,78];
// arr1.sort(function(n1,n2){
// console.log(n1,n2);
// return n2-n1;//从大到小
// });
// console.log(arr1);
/*
4 20
23 4
23 4
23 20
78 20
78 23
[78, 23, 20, 4]
第一次:[20,4,23,78] n1:4 n2:20 n2>n1所以不交换位置[20,4,23,78]
第二次:[20,4,23,78] n1:23 n2:4 n2<n1所以n1 n2交换位置[20,23,4,78]
第三次:[20,23,4,78] n1:23 n2:20 n2<n1所以n1 n2交换位置[23,20,4,78]
第四次:[23,20,4,78] n1:78 n2:20 因为20和4比较过了,所以直接20和78比,n2<n1 所以n1和n2交换位置[23,78,20,4]
第五次:[23,78,20,4] n1:78 n2:23 因为23<78 所以23和78交换位置[78,23,20,4]
结果:[78,23,20,4]
*/
var arr2 = [6,50,12,40];
arr2.sort(function(a,b){
console.log(a,b);
return a-b;//从小到大
});
console.log(arr2);
/*
50 6
12 50
12 50
12 6
40 12
40 50
[6, 12, 40, 50]
n1表示后面以为,n2表示前面一位
第一次比较[6,50,12,40]:n2:6 n1:50 n1-n2>0 所以n2排在n1前面 6,50,12,40
第二次比较[6,50,12,40]:n2:50 n1:12 n1-n2<0 所以n2排在n1后面 6,12,50,40
第三次比较[6,12,50,40]:n2:6 n1:12 n1-n2>0 所以n2排在n1前面 6,12,50,40
第四次比较[6,12,50,40]:n2:12 n1:40 n1-n2>0 所以n2排在n1前面 6,12,50,40
第五次比较[6,12,50,40]:n2:50 n1:40 n1-n2<0 所以n2排在n1后面 6,12,40,50
*/
3.3.2 特殊的排序(自定义排序)
当sort()方法已有的排序的规则符合不了需求时,可以自定义排序规则。
var arr1 = ['A','B','c','a','C','b'];
arr1.sort();
console.log(arr1);//["A", "B", "C", "a", "b", "c"]
//当元素不能按照unicode排序,而是需要按照A a B b C c的方式排序时,就需要自定义排序规则
arr1.sort(function(n1,n2){
//将比较的两个数都进行统一大小写
var n1 = n1.toLowerCase();
var n2 = n2.toLowerCase();
if(n1>n2){
return -1;
}else if(n2>n1){
return 1;
}
return 0;
});
console.log(arr1);//["C", "c", "B", "b", "A", "a"]
可以将自己想要排序的数据在对象里面定义规则,再通过sort()方法进行排序处理:
<script>
var index = {
"零":0,
"一":1,
"二":2,
"三":3,
"四":4,
"五":5,
"六":6
};
//将需要排序的内容通过自定义排序给定序号
var arr = ['二','六','一','五','零','四','三'];
arr.sort(function(n1,n2){
//排序时通过传入的值n1和n2可以得到对应数据的序号,再将序号进行排序,即可将对应的数据进行排序
console.log(index[n1],n1);
// console.log(index[n1],index[n2]);
return index[n1]-index[n2];
});
console.log(arr);
</script>
结果:
3.3.3 随机排序Math.random()
通过Math.random()实现随机排序。Math.random()的返回值是0~1(包含0不包含1)。由于sort的排序规则是a-b需要大于0,等于0,小于0三种情况,所以只需要使用Math.random()-0.5就可以得到两个数的值在-0.5到+0.5之间(随机返回一个整数或者负数)。即可实现随机排序。
<script>
var arr = ['a','b','c','d'];
//通过Math.random()实现随机排序。Math.random()的返回值是0~1(包含0不包含1)。由于sort的排序规则是a-b需要大于0,等于0,小于0三种情况,所以只需要使用Math.random()-0.5就可以得到两个数的值在-0.5到+0.5之间。即可实现随机排序
arr.sort(function(n1,n2){
return Math.random()-0.5;//保证数据在小于0,等于0,大于0三种情况之间
});
console.log(arr);
</script>
结果:
["d", "b", "a", "c"]
["d", "c", "b", "a"]
......
3.4数组常用方法
-
concat(arr1,arr2,arr3...):用于合并两个或多个数组。此方法不会改变原有数组,会返回一个新数组
var arr1 = ['a','b'];
var arr2 = ['1','2'];
var arr3 = ['三','五'];
var arr4 = arr1.concat(arr2,arr3);
console.log(arr1);//["a", "b"]
console.log(arr2);//["1", "2"]
console.log(arr3);//["三", "五"]
console.log(arr4);//["a", "b", "1", "2", "三", "五"]
-
join(separator):讲一个数组的所有元素连接成一个字符串,并返回这个字符串;不给分隔符默认为逗号“,”;分隔符是空字符串,就将数组进行直接拼接;如果原数组是空数组,会返回空字符串;如果只有一个元素,直接返回该元素的字符串。
var str = "kai-ke-ba";
var arr = str.split("-");
console.log(arr);
//如果分隔符为 "",直接拼接数组的每个元素
var joinStr = arr.join("");
console.log(joinStr);//kaikeba
//如果分隔符为 其他,使用给的分隔符进行分割
var joinStr = arr.join("%");
console.log(joinStr);//kaikeba
-
reverse:将数组中的所有元素位置颠倒,返回新数组。并会改变原有数组。
-
indexOf(searchValue[,fromIndex]):返回在数组中指定元素第一次出现的索引,如果不存在,返回-1;
-
lastIndexOf(searchValue[,fromIndex]):返回在数组中指定元素最后一次出现的索引,如果不存在,返回-1。
-
slice(begin[,end]):截取从begin开始,到end为止的数据,并作为一个新数组返回。不会改变原有的数组。
begin :截取的起始位置,不给,默认为0;
如果begin值超过length,返回空数组;
如果begin为负数,从右往左截取,begin = length+begin = length + (-begin)。(如果负数超过length,默认从0开始截取);
end:截取的结束位置,不给,默认到数组结尾;
如果end小于begin,得到空数组;
如果end为负数,说明从右往左倒数第end个结束(负数的绝对值超过了length,会得到空数组);
end超过了length,默认到数组结尾位置
begin包含在截取范围内,end不包含在截取范围内
赋址,浅拷贝和深拷贝:
- 赋址:数据不管是基本类型,还是复杂类型,都和原来的数据时相关联的;
- 浅拷贝:数据拷贝过来后,里面的第一层的基本类型时没有关联,但是里面的复杂类型依旧是有关联的。数组的slice方法属于浅拷贝
- 深拷贝:数据拷贝过来后,数据和原数组之间完全没有任何关系了
赋值:发现改变赋值过来的数组,原来的数组也会发生改变
//赋址:发现数组是使用传址,即将数据在内存中的引用地址进行传递,arr 和arr1指向的是同一个地址。所以更改arr1同时arr也进行更改了
//赋址:数据不管是基本类型,还是复杂类型,都和原来的数据时想关联的
var arr = [1,3,4,2,7];
var arr1 = arr;
arr1[0] = 'a';
console.log(arr1);//["a", 3, 4, 2, 7]
console.log(arr);//["a", 3, 4, 2, 7]
浅拷贝:
发现更改arr5的基本数据类型arr[1]时,arr4不会跟着改变:
//浅拷贝:数据拷贝过来后,里面的第一层的基本类型时没有关联了,但是里面的复杂类型依旧是有关联的。数组的slice方法属于浅拷贝
var arr4 = [{a:1,b:2},1];
var arr5 = arr4.slice();
arr5[1] = '234';
console.log(arr4);//[{…}, 1]
console.log(arr5);//[{…}, "234"]
但是,当更改arr5中的对象等复杂类型时,arr4和arr5的数值都被改变了:
//浅拷贝:数据拷贝过来后,里面的第一层的基本类型时没有关联了,但是里面的复杂类型依旧是有关联的。数组的slice方法属于浅拷贝
var arr4 = [{a:1,b:2},1];
var arr5 = arr4.slice();
arr5[0].a = "asdfasdf";
console.log(arr4);
console.log(arr5);
3.5 数组新增方法
- 所有的数组新增方法的功能都能使用for循环实现,只是比较麻烦;
- 所有的数组新增方法中的this,因为没有任何属性或方法调用,所以都是指向window,但是可以通过参数thisArg更改数组新增方法中的this指向;
- 所有新增的数组方法,都具有循环的效果
3.5.1 forEach(callback(ele,index,array)[,thisArg])循环数组
- 对数组中的每一个元素,执行一次提供的函数,返回值为undefined(所以不能获取到forEach的返回值进行其他操作)
- 参数:
- callback 执行的函数
- ele:数组循环中的元素
- index:元素对应的下标
- array:当前正在操作的数组
- thisArg :可选。决定callback中的this指向
- callback 执行的函数
注意:获取HTML元素时,只有querySelectotAll()得到的类数组可以使用forEach()函数。其他获取元素方法getElementsByTagName/ByClassName()等是不能使用forEach()函数的。
其他的方法filter()/reduce()/map()/some()/every()等方法只有数组可以使用,querySelectotAll()得到的类数组也不可以使用。
通过for循环实现较麻烦:
/*
for循环实现:比较麻烦
必须声明变量;
有循环条件;
有条件结束标志;
*/
var arr = [2,3,1,34,67];
//如果要使用for循环得到数组的所有下标
for (var i = 0; i < arr.length; i++) {
console.log(i);//
}
forEach() 可以直接获取到数组的循环元素,元素的下标,以及整个数组arr,还可以通过第二个参数thisArgs改变数组的this执行(本身没有任何调用指向window):
//forEach() 可以直接获取到数组的循环元素,元素的下标,以及整个数组arr,还可以通过第二个参数thisArgs改变数组的this执行(本身没有任何调用指向window)
arr.forEach(function(ele,index,arr){
console.log(ele,index,arr);
});
通过第二个参数thisArgs改变数组的this执行(本身没有任何调用指向window):
//forEach() 可以通过第二个参数thisArgs改变数组的this执行(本身没有任何调用指向window)
arr.forEach(function(ele,index,arr){
console.log(this);//Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
});
arr.forEach(function(ele,index,arr){
console.log(this);//#document
},document);
3.5.2 filter(callback(ele,index,array)[,thisArg])数组筛选
- 筛选出符合函数中条件的元素,并作为一个新数组返回。
- filter中return true就将结果添加到返回的新数组中,返回false就不进行添加。所以新数组中的元素是由return的结果决定。
- 如果直接return true 而没有其他筛选条件,会将所有元素返回,return false不会返回任何元素。
- 参数
- callback 条件函数
- ele:数组循环中的元素
- index:元素对应下标
- array:当前正在操作的数组
- thisAry:决定callback中的this指向
- callback 条件函数
需求:获取数组中>50的元素
使用for循环实现:
//需求:将数组中大于50的元素进行返回
var arr = [34,67,32,23,78];
//通过for循环实现:需要定义接收的数组,需要有if判断
var num = [];
for (var i = 0; i < arr.length; i++) {
if(arr[i]>50){
num.push(arr[i]);
}
}
console.log(num);//[67, 78]
使用filter实现:会将满足条件的所有元素返回到一个新数组中。如果直接return true;会将所有元素返回,return false不会返回任何元素。
//通过filter实现
var newArr = arr.filter(function(ele,index){
return ele>50;//会将满足条件的所有元素返回到一个新数组中
});
console.log(newArr);//[67, 78]
filter方法也可以通过第三个参数thisAry:决定callback中的this指向:
arr.filter(function(ele,index){
console.log(this);//Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
return ele>50;
});
arr.filter(function(ele,index){
console.log(this);//<body>...</body>
return ele>50;
},document.body);
3.5.3 map(callback(ele,index,array)[,thisArg])改变数组中每一位的值
- 由数组中的每一位元素执行函数后的结果,作为新数组的值.
- 必须有返回值,否则得到的每个元素值都是undefined
- 参数:
- callback 执行的函数
- ele:数组循环中的元素
- index:元素对应下标
- array:当前正在操作的数组
- thisAry:决定callback中的this指向
- callback 执行的函数
map()和forEach()的区别:map()方法返回值为每一位元素执行后的结果,但forEach()返回值为undefined
需求:将数组里的每个值扩大一倍,再进行输出
var arr = [34,67,32,23,78];
使用for循环实现:
//使用for循环
var num = [];
for (var i = 0; i < arr.length; i++) {
num[i] = arr[i] * 2;
}
console.log(num);//[68, 134, 64, 46, 156]
使用forEach()实现:
//使用forEach实现
var num1 = [];
arr.forEach(function(ele,index,arr){
num1[index] = ele * 2;
});
console.log(num1);//[68, 134, 64, 46, 156]
使用map()实现:map()直接将结果进行return,并返回到新数组。且第三个参数可以指定数组的this指向。
//使用map实现
var mapArr = arr.map(function(ele,index,arr){
console.log(this); //#document
return ele * 2;
},document);
console.log(mapArr);//[68, 134, 64, 46, 156]
3.5.4 reduce(callback(result,ele,index,array)[,initiaValue])累计器
- 对数组中的每一个元素执行callback函数,将结果根据callback函数中的条件,返回单个值。
- 如果不把累加结果返回,那么打印的result为undefined。
- 最终的累加值通过reduce的返回值获得
- 也可以叫做累计器(可以累加或减)
- 参数:
- callback 执行的函数
- result:上一次累计的结果
- ele:当前正在操作的元素
- index:元素对应的下标
- array:当前正在操作的数组
- initiaValue:result的初始值,如果不提供,则将使用数组中的第一个值。
- callback 执行的函数
需求:将数组中所有元素进行累加
//需求将所有的元素进行累加
var arr = [34,67,32,23,78];
通过for循环实现:
//通过for循环进行实现
var num = 0;
for (var i = 0; i < arr.length; i++) {
num += arr[i];
}
console.log(num);//234
通过reduce实现:
//通过reduce实现
var num1 = arr.reduce(function(result,ele,index,arr){
console.log(result,ele);
return result + ele;//上一次的累计结果+本次的ele元素
});
console.log(num1);//234
另一种写法:
通过reduce实现,并且给出累加初始化值100:
//通过reduce实现,并且给初始值为100
var num2 = arr.reduce(function(result,ele,index,arr){
console.log(result,ele);
return result + ele;//上一次的累计结果+本次的ele元素
},100);
console.log(num2);//334
3.5.5 some(callback(ele,index,array)[,thisArg])
- 测试数组中是否至少有一个元素通过了指定函数的测试,结果返回布尔值
- 参数:
- callback 执行的函数
- ele:数组循环中的元素
- index:元素对应下标
- array:当前正在操作的数组
- thisAry:决定callback中的this指向
- callback 执行的函数
需求:全部都没有选中时,去支付按钮不能点击,只有至少有一个选中时才能进行支付
使用JS实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div { width:200px; height:200px; margin: 100px auto;}
</style>
</head>
<body>
<div>
<input type="checkbox" name="" id="">薯片
<br>
<input type="checkbox" name="" id="">水果
<br>
<input type="checkbox" name="" id="">衣服
<br><br>
<button type="submit" disabled>去支付</button>
<br>
</div>
<script>
//需求:全部都没有选中时,去支付按钮不能点击,只有至少有一个选中时才能进行支付
var inputs = document.querySelectorAll("input");
var btn = document.querySelector("button");
//通过JS实现
for (var i = 0; i < inputs.length; i++) {
//通过num++记录是否至少有一个checked被选中
var num = 0;
inputs[i].onclick = function(){
this.checked ? num++:num--;
//通过num判断至少有一个checked被选中,"去支付"按钮才能显示
btn.disabled = num?false:true;//设置按钮可编辑不能加引号
};
btn.onclick = function(){
alert("去支付");
};
}
</script>
</body>
</html>
通过some方法实现:
注意:通过querySelectorAll获得的元素是一个类数组,而不是数组,所以不能使用数组新增方法 。需要将其放到数组中去,才能通过some进行操作
inputs.forEach(function(ele,index,arr){
inputs.some(function(){//inputs.some is not a function
return this.checked;
});
});
//由于通过querySelectorAll获得的CheckBox所有按钮是一个类数组,而不是数组,所以不能使用数组新增方法
var arr = [];
for (var i = 0; i < inputs.length; i++) {
arr.push(inputs[i]);
}
arr.forEach(function(ele,index){
ele.onclick = function(){
var isChecked = arr.some(function(ele,index){
return ele.checked;
});
btn.disabled = isChecked ? false:true;
};
});
btn.onclick = function(){
alert("去支付");
};
3.5.6 every(callback(ele,index,array)[,thisArg])
- 测试数组中所有的元素是否都通过了指定函数的测试,结果返回布尔值。
- 参数:
- callback 执行的函数
- ele:数组循环中的元素
- index:元素对应下标
- array:当前正在操作的数组
- thisAry:决定callback中的this指向
- callback 执行的函数
需求:当全部选中后,全选按钮自动被选中,否则全选按钮不被选中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div { width:200px; height:200px; margin: 100px auto;}
</style>
</head>
<body>
<div>
<input type="checkbox" name="" class="goods">薯片
<br>
<input type="checkbox" name="" class="goods">水果
<br>
<input type="checkbox" name="" class="goods">衣服
<br><br>
<input type="checkbox" name="" id="allCheck">全选
<!-- <button type="submit" disabled>去支付</button> -->
<br>
</div>
<script>
//需求:当全部选中后,全选按钮自动被选中,否则全选按钮不被选中
//通过JS实现
var inputs = document.querySelectorAll(".goods");
var allCheck = document.querySelector("#allCheck");
//通过JS实现
for (var i = 0; i < inputs.length; i++) {
//通过num++记录是否至少有一个checked被选中
var num = 0;
inputs[i].onclick = function(){
this.checked ? num++:num--;
//通过num判断所有checkbox被选中才能选中全选按钮
console.log(num,inputs.length);
allCheck.checked = num == inputs.length?true:false;
};
}
</script>
</body>
</html>
通过every实现:只有当所有checkbox选中后,全选按钮才会选中
//通过every实现
var arr = [];
for (var i = 0; i < inputs.length; i++) {
arr.push(inputs[i]);
}
console.log(arr);
arr.forEach(function(ele,index){
ele.onclick = function(){
var isChecked = arr.every(function(ele,index){
return ele.checked;
});
allCheck.checked = isChecked ? true:false;
};
});
结果:
4.对象方法
- 两种方式创建对象:以键值对存储对象,键值对之间用逗号隔开。
- var obj = {};
- var obj1 = new Object();
obj1["name"] = "lmf";//尽量使用[]方式添加键值,好维护。
- 获取对象上的数据:
- 方法一:obj.key 。此方式只能得到单个值
- 方法二:使用for ...in 可以获取obj上所有的键和值
- 方法三:Object.keys(obj)返回一个由key组成的数组;Object.values(obj)返回一个由value组成的数组。注意因为Object.keys(obj)和Object.values(obj)方法都是对象Object上的,所以必须通过Object.keys(obj)和Object.values(obj);才能获取到值
- 删除对象中的元素:delete obj.key。delete obj1['name'] 删除整个键值对。通过obj.key = '';的方式只能删除对应的值,不能删除对应的键。
- 对象的in运算,判断对象是否存在对应属性
需求:将所有的key和value分别获取,分别组成数组
通过for...in获取obj上所有键值:注意for...in中使用obj[key]获取到值
<script>
//需求:将所有的key和value获取出来分别组成数组
var obj = {
name:'lmf',
age:18,
gender:"female"
};
//通过for...in实现
var keys = [];
var values = [];
for (var o in obj) {
keys.push(o);
//注意for...in中使用obj[key]获取到值
values.push(obj[o]);
}
console.log(keys);//["name", "age", "gender"]
console.log(values);//["lmf", 18, "female"]
</script>
通过keys()和values()方法获取键值:注意因为Object.keys(obj)和Object.values(obj)方法都是对象Object上的,所以必须通过Object.keys(obj)和Object.values(obj);才能获取到值
//需求:将所有的key和value获取出来分别组成数组
var obj = {
name:'lmf',
age:18,
gender:"female"
};
var allKeys = [];
var allVals = [];
allKeys.push(Object.keys(obj));
allVals.push(Object.values(obj));
console.log(allKeys);
console.log(allVals);
删除对象中的元素:
var obj = {
name:'lmf',
age:18,
gender:"female"
};
//obj.key = '';方式只能删除值,不能删除键
obj.name = '';
console.log(obj);//{name: "", age: 18, gender: "female"}
//delete obj.key 可以删除整对键值对
delete obj.gender;
console.log(obj);//{name: "", age: 18}
5.JSON
5.1 JSON是什么?
JSON是一种轻量级的数据交换格式。用于不同语言之间交换字符串。因为语言的种类繁多,且不同的语言对于数据有不同的定义,例如:
php 中的数组,分为两种形式,一种:索引数组,这个与我们 JS 中的数组类似;还有一种:关联数组,它更像是我们 JS 中的对象,但是在php中他们都是数组。
5.2 JSON的数据格式(JSON:对象格式的字符串)
var jsonString = '{"key":value}';
- json的key必须有引号,value可以不使用引号。
- json是对象格式的字符串。所以最外层必须使用引号。
- 定义json的引号和key/value的引号使用单引和双引分开。
JSON对象:JS中为了方便操作JSON的数据,所以JS专门准备了JSON对象。
- JSON.parse( )
- 把JSON数据转化为 JS 中对应的数据,方便操作。
- JSON.stringify( )
- 把JS中的数组或对象,转成JSON字符串进行输出。
总结:JSON特点:
- key必须加上引号;
- JSON中最后一个值后面不能跟逗号
使用JSON对象转换时,如果JSON创建格式有误会报错:
var jsonStr = '{"name":"lmf","age":"18","gender":"female"}';
//JSON.parse将字符串转为对象
var str = JSON.parse(jsonStr);
console.log(typeof str);//object
//将对象转为字符串
var obj = JSON.stringify(str);
console.log(typeof obj);//string
6.常用Math方法
提供了与数学操作有关的一些属性与方法。与其它内置对象(如Date、Array等)不同,Math不能作为一个函数去使用,它只是一个对象常用属性。
6.1常用属性
Math.PI : 圆周率:Math.PI=π≈3.14159
console.log(Math.PI);//3.141592653589793
6.2常用方法
6.2.1 取整相关方法Math.ceil(x)/Math.floor(x)/Math.round(x)
- Math.ceil(x)
- 返回大于或等于
x
的最小整数,即:向上取整。如 1 < x <= 2 都取2。如1.00000001...都取2 - 参数
- x:任意数值
- 返回大于或等于
- Math.floor(x)
- 返回小于或等于
x
的最小整数,即:向下取整。如 1 < x <= 2 都取1。如1.99999999...都取1 - 参数
- x:任意数值
- 返回小于或等于
- Math.round(x)
- 返回
x
四舍五入后的整数值 - 参数
- x:任意数值
- 返回
如果给的值是数字类型的字符串会进行隐式类型转换,转换成数字类型再进行计算;
如果给的值不能被转换成数值,则会得到NaN;
小数点后面的值>=5就向上取整;<5就向下取整。
6.2.2随机数方法Math.random()
Math.random()
- 随机返回一个 0(包括0)到 1 (不包括1)之间的小数
- 扩展:
- 返回一个 0 到 n 之间的数
- 返回一个 n 到 m 之间的数
通过Math.random()方法返回一个0~n之间的数:
0~n:
- 要包含n,使用round
- 不包含n,推荐使用floor
//需求:将数组中的元素进行随机排序
/*
0~n:
要包含n,使用round
不包含n,推荐使用floor
*/
var arr = ["喝一杯","唱歌","真心话","大冒险","对视十秒"];
var num = Math.random() * 4;
console.log(num);//1.995949757996387
/*
数组是0-4
Math.random() * 4
发现直接使用Math.random() * 4存在以下问题:
1,小数位数太多
2,不包含4(这里希望要取到4)
*/
//解决小数位数太多 ceil()、floor()、round()都可以取整
console.log(Math.ceil(num));//向上取整包含4 (0出现概率太低)
console.log(Math.floor(num));//向下取整不包含4(不可用)
console.log(Math.round(num));//四舍五入后再取整可能包含4
var n = Math.round(num);
console.log(arr[n]);
通过Math.random()方法返回一个n~m之间的数:
n~m(如果是5~10):
- Math.random() * 10 会得到 0 - 10之间的值,有问题:解决
- 首先得到0-5的值;Math.random() * 5 0~5;
- 要想得到5-10之间的值,就将Math.random() * 5整体+5即可;
如想得到2-17的值:
- 0-15 Math.random() * 15
- 2-17 Math.random() * 15 + 2
//需求:想要得到n-m之间的值
/*
n~m:
如果是5~10:
Math.random() * 10 会得到 0 - 10之间的值,有问题:解决
首先得到0-5的值;Math.random() * 5 0~5;
要想得到5-10之间的值,就将Math.random() * 5整体+5即可;
如想得到2-17的值
0-15 Math.random() * 15
2-17 Math.random() * 15 + 2
*/
function getRandom(min,max){
return Math.round(Math.random() * (max-min) + min);
}
var num1 = getRandom(2,17);
console.log(num1);
6.2.3最大值与最小值Math.min()/Math.max()
- min([value1[,value2, ...]]) 返回一组数据中最小的值
- 返回传入参数中最小的值
- 参数
- 0 到 n 个数字
- 注意:
- 如果没有参数,返回
Infinity
- 如果参数中包含不能转成(内部通过Number方法)数字的,返回
NaN
- 如果没有参数,返回
- max([value1[,value2, ...]])
- 返回传入参数中最大的值
- 参数
- 0 到 n 个数字
- 注意:
- 如果没有参数,返回 -
Infinity
- 如果参数中包含不能转成数字的(内部通过Number方法),返回
NaN
- 如果没有参数,返回 -
案例:通过max和min实现商品累加,累减的判断
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button>-</button>
<span>0</span>
<button>+</button>
<script>
var btn = document.querySelectorAll("button");
var span = document.querySelector("span");
var num = Number(span.innerHTML);
btn[0].onclick = function(){
num--;
//判断商品不能小于0件
// if(num<=0){
// num = 0;
// }
//通过max实现判断商品不能小于0件
//当num小于0时,取最大值就会一直是0,如果大于0,就会取值num
num = Math.max(num,0);
span.innerHTML = num;
};
btn[1].onclick = function(){
num++;
//判断商品不能大于10件
// if(num>=10){
// num = 10;
// }
//通过min实现判断商品不能大于10件
//当商品数量<10时,取num;当商品数量>10时,取最小值即为10
num = Math.min(num,10);
span.innerHTML = num;
};
</script>
</body>
</html>
6.2.4绝对值 abs(x)
abs(x)
- 返回
x
的绝对值 - 参数
- 一个数值
- 注意:
- 传入参数如果不能转成数字的(内部通过Number方法),返回
NaN
- 传入参数如果不能转成数字的(内部通过Number方法),返回
var num = 2-17;
var num1 = 17-2;
console.log(Math.abs(num),Math.abs(num1));//15 15