解析允许字符串中含有非数字字符,解析按从左到右的顺序,如果遇到非数字字符就停止。而转换不允许出现非数字字符,否则会失败并返回NaN。

JSON字符串化:

工具函数JSON.stringify(..)在将JSON对象序列化为字符串时也用到了ToString
对于大多数简单值来说,JSON字符串和toString()的效果基本相同,只不过序列化的结果总是字符串:

  1. JSON.stringify( 42 ); // "42”
  2. JSON.stringify( "42" ); // ""42"" (含有双引号的字符串)
  3. JSON.stringify( null ); // "null”
  4. JSON.stringify( true ); // "true"

JSON.stringify(..)在对象中遇到undefinedfunctionsymbol时会自动将其忽略,在数组中则会返回null(以保证单元位置不变)

  1. JSON.stringify(undefined); // undefined
  2. JSON.stringify(function () { }); // undefined
  3. JSON.stringify( [1, undefined, function () { }, 4] ); // "[1,null,null,4]”
  4. JSON.stringify( { a: 2, b: function () { } } ); // "{"a":2}"

我们可以向JSON.stringify(..)传递一个可选参数replacer,它可以是数组或者函数,用来指定对象序列化过程中哪些属性应该被处理,哪些应该被排除。
如果replacer是一个数组,那么它必须是一个字符串数组,其中包含序列化要处理的对象的属性名称,除此之外其他的属性则被忽略。
如果replacer是一个函数,它会对对象本身调用一次,然后对对象中的每个属性各调用一次,每次传递两个参数,键和值。如果要忽略某个键就返回undefined,否则返回指定的值。

  1. var a = { b: 42, c: "42", d: [1, 2, 3] };
  2. JSON.stringify(a, ["b", "c"]); // "{"b":42,"c":"42"}”
  3. JSON.stringify(a, function (k, v) {
  4. if (k !== "c") return v;
  5. }); // "{"b":42,"d":[1,2,3]}"

JSON.string还有一个可选参数space,用来指定输出的缩进格式。space为正整数时是指定每一级缩进的字符数,它还可以是字符串,此时最前面的十个字符被用于每一级的缩进:

  1. var a = { b: 42, c: "42", d: [1, 2, 3] };
  2. JSON.stringify(a, null, 3);
  3. // “{
  4. // "b": 42,
  5. // "c": "42”,
  6. // "d": [
  7. // 1,
  8. // 2,
  9. // 3
  10. // ]
  11. // }" JSON.stringify( a, null, "-----" );
  12. // “{
  13. // -----"b": 42,
  14. // -----"c": "42”,
  15. // -----"d": [
  16. // ----------1,
  17. // ----------2,
  18. // —————3
  19. // ——]
  20. // }"

奇特的~运算符

  1. var a = "Hello World”;
  2. ~a.indexOf("lo"); // -4 <-- 真值!
  3. if (~a.indexOf("lo")) { // true // 找到匹配! }
  4. ~a.indexOf("ol"); // 0 <-- 假值!
  5. !~a.indexOf("ol"); // true
  6. if (!~a.indexOf("ol")) { // true // 没有找到匹配! }

||和&&

&&和||运算符的返回值并不一定是布尔类型,而是两个操作数其中一个的值。

  1. var a = 42;
  2. var b = "abc";
  3. var c = null;
  4. a || b; // 42
  5. a && b; // "abc"
  6. c || b; // "abc"
  7. c && b; // null
  1. function foo(a, b) {
  2. a = a || "hello”;
  3. b = b || "world”;
  4. console.log(a + " " + b);
  5. }
  6. foo(); // "hello world”
  7. foo("yeah", "yeah!"); // "yeah yeah!"

字符串和数字之间的相等比较

  1. var a = 42;
  2. var b = "42";
  3. a === b; // false
  4. a == b; // true

ES5规范这样定义:

  1. 如果Type(x) 是数字,Type(y) 是字符串,则返回x == ToNumber(y)的结果。
  2. 如果Type(x) 是字符串,Type(y) 是数字,则返回ToNumber(x) == y 的结果。

其他类型和布尔类型之间的相等比较

  1. var a = "42";
  2. var b = true;
  3. a == b; // false
  1. 如果Type(x) 是布尔类型,则返回ToNumber(x) == y 的结果;
  2. 如果Type(y) 是布尔类型,则返回x == ToNumber(y) 的结果。
    所以建议,无论什么情况下都不要使用true和false。请注意,这里说的只是==,=true和=false不允许强制类型转换,所以并不涉及ToNumber。

null和undefined之间的相等比较

null和undefined之间的==也涉及隐式强制类型转换:

  1. 如果x 为null,y 为undefined,则结果为true。
  2. 如果x 为undefined,y 为null,则结果为true。
    在中null和undefined相等(它们也与其自身相等),除此之外其他值都不存在这种情况。
    也就是说在中null和undefined是一回事,可以相互进行隐式强制类型转换:
  1. var a = null;
  2. var b;
  3. a == b;
  4. // true a == null;
  5. // true b == null;
  6. // true a == false;
  7. // false b == false;
  8. // false a == "";
  9. // false b == "";
  10. // false a == 0;
  11. // false b == 0;
  12. // false

对象和非对象之间的相等比较

ES5规定:

  1. 如果Type(x) 是字符串或数字,Type(y) 是对象,则返回x == ToPrimitive(y) 的结果;
  2. 如果Type(x) 是对象,Type(y) 是字符串或数字,则返回ToPrimitive(x) == y 的结果。