JS判断类型及强制类型转换

判断整数

es6的Number.isInteger:

Number.isInteger(4);        //true
Number.isInteger(4.00);     //true
Number.isInteger(4.1);     //fasle

或者时polyfill:

function isInteger(num){
    return typeof num === 'number' && num%1 === 0;
}

判断NaN

window.isNaN();

es6的 Number.isNaN();

function isNaN = function(value) {
    var n = parseInt(value);
    return n !== n;
};

判断-0

由于以下均返回true:

-0 === 0;
(-0).toString() === (0).toString() === '0';

因此可用下面方法:

function isNegZero(n){
    n = Number(n);
    return (n === 0) && (-1/n === -Infinity);
}

判断绝对相等可用 es6的Object.is() 方法:

var a = 3/'f';     //a为NaN
var b = -2*0;      //b为-0
Object.is(a, NaN);  //true
Object.is(b, -0);   //true
Object.id(b, 0);   //false

Object.is的简单polyfill:

Object.is = function(a, b){
    if(a === b && b === 0){
        return 1/a === 1/b
    }
    if(a !== a){
        return b !== b;
    }
    return a === b;
}

判断参数中只有1个真值

function onlyOneTrue(){
    var sum = 0;
    Array.from(arguments).forEach(function(val){
        if(Number(!!val) === 1){
            sum++;
        }
    });
    return sum === 1;
}

返回值

  1. 通过var定义变量表达式返回值为undefined
  2. 不允许将语句的结果赋值给变量
a = if(true){}
VM863:1 Uncaught SyntaxError: Unexpected token if

可以用eval:

a = eval('if(true){b=3}') //3

ES7有项提议:do表达式

var a,b;
a = do {
    if(true){
        b = 4;
    }
};
a;  //4

JSON.stringify()

若对非法JSON值对象(循环引用)序列化时,需要定义toJSON方法。

var o = {
    a:1,
    b:this.a,
    toJSON:function(){return this.a}
};
JSON.stringify(o);//"1"

JSON.stringify在遇到不安全的JSON值如undefined,function,symbol,循环引用时会自动忽略,但是在数组中会将其返回null,以保证单元位置不变

var o = {
    a:undefined,
    b:function(){},
    c:Symbol('hello'),
    d:1,
    e:[undefined,function(){}]
}


JSON.stringify(o);
//"{"d":1,"e":[null,null]}"

parseInt

parseInt(1/0,19);//18

上面输出18因为将”“”Infinite”第1个字母”I”用19进制表示是18,而第二个字母不是有效数字。所以返回18:

>
- 0 0
- 1 1
- 2 2
- 3 3
- 4 4
- 5 5
- 6 6
- 7 7
- 8 8
- 9 9
- a 10
- b 11
- c 12
- d 13
- e 14
- f 15
- g 16
- h 17
- i 18

parseInt(0.000008);//0

parseInt(0.0000008);//8,8e-7

parseInt(false,16);//250,'fa' 15*16+10=250

parseInt(parseInt,16);//15,'function'的第一个字母

parseInt('0x10');//16,0x开头,16进制

parseInt('103',2);//只取10,转为2进制

parseInt第一个字符会默认转为string型。

将对象转换为其对应的基本类型值

首先检查其内部是否有valueOf()方法,如果有且返回基本类型值是调用他,否则调用toString()方法。

'14' == true; //false
'14' == false; //false

以上因为是将true和false转换为数值了,因此,并没有发生Boolean类型的比较。

var a = '1';
var b = [1];
a == b;  //true
[null] == ''; //true

以上因此调用toString()将[1]转换为其基本类型值1

var a = 'abc';
var b = Object(a);
a == b; //true;

以上同理将Object类型的a转换为基本类型’abc’。
但是下面将不同:

var a1 = null;
var a2 = undefined;
var a3 = NaN;
var b1 = Object(a1);  //相当于Object();
var b2 = Object(a2);  //相当于Object();
var b3 = Object(a3);  //相当于new Number(NaN);

a1 == b1;  //false
a2 == b2;  //false
a3 == b3;  //false

真假转换

三元运算符:var b = a ? true : false;会默认将a强转为Boolean型。

Boolean判断中只有以下返回false:
- ” , Boolean(”);//false;
- 0
- null
- undefined
- NaN

([]) ? true : false;//true
Boolean([]);//true
[]==false;//true,因为将false转为0,Number([])===0

当用==和Boolean类型的值比较时,会将Boolean值转为number再比较。

false == 0;   //true
false == '';   //true
false == [];   //true

'' == 0;   //true
'' == [];   //true
0 == [];   //true

字符串和数字转换

非字符和字符用+运算符,则一次调用他的valueOf()和toString()直到转为简单基本类型值。

var a = [1,2];
var b = [3,4];
a + b;//'1,23,4' 

思考:如何使得下列情况发生:
1. new Number(2) == 3;

Number.prototype.valueOf = function(){
    return 3;
}
new Number(2) == 3; //true

2.if(a == 2 && a == 3){console.log('yes')}

var i = 2;
Number.prototype.valueOf = function(){
    return i++;
}
var a = new Number(45);
if(a == 2 && a == 3 && a == 4 && a == 5){
    console.log('yes')
}

抽象关系比较

对象转原始类型后,若都为字符串则比较字符串字母顺序,若有字符串和数字,则将字符串转为parseInt数字

var a = [12];
var b = ['13b'];
a>b;//false;
a//true,'12'<'13b'


var a = [1,2];
var b = [0,1,2];
a>b;//true;'1,2'>'0,1,2'

然而

12<'13b';//false;这里比较的是12
12>NaN;//false
12<NaN;//false

下面比较对象

var a={h:1};
var b={h,2};
a == b;//false,这里用JSON.stringify
a//false,这里用Object.toString,返回"[object Object]"
a>b;//false,这里用Object.toString,返回"[object Object]"

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

a <= btrue,因为a <= b意思为a不大于b,所以是a>b的反面,即!(a>b);a>b为false,所以!(a>b)为true

var a = [42];
var b = '043';
a > b;//true;'42'>'043'
[] == [];//false
[] === [];//false
{} == {};//false
{} === {};//false

Number([]);//0,因为[].toString()====''
Number(({}));//NaN,({}).toString==='[Object object]';

因为[]是Array的实例,内部还是实例化了Array这个构造函数,由于不是单例模式,所以每个实例对象都不相等。

var n0 = 123;
var n1 = new Number(123);//返回对象实例
var n2 = new Number(123);//返回对象实例
var n3 = Number(123);//返回原始值123
var n4 = Number(123);//返回原始值123

n0 == n1;//true;对象强转为原始值
n0 == n3;//true;都是原始值
n0 === n1;//false;无类型转换
n0 === n3;///true;都是原始值

n1 == n2;//false,两个实例不相等
n1 === n2;//false
n1 == n3;//true;对象强转为原始值
n1 === n3;//false

n3 == n4;//true;
n3 === n4;//true

以上使用Number进行测试的,道理同样适用于String,但是不适用于Object。

null和undefined

null == undefined;//true

null == false;//false,false转为0
undefined == false;//false,false转为0

null == '';//false
undefined == '';//false

null == 0;//false
undefined == 0;//false

Number(null);//0
Number(undefined);//NaN

parseInt(null);//NaN
parseInt(undefined);//NaN
parseInt('');//NaN

只有null==undefined,他们和其他假值都不相等

你可能感兴趣的:(javascript)