强制类型转换
基本概念
类型转换发生在静态类型语言的编译阶段;
强制类型转换则发生在动态类型语言的运行时(runtime)
JSON
JSON.stringify 用来把 JSON 文件字符串化,调用方法 tostring
字符串化的结果永远是字符串,所以会出现下面的双双引号结果
JSON.stringify(42); // 42
JSON.stringify("42"); // ""42""
JSON.stringify 在对象中遇到 undefined、function 和 symbol 时会自动将其忽略,在数组中则会返回 null
toJSON()指的是:“返回一个能够被字符串化的安全的 JSON 值”,而不是“返回一个 JSON 字符串”
可以向 JSON.stringify 传递一个 replacer 参数,表示仅转换每个属性;
比如下方代码表示仅转换对象 a 中的属性 b,所以 c 没有字符串化
var a = {
b: 42,
c: "42",
};
JSON.stringify(a, ["b"]); // "{"b":42}"
JSON.stringify 有第三个参数 space,表示指定输出的缩进格式
JSON.stringify(a,null,3)
boolean
对于所有真值为 true,而所有假值为 false
所有字符串都是真值,除了空字符串是假值外
显式强转为布尔类型最常用的是两个感叹号!!
var a = "";
!!a; // false
强转归纳
对于显式强转,比如下方字符串转数值,以及数值转字符串
这里不适用 new,并不创建封装对象
var num1 = 100;
var num2 = String(num1);
var str1 = "1.11";
var str2 = Number(str1);
单个加号运算符当做一元运算符,也是显式强转运算,可以把字符串类型数据转换成数值类型
var a = +"100"
js 中的构造函数没有参数时可以不用带()
如var time = new Data().geTime();
其他知识点
~x
等同于 -(x+1)
~42 = -(42+1) = -43
抽象渗漏:指代码中暴露了底层的实现细节
很多程序员喜欢用~~
代替 Math.floor(..)
进行向下取整;
而事实上~~仅适用于 32 位数字
~~-49.6 == -49
被诟病的==
==
负责执行隐式强转
当使用&&或者||连接两个包含==
的比较式时,二者是先后执行而非同时执行的!
如下会先判断 a==10
之后才判断 a==11
if(a==10 && a==11){}
千万不要使用==进行假值相等比较,会出现你意想不到的情况
下面例举了四种"假阳"的情况
"0" == false; // true
false == 0; // true
false == ""; // true
"" == 0; // true
42 == "42"; // true
"foo" == ["foo"]; // true
安全使用隐式强转法则
如果两边的值中有 true 或者 false,千万不要使用==
如果两边的值中有[]、""或者 0,尽量不要使用==
因为 typeof 总是返回七种基本类型之一,故在 typeof 管理下的==强转是被允许的
typeof x == "function"
一般的,我们为了更安全,抛弃==
改而使用===
抽象关系比较
抽象关系比较即针对诸如x<y
这种格式的代码中隐式强转规则
若双方中有一个是非字符串,则均转成数字后执行数字大小比较
若双方均为字符串,则按照字母顺序比较
var n1 = [42];
var n2 = ["43"];
a < b; // true
var n3 = ["42"];
var n4 = ["042"];
a < b; // false
语法
表达式变动
事实上,ES5 规定变量声明实际上是有返回值的,只不过被算法屏蔽掉了,返回结果为空
目前可以使用两种方式将获得语句的结果值赋值给另一个变量
直接 eval 填入代码,或者塞入 ES7 新增的 do 代码块
var a, b;
a = eval("if(true){b=100;}");
a = do {
if (true) {
b = 100;
}
};
标签语句:可以使用 goto 回到该标签的位置继续执行代码
function foo() {
bar: {
console.log("hello");
break bar;
}
console.log("word");
}
foo(); // hello world