// 知其然并且知其所以然 // 开发中合理运用
显式强制类型转换-明显 隐式强制类型转换-某些操作的副作用
var a = 42;
var b = a + "";
var c = String(a);
null;
undefined;
true;
9999;
1.07 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000;
{a: 1}
[1, 2, 3, 4];
JSON 字符串化
JSON.stringify(42);
JSON.stringify("42");
JSON.stringify(null);
JSON.stringify(true);
JSON.stringify(undefined);
JSON.stringify(function() {});
JSON.stringify([1, undefined, function() {}, null, true]);
JSON.stringify({ a: 2, b: function() {}, c: undefined, d: null, e: true });
var o = {};
var a = {
b: 42,
c: o,
d: function() {}
};
o.e = a;
JSON.stringify(a);
a.toJSON = function() {
return { b: this.b };
};
// JSON.stringify(..)可以传递一个可选参数 replacer,可以是数组和函数
//指定对象序列化过程中哪些属性应该被处理,哪些应该被排除
var a = {
b: 42,
c: "42",
d: [1, 2, 3],
e: {
f: 1
}
};
JSON.stringify(a, ["b", "c"]);
JSON.stringify(a, function(k, v) {
if (k !== "c") return v;
});
// JSON.stringify(..)还有可以传递一个可选参数 space,指定缩进格式
var a = {
b: 42,
c: "42",
d: [1, 2, 3]
};
JSON.stringify(a, null, 3);
JSON.stringify(a, null, "--------");
(1)字符串、数字、布尔值和null的JSON.stringify(..)规则与Tostring基本相同 (2)如果传递给JSON.stringify(..)的对象中定义了toJSON()方法,那么该方法会在字符串化之前调用,以便将对象转换为安全的JSON值
true
false
undefined
null
//字符串基本遵循数字常量相关规则
//处理失败转为NaN
对象 => 基本类型 => 非数字强制转化为数字
valueOf()
toString()
var a = {
valueOf:function(){
return '42'
}
}
var b ={
toString:function(){
return "40"
}
}
-------
""
[]
['123']
['123','456']
[123]
[123,456]
['abc','def']
var c= [4,2]
c.toString=function(){
return "222"
}
1、可以被强制类型转换为 false 的值 2、其他(被强制类型转换为 true 的值)
//假值
undefined
null
false
+0、-0 和 NaN
""
//假值对象
document.all
//真值
"false"
"0"
"''"
[]
{}
function(){}
...
String
Number
toString (涉及隐式转化:42 -> 封装对象 -> toString)
一元运算符+\-
var a = 42;
var b = String(a);
var c = "3.14";
var d = Number(c);
var a = 42;
var b = a.toString();
var c = "3.14";
var d = +c;
1、日期显式转换为数字
var d = new Date()
+d
// var time = new Date('2019-12-12').getTime()
// var time = Date.now()
2、~运算符(字位反转)
~x 相当于 -(x+1)
只使用于32位整数
// 在-(x+1)中唯一能够得到0(或者严格说是-0)的值是-1
indexOf
var a="hello word"
if(a.indexOf('lo') >=0 ){
}
if(a.indexOf('lo') !=-1 ){
}
if(~a.indexOf('lo')){
}
3、~~字位截除
parseInt针对的是字符串值,非字符参数首先会被强制转换为字符串(隐式)
var a="42";
var b="42px"
Number(a) //42
parseInt(a)//42
Number(b)//NaN
parseInt(b)//42
区别:
!!!坑 1、向 parseInt(...)中传递数字以及其他类型的参数,避免; 2、es5 之前,如果第一个字符是 x 或者 X=>十六进制;如果是 0 转为八进制; 3、parseInt(1/0,19)
parseInt(0.000008);
parseInt(0.0000008);
parseInt(false, 16);
parseInt(parseInt, 16);
parseInt("0x10");
parseInt("103", 2);
Boolean() ! !! if(!!...){...} !!.. ? .. : ..
var a = "0";
var b = [];
var c = {};
var d = "";
var e = 0;
var f = null;
var g;
+
var a = "42";
var b = "0";
var c = 42;
var d = 0;
a + b;
c + d;
var a = [1, 2];
var b = [3, 4];
a + b;
简单来说:如果+的其中一个操作数是字符串,则执行字符串拼接,否则执行数字加法
a + "" 对比 String(a)
var a = {
valueOf:function(){
return 42
}
toString:function(){
return 4
}
}
a + ""
String(a)
- 都会被转换为数字
var a = "3.14";
var b = a - 0;
var a = [3];
var b = [1];
a - b;
+
function onlyOne() {
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
if (arguments[i]) {
sum += arguments[i];
}
}
return sum == 1;
}
var a = true;
var b = false;
onlyOne(b, a);
onlyOne(b, a, b, b, b);
onlyOne(b, b);
onlyOne(b, a, b, b, b, a);
if(...) for(.. ; ..; ..)第二个参数 while(..) 和 do..while(..) ? : || && 左边的操作数
注意:返回值
var a = 42;
var b = "abc";
var c = null;
a || b;
a && b;
c || b;
c && b;
|| 和 && 对第一个操作数执行条件判断,如果不是布尔值,就先进行 ToBoolean 强制类型转换,再执行条件判断
对于||来说,如果条件判断结果为 true,就返回第一个操作数,如果为 false 就返回第二个操作数的值
&&则相反,如果条件判断结果为 true 就返回第二个操作数,如果为 false 就返回第一个操作数的值
const a = b || "somthing";
a && b();
var s1 = Symbol("cool")
String(s1)
var s2 = Symbol("not cool")
s2 + ""
转数字 ×
转布尔值 ✔️
== 允许在相等比较中进行强制类型转换 === 不允许
==在比较两个相同类型的值,就仅比较它们是否相等
//特殊情况
NaN == NaN
+ 0 == -0;
==在比较两个不同类型的值时会发生隐式强制类型转化
var a = 42;
var b = "42";
a === b;
a == b;
(1)如果 Type(x)是数字,Type(y)是字符串,则返回 x == ToNumber(y)的结果 (2)如果 Type(x)是字符串,Type(y)是数字,则返回 ToNumber(x) == y 的结果
数字优先
var a = "42";
var b = true;
a == b;
var x = "42";
var y = false;
x == y;
(1)如果 Type(x)是布尔类型,则返回 ToNumber(x) == y 的结果 (2)如果 Type(y)是布尔类型,则返回 x == ToNumber(y)的结果
var a = null;
var b;
a == b;
a == null;
b == null;
a == false;//
b == false;
a == "";//
b == "";//
a == 0;//
b == 0;
(1)如果 x 为 null,y 为 undefined,则结果为 true (2)如果 x 为 undefined,y 为 null,则结果为 true 在==中 null 和 undefined 相等(它们也与其自身相等),除此之外其他值都不和它们两个相等
var a = 42;
var b = [42];
a == b;
(1)如果 Type(x)是字符串或者数字,Type(y)是对象,则返回 x == ToPrimitive(y)的结果; (2)如果 Type(x)是对象,Type(y)是字符串或者数字,则返回 ToPrimitive(x) == y 的结果。
var a = "abc";
var b = Object(a);
a === b;
a == b;
var a = null;
var b = Object(a);
a == b;
var c;
var d = Object(c);
c == d;
var e = NaN;
var f = Object(e);
e == f;
1、 "0" == null
2、 "0" == undefined
3、 "0" == false
4、 "0" == NaN
5、 "0" == 0
6、 "0" == ""
7、 false == null
8、 false == undefined
9、 false == NaN
10、 false == 0
11、 false == ""
12、 false == []
13、 false == {}
14、 "" == null
15、 "" == undefined
16、 "" == NaN
17、 "" == 0
18、 "" == []
19、 "" == {}
20、 0 == null
21、 0 == undefined
22、 0 == NaN
23、 0 == []
24、 0 == {}
[] == ![]
2 == [2]
"" == [null]
·如果两边的值中有 true 或者 false,千万不要使用== ·如果两边的值中有[]、""、0,尽量不要使用==
比较双方首先调用 ToPrimitive,如果结果出现非字符串,就根据 ToNumber 规则将双方强制类型转换为数字来比较
var a = [42];
var b = ["43"];
a < b;
b < a;
var a = ["42"];
var b = ["043"];
a < b;
var a = [4, 2];
var b = [0, 4, 3];
a < b;
var a = { b: 42 };
var a = { b: 43 };
a < b;
a == b;
a > b;
a <= b;
a >= b;
a<=b ----> !(b<a)