隐式转换
两种类型的变量在进行运算或比较时,一种类型会向类一种进行转化,然后再进行比较和运算
加法
- 作为算数运算符 (除string类型外的原始数据类型进行加法运算时)非数字类型,会转为数字类型,通过Number()方法
- 作为字符串连接符(有一个操作数string类型以及引用数据类型时)
减法|乘法|除法
- 非数字类型会转为数字类型
- 如果是原始数据类型会调用Number()方法进行转换
- 如果是引用数据类型会调用自身valueOf方法进行转换,如果转换后不是原始值,则会调用toString方法进行转换,如果转换后不是数字,则会调用Number()进行转换,如果转换后不是数字则会返回NaN。
算数运算符
规则:
- 非数字基础数据类型:在后台调用 Number()将其转换为数值,然后再应用上面的规则。
- 引用数据类型:先调用valueOf() 得到的值无法计算再toString(),然后将toString()方法得到的结放Number()中转换
- NaN与任何数字进行算数运算返回值都为NaN
- 布尔值会转换为1/0
+
- 如果是 Infinity 加 Infinity,则结果是 Infinity;
- 如果是-Infinity 加-Infinity,则结果是-Infinity;
- 如果是 Infinity 加-Infinity,则结果是 NaN;// Infinity +(- Infinity )=NaN
- 如果是+0 加+0,则结果是+0;
- 如果是-0 加-0,则结果是-0;
- 如果是+0 加-0,则结果是+0。//+0-0=+0
如果有一个操作数是字符串,那么就要应用如下规则:
- 如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来;
- 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来;如果有一个操作数是对象、数值或布尔值,则调用它们的 toString()方法取得相应的字符串值,然后再应用前面关于字符串的规则。对于 undefined 和 null,则分别调用 String()函数并取得字符串"undefined"和"null"。
var result = true + false; //1
var result0 = 5 + false; //5
var result1 = 5 + true; //6
var result2 = NaN + 1; //NaN
var result3 = 5 + 3; //8
var result4 = 5 + ''; //'5'
var result5 = 5 + '2';//'52'
var result6 = 5 + null; //5
var result7 = {} + 1; //[object Object]1
var result8 = [] + 1;//'1'
var result9 = undefined + '999';//'undefined999'
var result10 = null + '123456';//'null123456'
var result11 = [] + [];//''
var result12 = [] + {};//'[object Object]'
var result13 = {} + {};//'[object Object][object Object]'
- 加法操作都应优先将操作数转为数字进行运算,转换不成功则为NaN
- 如果涉及到有操作数为字符串,则应将另一操作数转为字符串再进行拼接
- 如果涉及到对象,调用toString() 转为字符串后再运算
-
- 如果有一个操作数是 NaN,则结果是 NaN;
- 如果是 Infinity 减 Infinity,则结果是 NaN;//infinity-infinity=NaN
- 如果是-Infinity 减-Infinity,则结果是 NaN;
- 如果是 Infinity 减-Infinity,则结果是 Infinity;
- 如果是-Infinity 减 Infinity,则结果是-Infinity;
- 如果是+0 减+0,则结果是+0;
- 如果是+0 减-0,则结果是+0;
- 如果是-0 减-0,则结果是+0;
- 如果是-0 减+0,则结果是-0;
var result1 = 5 - true; //4
var result2 = NaN - 1; //NaN
var result3 = 5 - 3; //2
var result4 = 5 - ''; //5
var result5 = 5 - '2';//3
var result6 = 5 - null; //5
var result7 = {} - 1;//NaN
var result8 = [] - 1;//-1
var result9 = new Date() - 1;//时间戳-1
*
乘法操作符由一个星号(*)表示,用于计算两个数值的乘积。
- 如果有一个操作数是 NaN,则结果是 NaN;
- 如果是 Infinity 与 0 相乘,则结果是 NaN;// Infinity*0=NaN
- 如果是 Infinity 与非 0 数值相乘,则结果是 Infinity 或-Infinity,取决于有符号操作数的符号;
- 如果是 Infinity 与 Infinity 相乘,则结果是 Infinity
console.log(NaN * 1);//NaN
console.log(NaN * Infinity);//NaN
console.log(NaN * (-Infinity));//NaN
console.log(Infinity * (-Infinity)); //-Infinity
console.log(Infinity * Infinity); //Infinity
console.log(Infinity * 1); //Infinity
console.log(Infinity * (-1)); //-Infinity
console.log((-Infinity) * (-1)); //Infinity
console.log((-Infinity) * 1); //-Infinity
console.log(1 * {});//NaN
console.log(1 * []); //0
console.log(1 * [100]); //100
console.log(1 * { q: 1 }); //NaN
/
除法操作符由一个斜线符号(/)表示,执行第二个操作数除第一个操作数的计算
- 如果有一个操作数是 NaN,则结果是 NaN;
- 如果是 Infinity 被 Infinity 除,则结果是 NaN; // Infinity / Infinity = NaN
- 如果是零被零除,则结果是 NaN;
- 如果是非零数被零除,则结果是 Infinity 或-Infinity,取决于有符号操作数的符号;
- 如果是 Infinity被任何数值除,则结果是Infinity 或-Infinity,取决于有符号操作数的符号;// Infinity/0=Infinity
console.log(NaN / 1);//NaN
console.log(NaN / Infinity);//NaN
console.log(NaN / (-Infinity));//NaN
console.log(Infinity / (-Infinity)); // NaN
console.log(Infinity / Infinity); // NaN
console.log(0 / 0); // NaN
console.log(1 / 0); // Infinity
console.log(-1 / 0); // -Infinity
console.log(Infinity / 1); // Infinity
console.log(Infinity / (-1)); // -Infinity
console.log((-Infinity) / (-1)); // Infinity
console.log((-Infinity) / 1); // -Infinity
console.log(1 / {}); // NaN
console.log(1 / []); // Infinity
console.log(1 / [100]); // 0.01
console.log(1 / { q: 1 }); // NaN
%
取余操作符由一个百分号(%)表示
- 如果被除数是无穷大值Infinity 而除数是有限大的数值,则结果是 NaN;// Infinity%?=NaN
- 如果被除数是有限大的数值而除数是零,则结果是 NaN;// 5%0=NaN
- 如果是 Infinity 被 Infinity 除,则结果是 NaN; // Infinity % Infinity = NaN
- 如果被除数是有限大的数值而除数是无穷大的数值,则结果是被除数; // 5%Infinity = 5
- 如果被除数是零,则结果是零;// 0%1
console.log(Infinity % 0); // NaN
console.log(-Infinity % 0); // NaN
console.log(Infinity % 1); // NaN
console.log(999 % 0); // NaN
console.log(0 % 0); // NaN
console.log(Infinity % Infinity); // NaN
console.log(888 % Infinity); // 888
console.log(0 % 9); // 0
console.log(0 % Infinity); // 0
console.log(0 % (-Infinity)); // 0
console.log(0 % {}); // NaN
console.log(Infinity % {}); // NaN
console.log(Infinity % []); // NaN
console.log([] % Infinity); // 0
console.log([100] % Infinity); // 100
console.log({} % Infinity); // NaN
关系运算符
关系运算符的返回值为Boolean类型,常见的关系运算符为>、<、=、!=、>=、<=、、=
比较规则
- 如果两个操作数都是数值,则执行数值比较。
console.log(2 > 0);
console.log(2 < 0);
console.log(2 > NaN);
console.log(2 > Infinity);
console.log(2 > (-Infinity));
console.log(NaN < NaN);
- 如果两个操作数都是字符串,则比较两个字符串对应的字符编码值。
console.log('abc' < 'abd');
var str = 'cd';
console.log(str.charCodeAt(0));
console.log(str.charCodeAt(1));
console.log('abc' > 'abd');
- 任何操作数与NaN 进行关系比较,结果都是false
console.log({} < NaN);
console.log([] > NaN);
console.log('' < NaN);
console.log(1 > NaN);
console.log(true < NaN);
console.log(undefined < NaN);
console.log(null > NaN);
- 如果一个操作数是数值,则将另一个操作数转换为一个数值,然后执行数值比较。
console.log(1 > {});
console.log(1 > []);
console.log(1 > [33]);
console.log(1 < undefined);
console.log(1 > null);
console.log(1 > '111');
console.log(1 > '111%');
- 如果操作数是对象,则这个对象将先使用valueOf()转换成原始值,如果结果还不是原始值,则再使用toString()方法转换;在对象转换为原始值之后
- 如果两个操作数都是字符串,则按照字母表的顺序对两个字符串进行比较。
console.log('a' < {});
2. 如果至少有一个操作数不是字符串,则两个操作数都转换成数字进行比较。
console.log(true < {});
console.log(true > []);
- 如果一个操作数是布尔值,则先将其转换为数值,然后再执行比较。
console.log(true < '12')
console.log(true < []);
console.log(true < {});
在使用关系操作符比较两个字符串时,会执行一种奇怪的操作。很多人都会认为,在比较字符串值时,小于的意思是“在字母表中的位置靠前”,而大于则意味着“在字母表中的位置靠后”,但实际上完全不是那么回事。在比较字符串时,实际比较的是两个字符串中对应位置的每个字符的字符编码值。经过这么一番比较之后,再返回一个布尔值。由于大写字母的字符编码全部小于小写字母的字符编码,因此我们就会看到如下所示的奇怪现象:
var result = "Brick" < "alphabet";
在这个例子中,字符串"Brick"被认为小于字符串"alphabet"。原因是字母 B 的字符编码为 66,而字母 a 的字符编码是 97。如果要真正按字母表顺序比较字符串,就必须把两个操作数转换为相同的大小写形式(全部大写或全部小写),然后再执行比较,如下所示:
var result = "Brick".toLowerCase() < "alphabet".toLowerCase();
、=!与=
- 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false 转换为 0,而true 转换为 1;
- 如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值;
- 如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf()方法,toString()用得到的基本类型值按照前面的规则进行比较;
- null 和 undefined 是相等的。
- 要比较相等性之前,不能将 null 和 undefined 转换成其他任何值(null == 0为false)。
- 如果有一个操作数是 NaN,则相等操作符返回 false,而不相等操作符返回 true。
- 如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回 true;否则,返回 false。
[] == '0'; // false 将[]转为字符串再与'0'比较
{} == '[object Object]'; // true 将{}转为字符串再与'[object Object]'比较
[] == 0; // true 将[]转为数字再与0作比较
[] == true; // false
// '' == 1 ---> 0 == 1
[] == false; // true
// '' == false ---> '' == 0 ---> 0 ==0
'abc' == true; 'abc' == 1 NaN == 1
console.log(1 == true);
console.log(1 == false);
console.log(true == true);
console.log('111' == '11');
console.log('whr' == 'w hr');
console.log(null == undefined); // true 规定
console.log(false == undefined); // false
console.log(null == 0); // false *****要比较相等性之前,不能将 null 和 undefined 转换成其他任何值
console.log(null == null);
console.log(undefined == undefined);
console.log(NaN == NaN);
console.log(NaN.toString() == NaN.toString());
console.log(NaN != NaN);
除了在比较之前不转换操作数之外,全等和不全等操作符与相等和不相等操作符没有什么区别。全等操作符由 3 个等于号(===)表示,它只在两个操作数未经转换就相等的情况下返回 true,如下面的例子所示:
var result1 = ("55" == 55); //
var result2 = ("55" === 55); //
不全等操作符由一个叹号后跟两个等于号(!==)表示,它在两个操作数未经转换就不相等的情况下返回 true。例如:
var result1 = ("55" != 55);
var result2 = ("55" !== 55);
记住: null == undefined 会返回 true,因为它们是规定;但 null === undefined 会返回 false,因为它们是不同类型的值。
由于相等和不相等操作符存在类型转换问题,为了保持代码中数据类型的完整性,推荐使用全等和不全等操作符。
console.log('5' == 5);
console.log('5' === 5);
console.log(5 === 5);
console.log('5' !== 5);
console.log('5' != 5);
console.log(null === undefined);
// 注意:全等之引用类型
console.log(11 === 11); // 比较值相等 并且类型相同
console.log({} == {}); // false
console.log({} === {}); // false 引用类型全等 类型一样 引用地址也得一样
var obj1 = {};
var obj2 = obj1;
console.log(obj1 == obj2); // true
console.log(obj1 === obj2); // true
递增递减运算符
和--表示对变量的+1和-1操作,但是和--的相对于变量的位置是有区别的
var age = 29;
console.log(age++);//++在后,先使用变量再自加
console.log(++age);//++在前,先变量自加再使用
var age = 29;
var anotherAge = --age + 2;//29-1+2=28+2
alert(age); //28
alert(anotherAge); //30
var num1 = 2;
var num2 = 20;
var num3 = --num1 + num2;//2-1+20=1+20
var num4 = num1 + num2;//1+20
var num1 = 2;
var num2 = 20;
var num3 = num1-- + num2;//2+20
var num4 = num1 + num2; //1+20
var a = 2;
var b = 3;
var c = (++a) + (b++) + b + (a++) - a;//(2+1)+(3)+4+(3)-4=9
- 在应用于一个包含有效数字字符的字符串时,先将其转换为数字值,再执行加减 1 的操作。字符串变量变成数值变量。
- 在应用于一个不包含有效数字字符的字符串时,将变量的值设置为 NaN。字符串变量变成数值变量。
- 在应用于布尔值 false 时,先将其转换为 0 再执行加减 1 的操作。布尔值变量变成数值变量。
- 在应用于布尔值 true 时,先将其转换为 1 再执行加减 1 的操作。布尔值变量变成数值变量。
- 在应用于浮点数值时,执行加减 1 的操作。
- 在应用于对象时,先调用对象的 valueOf()方法(后面章节将详细讨论)以取得一个可供操作的值。然后对该值应用前述规则。如果结果是 NaN,则在调用 toString()方法后再应用前述规则。对象变量变成数值变量。
var s1 = " 2";//2
var s2 = "z";//NaN
var b = false;//0
var f = 2.1;//2.1
var o = {
valueOf: function() {
return -1;
}
};
console.log(s1++); //2
console.log(s1); //3
++s2;//NaN
console.log(s2);//NaN
console.log(b++);//0
console.log(b);//1
f--; //2.1
console.log(f--);//1.1
console.log(f);//0.1
o--; //-1
console.log(o--);//-2
console.log(o);//-3
逻辑运算符
逻辑非
逻辑非操作符由一个叹号(!)表示,可以应用于 ECMAScript 中的任何值。无论这个值是什么数据类型,这个操作符都会返回一个布尔值。
alert(!false); //true
alert(!"blue"); //false
alert(!0); //true
alert(!NaN); //true
alert(!""); //true
alert(!12345);//false
同时使用两个逻辑非操作符,也可以用于将一个值转换为与其对应的布尔值,,如下面的例子所示:
alert(!!"blue"); // true
alert(!!0); // false
alert(!!NaN); // false
alert(!!""); // false
alert(!!12345); // true
逻辑与 (遇到假值阻塞)
逻辑与操作符由两个和号(&&)表示,有两个操作数,如下面的例子所示:
var result = true && false;
逻辑与操作属于短路操作,即如果第一个操作数能够决定结果,那么就不会再对第二个操作数求值。对于逻辑与操作而言,如果第一个操作数是 false,则无论第二个操作数是什么值,结果都不再可能是true 了。
遇到假值阻塞:表达式从左到右一一判断,若是假值(false),停止判断,返回假值;若没有假值,则返回最后一个真值。
console.log('' && 3); // ''
console.log(9 && 3); // 3
console.log({} && ''); // ''
console.log({} && [] && 8 && new Number() && NaN); // NaN
逻辑或 (遇到真值阻塞)
逻辑或操作符由两个竖线符号(||)表示,有两个操作数,如下面的例子所示:
var result = true || false;
与逻辑与操作符相似,逻辑或操作符也是短路操作符。也就是说,如果第一个操作数的求值结果为true,就不会对第二个操作数求值了。下面看一个例子:
console.log('' || 3); // 3
console.log(9 || 3); // 9
console.log({} || ''); // {}
console.log('' || 0 || false || NaN || undefined || null); // null
遇到真值阻塞:表达式从左到右一一判断,若是真值(true),停止判断,返回真值;若没有真值,则返回最后一个假值。
var c = (a = 3) || (b = 4);//返回3
console.log(a);//3
console.log(b);//报错
console.log(c);//3
var c = (a = 0) || (b = 4);//返回4
console.log(a);//0
console.log(b);//4
console.log(c);//4
5 && 6 && 8 && '' && 0 || 1;//''||1 1
5 && 6 && 8 && '' && 0;//''
'' || 2 && 3 || '';//2&&3||'' 3||'' 3
一元加减运算符
一元加操作符以一个加号(+)表示,放在数值前面,对数值不会产生任何影响,如下面的例子所示:
var num = 25;
num = +num; // 仍然是 25
不过,在对非数值应用一元加操作符时,该操作符会像 Number()转型函数一样对这个值执行转换。
var s1 = "01";
var s2 = "1.1";
var s3 = "z";
var b = false;
var f = 1.1;
var o = {
valueOf: function() {
return -1;
}
};
s1 = +s1; // 1
s2 = +s2; // 1.1
s3 = +s3; // NaN
b = +b; // 0
f = +f; // 1.1
o = +o; // -1
一元减操作符主要用于表示负数,例如将 1 转换成-1。下面的例子演示了这个简单的转换过程:
var num = 25;
num = -num; //-25
var s1 = "01";
var s2 = "1.1";
var s3 = "z";
var b = false;
var f = 1.1;
var o = {
valueOf: function() {
return -1;
}
};
s1 = -s1; // -1
s2 = -s2; // -1.1
s3 = -s3; // NaN
b = -b; // -0
f = -f; // -1.1
o = -o; // 1
三目运算符
var max = (num1 > num2) ? num1 : num2;
(num1 > num2)结果为true;返回num1;否则,返回Num2
复合赋值运算符
- 乘/赋值(*=);
- 除/赋值(/=);
- 模/赋值(%=);
- 加/赋值(+=);
- 减/赋值(-=);
var num = 10;
num += 10; // num=num+10
逗号运算符
使用逗号操作符可以在一条语句中执行多个操作,如下面的例子所示:
console.log(num1,num2,num3)
var num1=1, num2=2, num3=3;
逗号操作符多用于声明多个变量;但除此之外,逗号操作符还可以用于赋值。在用于赋值时,逗号操作符总会返回表达式中的最后一项,如下面的例子所示:
var num = (5, 1, 4, 8, 0); // num 的值为 0
由于 0 是表达式中的最后一项,因此 num 的值就是 0。虽然逗号的这种使用方式并不常见,但这个例子可以帮我们理解逗号的这种行为。
函数调用时,值用逗号分开,是传参不是逗号运算
console.log(100,false,{});
if( 100, console.log(false), document.write("文本输出") ){
console.log("内部");
}
var i = 0,
j = 0;
// 初始值 结束判断 每次语句块执行完追加执行
for (i, j; i < 5, j < 10; i++, j++) {
console.log(i, j);
}
console.log(i, j)//20
function fn() { console.log(222); }
if (false, fn(), true) {
console.log(333);
}
标签:操作数,Infinity,log,NaN,运算符,var,console
From: https://www.cnblogs.com/Kongqingzhi/p/16608453.html