5、Math中的常用方法(10个)6、Date日期操作基础详解以及常用方法(12个)
5、Math中的常用方法(10个)
数学函数:但是它是对象数据类型的typeof Math ->"object
Math对象中给我们提供了很多常用操作数字的方法console.log(Math)查看所有方法
Mat bs
:取绝对值
Math.ceil/floor
:向上取整/向下取整
Math.round
:四舍五入
Math.random
:获取[0,1)之间的一个随机数
- Math.round(Math.random()*(b-a)+a):获取a-b之间的一个随机数
Math.max/min
:获取几个数中的最大/最小值
Math.PI
:获取圆周率
Math.pow/sqrt
:
pow() 方法可返回 x 的 y 次幂的值。
sqrt() 方法可返回一个数的平方根。
6、Date日期操作基础详解以及常用方法(12个)
Date是日期类,通过它可以对时间进行处理
Date上的静态方法:now()
now()方法返回自1970年1月1日 00:00:00 UTC到当前时间的毫秒数,类型为Number。
因为 now() 是Date的一个静态函数,所以必须以 Date.now() 的形式来使用。
var time=new Date();//获取当前客户端本机时间
//获取的结果是一个日期格式的对象:Sun Oct 22 2017 15:58:40 GMT+0800 (中国标准时间)
time.getFullYear()//获取四位整数年
time.getMonth()获取月(0-11代表1-12月)
time.getDate()获取日
time.getDay()获取星期(0-6代表周日-周六)
time.getHours()获取小时
time.getMinutes()获取分钟
time.getSeconds()获取秒
time.getMilliseconds`['mɪlisekənd]` ()获取毫秒
time.getTime()获取当前日期距离'1970-01-01 00:00:00'的毫秒差
time.toLocaleString():根据本地时间规则把time转化为字符串并返回结果;
var time = new Date('2017-10-22'); //当new Date中传递一个时间格式的字符串,相当于把这个字符串转换为标准格式的时间对象
'2017-10-22' (IE下识别不了)
将time='2017-10-24';转化为'2017/10/24'的方法:
1.用replace+正则处理
2.用字符串拆分+join转换为数组
3.用time=new Date(time);然后用Date对象的方法获取到年月日之后用'/'拼接;
7、字符串中的方法(12个带上 trim都不会改变原字符串)
在JS中用单/双引号包裹起来的都是字符串
字符串就是由0-多个字符组成的字串
1.以数字为索引,从零开始
2.有length属性,存储的是当前字符串中字符的个数(字符串的长度)
字符串的查询
charAt && charCodeAt
str.charAt(索引):返回指定位置的字符
<font color=red>字符串可以用[]访问单个字符,为什么还要用charAt()?区别如下:<font>
- str[index],IE7及以下不兼容,index超不超出字符串的长度都会返回undefined;
- str.charAt(index):对于超出index 范围的值,会返回空字符串,IE6-8兼容
str.charCodeAt(索引):返回指定位置字符的Unicode编码值(对应ASCII码表)
String.fromCharCode(十进制的Unicode值):把Unicode值转换为对应的字符
indexOf && lastindexOf
(字符串中的兼容所有浏览器)
str.indexOf('A'):获取A字符在str中第一次出现位置的索引
str.lastindexOf('A'):获取A字符在str中最后一次出现位置的索引
如果当前字符没有在str中出现过,则返回-1,我们可以根据这个规律验证一下字符串中是否包含某个字符
字符串的截取
slice && substr && substring
1.slice(start,end)
- start:要抽取的字串的起始下标(从0开始,可不写,如果不写start,则end也不能写,结果返回整个字符串),支持负数,-1表示字符串的最后一个字符)
- end:子字符串的结束位置,包含start,而不包含end。(可不写,不写的话则返回start到原字符串结尾,如果为负数,-2则表示到子字符串的倒数第二个字符结束)
说明
1:<font color=red>start >= end</font>,则返回空字符串
2:<font color=red>start或end超出范围</font>,只截取未超出范围的字符,没有返回空字符串
var m='zhufengpeixun';
var f=m.slice(12,15);
console.log(f);//"n";
2.substr(start,length)['sʌbstər]
- start:要抽取的字串的起始下标(可不写,如果不写start,则end也不能写,结果返回整个字符串),支持负数,-1表示字符串的最后一个字符)
- length:子串的字符数,必须是数值。如果省略了该参数,那么返回从 stringObject 的开始位置到结尾的字串。如果为0或负数,则返回空字符串
提示和注释
注释:substr() 的参数指定的是子串的开始位置和长度,因此它可以替代 substring() 和 slice() 来使用。
<font color=red>重要事项:</font>ECMAscript 没有对该方法进行标准化,因此反对使用它。
3.substring(start,end)
- start:要抽取的字串的起始下标(从0开始,可不写,如果不写start,则end也不能写,结果返回整个字符串)
- end:子字符串的结束位置,包含start,而不包含end。(可不写,不写的话则返回start到原字符串结尾)
说明
1:<font color=red>start = end</font>,则返回空字符串
2:<font color=red>start >end</font>,那么该方法在提取子串之前会先交换这两个参数。
3:<font color=red>start或end超出范围</font>,只截取未超出范围的字符,没有返回空字符串
<font color=red>重要事项:</font>与 slice() 和 substr() 方法不同的是,substring() 不接受负的参数,会将负数转换为0,然后和start调换位置
字符串转换为数组
split
str.split():按照某一个字符把字符串分割成数组,参数为字符或者正则
a.split(''):将字符串分割为单个字符的数组
a.spit(' '):将字符串分割为单词组成的数组
字符串的修改
replace
str.replace(n,m):把字符n替换成为字符m。
注意
:replace并不会修改原来的字符串,而是返回一个新的字符串
1.在不使用正则的情况下,每次执行只能替换第一个匹配的字符串
2.第一项为正则时,正则捕获几次,就替换几次,换成函数也同理,正则捕获几次,函数就执行几次,函数中返回的是什么,就相当于把正则捕获的内容替换成什么。
3.如果换成函数,函数中会默认传入三个参数,arguments(当前函数的参数集合)
str.replace(/zhufeng/g,function(content,index,input){
arguments(捕获到的内容,索引,原始字符串集合)
默认传入的参数:
如果传入的正则中有小括号,
arguments[1] = 第一个小括号捕获的内容
arguments[2] = 第二个小括号捕获的内容…直到小括号捕获的内容显示完,然后才继续显示索引
arguments[n] = 每一次捕获的开始索引
arguments[n+1] = 原始字符串
传入的正则中没有小括号
arguments[0] = content:每一次捕获的大正则内容
arguments[1] = index:每一次捕获的开始索引
arguments[2] = input:原始字符串
})
字符串的大小写转换
toUpperCase && toLowerCase
str.toUpperCase:把字母转换为大写
str.toLowerCase:把字母转换为小写
字符串中去除空格
trim && trimLeft &&trimRight
**
str.trim():去除字符串两端的空白字符
str.trimLeft():去除字符串左边的空白字符
str.trimRight()):去除字符串右边的空白字符
8、数组的结构方法和去重(带上map和forEach共15个
)
数组也是对象数据类型的->'object'
数组也有属性名,只不过属性名是数字,我们把数字属性名叫做索引
类数组:类似于数组,但是不是数组
数组中常用的方法
1.方法的意义和作用
2.方法需要的参数
3.方法的返回值
4.方法执行后原有数组是否改变
数组的增删
方法名 | 含义 | 参数 | 返回值 | 原有数组是否改变 |
---|---|---|---|---|
unshift | 将数据添加到一个数组的开头 | 新增加的内容 | 新增后数组的最新长度 | 变 |
push | 将数据添加到一个数组的末尾 | 一到多个,需要新增加的内容 | 新增后数组的最新长度 | 变 |
pop | 移出数组中最后一个元素 | 无 | 被删除的这一项内容 | 变 |
shift | 移出数组中第一个元素 | 无 | 被删除的这一项内容 | 变 |
也可以把数组当作普通对象,使用对象键值对的操作,给其设置新的属性(索引):
增加:ary[ary.length]=向数组的末尾追加了新的内容
删除:
- delete删除:
delete ary[索引]
删除指定索引这一项(当前项被删除后,原有数组其它项的索引不会改变;当前数组的length也不会改变;) - ary.length- -:删除数组最后一项
数组的修改
方法名 | 含义 | 参数 | 返回值 | 原有数组是否改变 |
---|---|---|---|---|
splice(n,m) | 从索引n开始删除m个元素 | n,m | 被删除的会以一个新数组返回 | 变 |
splice(n) | 从索引n开始删除到末尾 | n | 被删除的会以一个新数组返回 | 变 |
splice(0) | 清空数组 | 0 | 被清空的会以一个新数组返回 | 变 |
splice(n,m,x) | 从索引n开始用x替换m个元素,如果m为0,则表示把x增加到n的前面 | n,m,x | 被替换的的会以一个新数组返回 | 变 |
数组的查询
方法名 | 含义 | 参数 | 返回值 | 原有数组是否改变 |
---|---|---|---|---|
slice(n,m) | 从索引n开始找到m处(不包含m) 注意 :某一项的话需要用项数减一来获取索引 |
n,m | 把找到的部分以一个新数组返回 | 不变 |
slice(n) | 从索引n开始找到末尾 | n | 把找到的部分以一个新数组返回 | 不变 |
slice()/(0) | 克隆数组 | 0 | 克隆原有数组并以一个新数组返回 | 不变 |
slice支持负数索引,如果传递的索引为负数,浏览器解析的时候是按照 总长度+负数索引 来处理的
数组的拼接
方法名 | 含义 | 参数 | 返回值 | 原有数组是否改变 |
---|---|---|---|---|
concat(数组) | 用于连接两个或多个数组 | 一个或多个数组也可以是具体值 | 连接后的数组 | 不变 |
concat() | 克隆数组 | 无 | 克隆后的数组 | 不变 |
数组的转化
方法名 | 含义 | 参数 | 返回值 | 原有数组是否改变 |
---|---|---|---|---|
toString() | 把数组转换为字符串 | 无 | 数组的每一项在字符串中用逗号隔开(一个字符串) | 不变 |
join(符号) | 把数组的每一项按照指定连接符拼接成字符串 | 连接符 | 指定连接符拼接成的字符串 | 不变 |
var total=eval(ary.join('+')) total=数组的和
数组的排序
方法名 | 含义 | 参数 | 返回值 | 原有数组是否改变 |
---|---|---|---|---|
reverse() | 用于颠倒数组中元素的顺序 | 无 | 颠倒后的数组 | 变为颠倒后的数组 |
sort() | 把数组进行排序 | 不填则只给10以下的数排序或填写函数 | 排序后的数组 | 变为排序后的数组 |
ary.sort(function(a,b){
return a-b;//实现数组按升序排列
return b-a;//实现数组按降序排列
})
//实现原理:每次拿出数组中的当前项和后一项,每一次比较都会让匿名函数执行一次,不仅执行,而且还给匿名汉书传递了两个参数a,b
a:当前项
b:当前项的后一项
在匿名函数中,如果return的结果是一个大于0的数,让a和b交换位置
如果return 的结果是一个小于等于0,则不交换;
验证数组中是否包含某一项
A.indexOf(B)/lastIndexOf:和字符串相同,获取B项在数组A中第一次/最后一次出现位置的索引,如果数组中没有这一项返回-1(不兼容IE6-8,在不考虑兼容的情况下,我们可以根据这个规律验证数组中是否包含某项)
兼容写法:
Array.prototype.myIndexOf=function(value){
var result=-1;
for(var i=0;i<this.length;i++)
if(value===this[i]){
result=i;
break;
}
return result;
}
遍历数组中的每一项
(ES5独有IE6-8不兼容)
以下方法IE6-8不兼容
every() :对数组中的每一项运行给定函数,如果该函数对每一项都返回 true ,则返回 true ,只要有一项返回false,就直接返回false;
注意:如果调用every方法的数组为一个空数组,那么不会运行传递的回调函数,直接返回true(此处涉及every的判别机制问题)
var numbers = [1,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(function(item, index, array){
return (item > 2);
});
console.log(everyResult)//false
some() :对数组中的每一项运行给定函数,只要有一项运行函数后返回 true ,就直接返回 true ,否则返回false
注意:如果调用some方法的数组为一个空数组,那么不会运行传递的回调函数,直接返回false(此处涉及some的判别机制问题)
var numbers = [1,2,3,4,5,4,3,2,1];
var everyResult = numbers.some(function(item, index, array){
return (item > 2);
});
console.log(everyResult)//true
filter() :对数组中的每一项运行给定函数,返回运行给定函数返回 true 的项组成的数组
。
var numbers = [1,2,3,4,5,4,3,2,1];
var filterResult = numbers.filter(function(item, index, array){
return (item > 2);//如果没有符合的项,filterResult则是一个空数组
});
console.log(filterResult);//[3,4,5,4,3]
forEach() :对数组中的每一项运行给定函数。这个方法没有返回值。(本质上与for循环迭代一样)
map() :对数组中的每一项运行给定函数,返回是一个新的数组,数组中包含每次运行给定函数返回的结果。
以上方法都不会修改数组中的包含的值
forEach:不修改原来的数组,无返回值
forEach:遍历数组中的每一项,不对原来的数组进行修改。不支持return,没有返回值。第二个参数表示传的是谁就把function中的this修改为谁,可不写默认为window
ary.forEach(function(value,index){
//=>数组中有多少项,当前回调函数执行多少次;每一次传递进来的value就是当前遍历数组这一项的值,index就是遍历这一项的索引
},this(可选))
map:不修改原来的数组,支持返回值
(返回的是一个数组)
map:和forEach非常相似,map 的回调函数中支持return返回值,return的是什么相当于把数组中这一项改为什么(但是并不改变原来的数组,只是相当于把原数组克隆了一份,修改了克隆的数组里面每一项的值)
第二个参数表示传的是谁就把function中的this修改为谁,可不写默认为window。
var numbers = [1,2,3,4,5,4,3,2,1];
var mapResult = numbers.map(function(item, index, array){
return item * 2;
});
console.log(mapResult); //[2,4,6,8,10,8,6,4,2]
ary.map(function(value,index){
//=>数组中有多少项,当前回调函数执行多少次;每一次传递进来的value就是当前遍历数组这一项的值,index就是遍历这一项的索引
return xxx; //=>RETURN后面返回的结果就是把当前遍历的这一项修改为xxx
});
map执行完成后返回一个新的数组
归并方法:
reduce(fn,initValue)和 reduceRight(fn,initValue):
(IE6-8不兼容)
这两个方法都会循环数组的所有项,然后构建一个最终返回的值。都支持两个参数,第一个参数为循环每一次执行的回调函数,第二个参数为循环第一次的时候给的回调函数中prev的初始值;区别在于从哪头开始遍历数组,除此之外,它们完全相同;
注意:不设置初始值的时候,会把数组中的第一项的值赋给回调函数中的prev,从第二项开始循环,fn执行的次数为 数组的长度-1。如果设置了prev的初始值,就会从第一项开始循环。fn的执行次数为 数组的长度
每次循环执行回调函数都会默认传递四个参数prev, cur, index, array
prev:上一次累积的值(前提是回调函数中必须有返回值,没有返回值则从第二次开始就是undefined)
cur:当前循环的那一项
index:当前项的索引
array:原始数组
不设置初始值
var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, cur, index, array){
return prev + cur;
});
console.log(sum);//15
获取两个对象中age相加的值(设置初始值相当于把第一次循环时prev的值设置为了0)
var values = [{name:'zhufeng',age:9},{name:'zhufeng',age:21}];
var sum = values.reduce(function(prev, cur, index, array){
第一次循环prev为0
return prev + cur.age;
},0);
console.log(sum);
ES6中新增的数组方法
find(fn,this(可选)):返回数组中符合条件的项,不修改原来的数组
findIndex(fn,this(可选)):返回数组中符合条件的项的索引,不修改原来的数组
这两个方法都可以接受第二个参数,用来改变回调函数fn中的this。
它的第一个参数是一个回调函数,支持三个参数依次为当前的值、当前的索引和原数组。所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员,停止循环。findIndex返回的是符合条件的数组成员的索引,如果没有符合条件的成员,find返回undefined,findIndex返回-1。
数组的去重
思想:
方案一双循环:拿数组中的每一项和它后面的每一项比较,如果相同则删除后面的那一项
for(var i=0;i<ary.length-1;i++){
var val=ary[i];
for(var k=i+1;k<ary.length;k++){//拿第一项从第二项开始作比较所以k从1开始
if(val===ary[k]){
ary.splice(k,1);
//splice会导致数组塌陷,即删除项后面的每一项的索引都会-1,此时j++会跳过删除项后面的第一项,从第二项开始比较
k--;//解决数组塌陷问题,相当于k没加没减继续拿
}
// val===ary[k]?ary.splice(k,1):k++;//这种方式也可以解决数组塌陷问题,需要把大循环中的i++删除,
}
}
方案二:用indexOf来验证当前数组中是否包含某一项,包含则把当前项删除掉(不兼容IE6-8);
function uniqe(ary) {
for (var i = 0; i < ary.length;) {
var cur = ary[i];
var val = ary.slice(i + 1);//当前项后面的项组成的一个新数组
val.indexOf(cur) > -1 ? ary.splice(i, 1) : i++;
}
return ary;
}
方案三:利用对象中属性名不能重复的原理,循环数组中的每一项,把每一项当做属性名在对象中验证其值是否存在(typeof obj[cur[i]]==='undefined'),如果在对象中不存在(true),把最后一项的值赋值给当前项,然后删除最后一项;
function oSort(ary) {
var obj={};
for(var i=0;i<ary.length;i++){
var cur=ary[i];
if(obj[cur]===cur){
ary[i]=ary[ary.length-1];
ary.length--;
i--;
continue;
}
obj[cur]=cur;
}
obj=null;
return ary;
}
方案四:先将原数组排序,排完序之后重复的项都会靠在一起,创建一个空的数组,然后把原数组中的第一项放到新数组中,然后循环原数组,从第二项开始,和新数组中的最后一项比较是否相等,如果不相等,则把原数组中的这一项添加到新数组的末尾,最后返回新数组即可;(<font color=red>有局限性:因为在去重之前会把原数组排序,所以会改变原来的数组</font>)
Array.prototype.myUnique=function(){
var ary=this.sort(),
val=[];
val.push(ary[0]);
fot(var i=1;i<ary.length;i++){
var obj=ary[i];
if(obj!==val[val.length-1]){
val.push(obj);
}
}
return val;
}
冒泡排序
原理:让数组中的当前项和后面的每一项进行比较,如果当前项大于后一项,我们让两者交换位置(小—大)
function bubble(ary) {
//->外层循环控制的是比较的轮数:
for (var i = 0; i < ary.length - 1; i++) {
//->里层循环控制每一轮比较的次数
for (var k = 0; k < ary.length - 1 - i; k++) {
//ary[k]:当前本次拿出来这一项
//ary[k+1]:当前项的后一项
if (ary[k] > ary[k + 1]) {
//当前项比后一项大,我们让两者交换位置
var temp = ary[k];
ary[k] = ary[k + 1];
ary[k + 1] = temp;
}
}
}
return ary;
}
每一轮从前到后两两比较,虽然不一定实现最后的排序效果,但是可以把当前最大的放在末尾
具体比较的轮数:ary.length-1 数组有多长,我们只需要把总长度-1个数分别放在末尾,即可实现最后的排序
对于数组[12, 13, 23, 14, 16, 11];
第一轮比较5次:一共六个,不需要和自己比较
第二轮比较4次:一共六个,不用和自己比,也不用和第一轮放在末尾的那个最大值比
第三轮比较3次
每一轮比较的次数 ary.length-1(不用和自己比)-当前已经执行的轮数(执行一轮向末尾放一个最大值,这些值不需要再比较)
快速排序
原理:先找数组中的中间项,然后和其余项作比较,比中间项小的放在左边(新数组),大的放在右边(新数组);然后使用递归方法,把左边的数组和右边的数组再次调用快速排序,最后把递归后的结果(都是数组)连接起来并返回
function quick(ary){
//如果传进来的数组只有一项或者是空的,我们则不再继续取中间项拆分
if(ary.length<=1)return ary;
//获取中间项的索引:把中间项的值获取到,在原有数组中删除中间项
var oIndex=Math.floor(ary.length/2);
var val=ary.splice(oIndex,1)[0];//->splice返回的是个数组,数组中包含了删除的那个内容
//用中间项和数组中剩下的项作比较,比中间项大放在右边,小的放在左边(左右两边都是新数组)
var aryLeft=[],aryRight=[];
for(var i=0;i<ary.length;i++){
var cur=ary[i];
cur>val?aryRight.push(cur):aryLeft.push(cur);
}
//然后使用递归方法,把左边的数组和右边的数组也快速排序
//最后把递归后的结果(都是数组)和中间项连接起来,并返回
return quick(aryLeft).concat(val,quick(aryRight));
}
插入排序法
原理:类似抓牌,先从数组中拿出一项(一般都是第一项)放在手中(一个新的空数组中),然后循环数组中剩下的项,和手中现有的项作比较,如果数组中的项比手中当前项小,就把数组中的项放在手中当前项的前面。如果数组中的项比手中当前项大,则不进行操作,进行下一次循环比较。如果数组中的项比手中最后一项还要大,则把数组中的项放在手中最末尾的位置;
function insert(ary) {
var handAry=[];
//从数组中抽取第一项放到手中
handAry.push(ary[0]);
//拿数组中剩余的项(i从1开始)和手中的项做比较
for (var i = 1; i <ary.length; i++) {
var obj = ary[i];//数组中剩下的项
//因为往手中增加项会导致长度改变,所以要把没添加之前的长度存起来(len=handArray.length);
for (var k = 0; k <handAry.length; k++) {
//handAry[k]:当前比较的手里的牌
//新抓的牌比当前比较的这张牌小,我们就把新抓的放在当前比较这张牌的前面
if(obj<handAry[k]){
handAry.splice(k,0,obj);
break;
}
//如果数组中的项比较到了最后一项以上条件还未满足,则说明数组中的项比手中最后一项还要大,就把它添加到末尾
if(k===len-1){
handAry.push(obj);
break;
}
}
}
return handAry;
}
数组排序+去重(自己总结的wihle循环方法)
function mySortAndUnique(ary) {
var obj={},val=[],len=ary.length;
//去重
while (len--){
obj[ary[len]]=ary[len];
}
//利用
for (var key in obj) {
if(obj.hasOwnproperty(key)){
val.push(obj[key]);
}
}
obj=null;
return val;
}
9、数据类型转换
把其他数据类型转换为number类型
什么情况下会把其他数据类型转换为number类型?
- 1、isNaN、Number、parseInt、parseFloat
- 2、在进行加减乘除数值运算的时候
<font color=red>特殊:</font>
null->0
undefined->NaN
引用数据类型转换为数字:都为NaN,单个数值的数组或空数组除外
Number({})->NaN
Number([])->0
Number([9])->9
Number(['19'])->19
- 先通过toString方法将对象转化为字符串,之后再调用Number方法把字符串转化为数字
JS中的数学运算
+、-、*、/
除了加号,具有特殊性,其余的运算符都是数学运算,也就是遇到非数字类型的,会调用number转换为number类型再运算
加法的特殊性:在遇到字符串的时候,+ 不是数学运算,而是字符串拼接,只要不遇到字符串就是数学运算。字符串拼接:是把其他值转换为字符串再进行拼接
- <font color=red>提示:</font>对于Number、String、Boolean、Array、RegEx、Date、Function原型上的toString方法都是把当前数据类型转换为字符串的类型(它们的作用仅仅是用来转换为字符串的)
把其他数据类型转换为布尔类型
什么情况下会把其他数据类型转换为布尔类型?
- 1.Boolean、!、!!
- 2.在条件判断的时候,先转换为布尔类型,再验证是否成立
- <font color=red>提示:</font>只有null,undifined,NaN,±0,空字符串,会转化为false其他都转化为true
比较运算符
== 操作符是只比较值,而不比较数据类型;
===操作符既比较值,也比较数据类型,都相等才返回true;
在使用 == 进行比较的时候,如果左右两边数据类型不相同,浏览器会默认转换为相同的类型,然后再比较(===
不会这样操作)
所有对象转化为布尔值都是true(包括空对象)高程三27,电子书45页,null不是对象数据类型的,所以转化为false
比较规则如下:
- 1,数字 == 字符串 在比较相等性之前先将字符串转换为数字;(空字符串转化为0)
- 2,布尔 == xxx 只要有布尔就都转化为数字比较
- 3,xxx == 对象
- 先将对象转化为字符串(调用内置类(Array、RegExp、Data、Math、Function)上的toString方法)然后遵循以下比较规则:
(如何验证对象和xxx比较是先把对象转化为字符串[12,14,15]=='12,14,15')
<font color=red>注意:</font>Object上的 toString 方法不是转换为字符串的,而是检测数据类型的;
- xxx为 字符串 时,用对象转化后的字符串与xxx比较;
- xxx为 数字 时,把对象转化后的字符串再转化为数字后比较
- xxx为 布尔值 时,把对象转化后的字符串再转化为数字,把布尔值也转化为数字再比较;
- 4,对象 == 对象 只有两个对象都指向同一个内存空间才返回true
- 5,null或者undefined 和其它任何值都不相等
- null===null//true
- undefined===undefined//true;
10、逻辑运算符
&&:逻辑与
在有一个操作数不是布尔值的情况下,&&操作就不一定返回布尔值;此时,它遵循下列规则:
- 1,如果第一个操作数是对象,则返回第二个操作数;
- 2,如果第二个操作数是对象,则只有在第一个操作数的求值结果为 true 的情况下才会返回第二个对象;
- 3,如果两个操作数都是对象,则返回第二个操作数;
||:逻辑或
如果有一个操作数不是布尔值,逻辑或也不一定返回布尔值;此时,它遵循下列规则:
- 1,如果第一个操作数是对象,则返回第一个操作数;
- 2,如果第一个操作数的求值结果为 false ,则返回第二个操作数;
- 3,如果两个操作数都是对象,则返回第一个操作数;
总结
逻辑或操作符都是短路操作符:
对于 && 来说,如果第一个操作数的求值结果为false ,就不会对第二个操作数求值了。
对于 || 来说,如果第一个操作数的求值结果为true,就不会对第二个操作数求值了。