-
Notifications
You must be signed in to change notification settings - Fork 0
/
objType.js
192 lines (177 loc) · 6.71 KB
/
objType.js
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
(function () {
var getProto = Object.getPrototypeOf
// javascript数据类型判断
var class2type = {}
var toString = class2type.toString
var hasOwn = class2type.hasOwnProperty
var fnToString = hasOwn.toString
var ObjectFunctionString = fnToString.call(Object)
// var toString = class2type.toString
"Boolean Number String Null Undefined Function Array Set Map Date RegExp Object Error Symbol"
.split(" ")
.forEach((name, index) => {
class2type["[object " + name + "]"] = name.toLowerCase()
})
function ObjType(obj) {
return class2type[toString.call(obj)] || typeof obj
}
var isFunction = function isFunction(obj) {
// Support: Chrome <=57, Firefox <=52
// In some browsers, typeof returns "function" for HTML <object> elements
// (i.e., `typeof document.createElement( "object" ) === "function"`).
// We don't want to classify *any* DOM node as a function.
return typeof obj === "function" && typeof obj.nodeType !== "number"
}
var isWindow = function isWindow(obj) {
return obj != null && obj === obj.window
}
// 原始类型
var isPrimitive = function (obj) {
return obj === null || ['string', 'number', 'boolean', 'undefined', 'symbol'].indexOf(typeof obj) !== -1
}
function toNumber(val) {
const n = parseFloat(val)
return isNaN(n) ? val : n
};
function isNum(val) {
return typeof val === 'number'
}
var isPlainObject = function (obj) {
var proto, Ctor
// Detect obvious negatives
// Use toString instead of jQuery.type to catch host objects
if (!obj || toString.call(obj) !== "[object Object]") {
return false
}
proto = getProto(obj)
// Objects with no prototype (e.g., `Object.create( null )`) are plain
if (!proto) {
return true
}
// Objects with prototype are plain iff they were constructed by a global Object function
Ctor = hasOwn.call(proto, "constructor") && proto.constructor
return (
typeof Ctor === "function" &&
fnToString.call(Ctor) === ObjectFunctionString
)
}
var isEmptyObject = function (obj) {
var name
for (name in obj) {
return false
}
return true
}
/**
* 有时你需要知道某些内容是否为空,并根据结果决定要使用的方法,
* 例如检查长度、大小或是否包含任何子元素。下面这个工具打包了这些功能,
* 你可以用它检查 String、Object、Array、Map 和 Set 的大小。
*/
function isEmpty(x) {
if (Array.isArray(x)
|| typeof x === 'string'
|| x instanceof String
) {
return x.length === 0
}
if (x instanceof Map || x instanceof Set) {
return x.size === 0
}
if (({}).toString.call(x) === '[object Object]') {
return Object.keys(x).length === 0
}
return false
}
function isArrayLike(obj) {
// Support: real iOS 8.2 only (not reproducible in simulator)
// `in` check used to prevent JIT error (gh-2145)
// hasOwn isn't used here due to false negatives
// regarding Nodelist length in IE
var length = !!obj && "length" in obj && obj.length,
type = ObjType(obj)
if (isFunction(obj) || isWindow(obj)) {
return false
}
return type === "array" || length === 0 ||
typeof length === "number" && length > 0 && (length - 1) in obj
}
// 判断两个对象是否相等,对象相等
// ES6新增的Object.is判断两个对象是否相等,但对于对象类型判断只看是否指向同一个对象
// https://www.jb51.net/article/110768.htm
function isObjEqual(a, b) {
//如果a和b本来就全等
if (a === b) {
//判断是否为0和-0
return a !== 0 || 1 / a === 1 / b
}
//判断是否为null和undefined
if (a == null || b == null) {
return a === b
}
//接下来判断a和b的数据类型
var classNameA = toString.call(a),
classNameB = toString.call(b)
//如果数据类型不相等,则返回false
if (classNameA !== classNameB) {
return false
}
//如果数据类型相等,再根据不同数据类型分别判断
switch (classNameA) {
case '[object RegExp]':
case '[object String]':
//进行字符串转换比较
return '' + a === '' + b
case '[object Number]':
//进行数字转换比较,判断是否为NaN
if (+a !== +a) {
return +b !== +b
}
//判断是否为0或-0
return +a === 0 ? 1 / +a === 1 / b : +a === +b
case '[object Date]':
case '[object Boolean]':
return +a === +b
}
//如果是对象类型
if (classNameA == '[object Object]') {
//获取a和b的属性长度
var propsA = Object.getOwnPropertyNames(a),
propsB = Object.getOwnPropertyNames(b)
if (propsA.length != propsB.length) {
return false
}
for (var i = 0; i < propsA.length; i++) {
var propName = propsA[i]
//如果对应属性对应值不相等,则返回false
if (a[propName] !== b[propName]) {
return false
}
}
return true
}
//如果是数组类型
if (classNameA == '[object Array]') {
if (a.toString() == b.toString()) {
return true
}
return false
}
}
// console.log(class2type)
console.log(ObjType({}))
console.log(ObjType([]))
console.log(ObjType(Symbol()))
console.log(ObjType(null))
console.log(ObjType(undefined))
console.log('String object or string, ', ObjType(String("Str")), ObjType(""))
console.log('Number object or number, ', ObjType(Number(222222)), ObjType(23))
console.log('Boolean object or boolean, ', ObjType(Boolean(false)), ObjType(true))
console.log(ObjType(() => { }))
console.log(ObjType(new RegExp()))
console.log(ObjType(new Error()))
console.log(ObjType(new Date()))
console.log('set map,', ObjType(new Set()), ObjType(new Map()))
console.log('isPlainObject', isPlainObject({ a: 1, b: 2 }))
console.log('isPlainObject', isPlainObject(new Date()))
console.log('isPrimitive', isPrimitive(1), isPrimitive(new Date()))
})()