原文

You Don't Know JS: Types & Grammar

测试

console.log(1+ "2"+"2");
console.log(1+ +"2"+"2");
console.log("A"- "B"+"2");
console.log("A"- "B"+2);

122,32,NaN2,NaN

对象包装

  • String()

  • Number()

  • Boolean()

  • Array()

  • Object()

  • Function()

  • RegExp()

  • Date()

  • Error()

  • Symbol()

var a = new String( "abc" );

typeof a; // "object" ... not "String"

a instanceof String; // true

Object.prototype.toString.call( a ); // "[object String]"
console.log(a); // String {[[PrimitiveValue]]: "abc"}

基础数据类型没有属性和方法,为了使用方法和函数,就需要对应的对象包装它。JS可以自动做到这一点。

var a = "abc";

a.length; // 3
a.toUpperCase(); // "ABC"

注意,用构造器构造的对象,永远是“truthy”。

var a = new Boolean( false );

if (!a) {
    console.log( "Oops" ); // never runs
}

类型转换

ToString

默认调用toString()

[1,3,4]+"haha" // "1,3,4haha"
"haha" + {f:'da'} // "haha[object Object]"

{f:'da'}+"haha" // NaN
var f = {f:'da'}
f+"haha" // "[object Object]haha"

数组默认调用toString()

JSON字符串化,会忽略undefined,function,symbol,循环引用的对象还会报错。

JSON.stringify( 42 );    // "42"
JSON.stringify( "42" );    // ""42"" (a string with a quoted string value in it)
JSON.stringify( null );    // "null"
JSON.stringify( true );    // "true"

JSON.stringify( undefined );                    // undefined
JSON.stringify( function(){} );                    // undefined

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

JSON.stringify(obj, replacer, space)

ToNumber

true变成1,false变成0,undefined变成NaNnull变成0,""变成0,[]变成0

当进行数值计算时,数字型字符串变成数字,非数字型字符串变成NaN,对象先通过toSting()变成字符串,再参与计算。

[2]*2 // 4
[2,3]*2 // NaN
['2']*2 // 4
'A'*2 // NaN
null+2 // 2
''*2 // 0

ToBoolean

falsy values

  • undefined

  • null

  • false

  • +0,-0,NaN

  • ""

!!"" // false
!!"  " // true
""*1 // 0
"  "*1 // 0
var a = new Boolean( false );
var b = new Number( 0 );
var c = new String( "" );

var d = Boolean( a && b && c );

d; // true
var a = [];                // empty array -- truthy or falsy?
var b = {};                // empty object -- truthy or falsy?
var c = function(){};    // empty function -- truthy or falsy?

var d = Boolean( a && b && c );

d; // true

它们都是对象。

var a = "false";
var b = "0";
var c = "''";

var d = Boolean( a && b && c );

d; // true

它们都是非空字符串。

var a = "false";
var b = "0";
var c = "";

var d = Boolean( a && b && c );

d; // false

Date To Number

var d = new Date( "Mon, 18 Aug 2014 08:53:06 CDT" );

+d; // 1408369986000

// or
var timestamp = +new Date();
var timestamp = new Date().getTime();
var timestamp = Date.now();
new Date().getDate() // 10
Date.now().getDay() // TypeError

Parsing Numeric Strings

var a = "42";
var b = "42px";

Number( a );    // 42
parseInt( a );    // 42

Number( b );    // NaN
parseInt( b );    // 42
parseInt("px42px"); // NaN

当传入的非字符串先转化为字符串,调用toString()

parseInt([14,2,3]) // 14
parseInt( new String( "42") ); // 42
var a = {
    num: 21,
    toString: function() { return String( this.num * 2 ); }
};

parseInt( a ); // 42

隐式转换

var a = {
    valueOf: function() { return 42; },
    toString: function() { return 4; }
};

a + "";            // "42"

String( a );    // "4"

[] + {} // "[object Object]"
{} + [] // 0

=====

==

In the ES5 spec, clauses 11.9.3.4-5 say:

If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
If x is null and y is undefined, return true.
If x is undefined and y is null, return true.
If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.

"0" == null;            // false
"0" == undefined;        // false
"0" == false;            // true -- UH OH!
"0" == NaN;                // false
"0" == 0;                // true
"0" == "";                // false

false == null;            // false
false == undefined;        // false
false == NaN;            // false
false == 0;                // true -- UH OH!
false == "";            // true -- UH OH!
false == [];            // true -- UH OH!
false == {};            // false

"" == null;                // false
"" == undefined;        // false
"" == NaN;                // false
"" == 0;                // true -- UH OH!
"" == [];                // true -- UH OH!
"" == {};                // false

0 == null;                // false
0 == undefined;            // false
0 == NaN;                // false
0 == [];                // true -- UH OH!
0 == {};                // false

疯狂的例子

[] == ![];        // true
2 == [2];        // true
"" == [null];    // true
0 == "\n";        // true

clipboard.png

来源:https://github.com/dorey/JavaScript-Equality-Table

比较

var a = [ 42 ];
var b = [ "43" ];

a < b;    // true
b < a;    // false
var a = [ "42" ];
var b = [ "043" ];

a < b;    // false
var a = [ 4, 2 ];
var b = [ 0, 4, 3 ];

a < b;    // false
var a = { b: 42 };
var b = { b: 43 };

a < b;    // false
a == b;    // false
a > b;    // false

a <= b;    // true
a >= b;    // true

Since b < a is also false, the result of a <= b is true.

var a = [ 42 ];
var b = "043";

a < b;                        // false -- string comparison!
Number( a ) < Number( b );    // true -- number comparison!

有必要改天重新整理下


nbb3210
436 声望31 粉丝

优雅地使用JavaScript解决问题