javascript 的弱类型很简洁,而在开发的时候我们也需要时刻注意数据的类型。

本篇文章介绍 Ramda Type 方法。

Primitives

Javascript 有6种数据类型 null, undefined, number, string, boolean, object。(es6中增加了 symbol

1
'3' * '4' // 12

JavaScript 的内置转换机制只支持类型 BooleanNumberString,和Object。没有将一个构造函数的实例转换为另一个构造函数的实例的标准方法。

Javascript 在值之间做了区分

  • 原始值: boolean, number, string, nullundefined
  • 所有其他值是对象。

两者间的主要区别是如何比较,每个对象都有一个唯一的身份,仅(严格)等于自己。

1
2
3
4
5
6
{} == {} // false
var obj1 = {};
var obj2 = {};
obj === obj2 // false
var obj3 = obj1;
obj3 === obj1 // true

而原始值在编码相同值的情况下是相等的。

1
2
3
var p1 = 123;
var p2 = 123;
p1 === p2 // true
1
2
3
4
typeof 'abc' // 'string'
typeof new String('abc') // 'object'
'abc' instanceof String // false
'abc' === new String('abc') // false

可以看到原始值与构造实例有着根本的不同。

1
new String(1); // String {[[PrimitiveValue]]: "1"}

而这也就引入了原始值转换:

  • null, undefined 没有属性,所以无法再本身调用方法。
  • valueOf 会在number, string, booleanarray 上调用。
  • 而其他类型就会使用 toString

object 也存在 valueOf 但在强制类型转换时会调用 toString

Ramda Type

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function is(Ctor, val) {
// 首先对 null undefined 进行判断
return val != null && val.constructor === Ctor && val instanceof Ctor;
}
function isNil(val) {
// null undefined 的判断
return val == null;
}
function propIs(type, name, obj) {
return is(type, obj[name]);
}
function type(val) {
// 使用 toString 来转换为字符串
return Object.prototype.toString.call(val).slice(8, -1);
}

More Type

这里说一下其他数据的判断。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
* 判断整数
*
* @param {any} val
* @returns {boolean}
* @example
* myIsInteger(2) => true
* myIsInteger(2.01) => false
*/
function myIsInteger(val) {
// return Number.isInteger(val);
return (val << 0) === val;
}
/**
* 安全整数
*
* @param {any} val
* @returns {boolean}
* @example
* myIsSafeInteger(2) => true
* myIsSafeInteger(Number.MAX_SAFE_INTEGER + 1) => false
*/
function myIsSafeInteger(val) {
return (
typeof val === 'number' &&
Number.MIN_SAFE_INTEFER <= val &&
Number.MAX_SAFE_INTEFER >= val
);
}
/**
* NaN 判断
*
* @param {any} val
* @returns {boolean}
* @example
* myIsNaN(2) => false
* myIsNaN(NaN) => true
*/
function myIsNaN(val) {
return typeof val === 'number' && isNaN(val);
}
/**
* 0 -0 判断
* 在 javascript 中虽然存在 +0 -0 单他们是相等的,这里要区分他们需要时 Infinity
*
* @param {any} val
* @returns {boolean}
* @example
* myIsNegativeZero(1) => false
* myIsNegativeZero(0) => false
* myIsNegativeZero(-0) => true
*/
function myIsNegativeZero(val) {
return val === 0 && (1/val) < 0;
}

Object.is

Object.is() 判断两个值是否相同。如果下列任何一项成立,则两个值相同:

  • 两个值都是 undefined
  • 两个值都是 null
  • 两个值都是 true 或者都是 false
  • 两个值是由相同个数的字符按照相同的顺序组成的字符串
  • 两个值指向同一个对象
  • 两个值都是数字并且
  • 都是正零 +0
  • 都是负零 -0
  • 都是 NaN
  • 都是除零和 NaN 外的其它同一个数字
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Object.is('foo', 'foo'); // true
    Object.is(window, window); // true
    Object.is('foo', 'bar'); // false
    Object.is([], []); // false
    var test = { a: 1 };
    Object.is(test, test); // true
    Object.is(null, null); // true
    // 特例
    Object.is(0, -0); // false
    Object.is(-0, -0); // true
    Object.is(NaN, 0/0); // true

Type library

Reference