前端 判断 数据类型
# 数据类型
- 基本数据类型:String、Number、Boolean、Symbol、Undefined、Null、BigInt。
- 引用数据类型:object、Array、Function、Date 等等
# 判断方法
- typeof
- instanceof
- Object.prototype.toString()
- constructor
# typeof
- 对于基本类型,除 null 以外,均可以返回正确的结果:包括 number、boolean、symbol、string、undefined、BigInt。
- 对于引用类型,除 function 返回 function 类型以外,对 Array、Function、Date 等等均返回 object 类型。
- 对于 null ,返回 object 类型。
typeof
是操作符而不是函数,用来检测变量的类型- typeof 的判断原理:js 中数据类型在底层上是用二进制表示的,前三位(低位)代表数据类型
000:对象(因为null的二进制全是0,所以也被typeof判断为Object类型)
110:布尔
100:字符串
010:浮点数
1:整数
let num = 18;
let str = "yhd";
let show = true;
let sym = Symbol();
let data = undefined;
let info = null;
console.log(typeof num); // number
console.log(typeof str); // string
console.log(typeof show); // boolean
console.log(typeof sym); // symbol
console.log(typeof data); // undefined
console.log(typeof info); // object
let fun = function add() {};
let arr = ["yhd", "gsr"];
let obj = {name: "yhd", age: "23"};
let date = new Date();
console.log(typeof fun); // function
console.log(typeof arr); // object
console.log(typeof obj); // object
console.log(typeof date); // object
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
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
# instance
- instanceof 可以正确判断对象的数据类型,用来判断 A 是否为 B 的实例,表达式为: A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。因为内部机制是通过判断 A 对象的原型链中是不是能找到 B 构造函数的prototype。
- 示例
let fun = function add() {};
let arr = ["yhd", "gsr"];
let obj = {name: "yhd", age: "23"};
let date = new Date();
console.log(fun instanceof Function); // true
console.log(arr instanceof Array); // true
console.log(obj instanceof Object); // true
console.log(date instanceof Date); // true
console.log(arr instanceof Object) // true
console.log(fun instanceof Object); // true
console.log(date instanceof Object); // true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
- 手写 instance
function instance(A,B) {
if(typeof leftVaule !== 'object' || leftVaule === null) return false;
A = A.__proto__;
B = B.prototype;
while(true){
if(A===NULL) return false; // 找到头了还没找到
if(A===B) return true; //
A=A.__proto__; // 没找到就沿着A的原型链继续找
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
- instanceof 能够判断出 arr 是 Array 的实例,但他也认为 arr 也是 Object 的实例,为什么呢? 原因:从 instanceof 中能够判断出 arr.**proto ** 指向 Array.prototype,而 Array.prototype.**proto ** 又指向了 Object.prototype,最终 Object.prototype.**proto ** 指向了 null,标志着原型链的结束。因此,arr、Array、Object 就在内部形成了一条原型链。 在原型链上,arr 的 **proto ** 直接指向 Array.prototype,间接指向 Object.prototype。function、date 同理。
- instanceof 只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪种类型。
- 弊端:由于 instanceof 只能用来判断对象,所以下面的情况是不能判断的:
var a = new Number(1);
a instanceof Number // true,
1 instanceof Number // false,无法判断基本类型
const fakeArr = { __proto__: Array.prototype, length: 0 };
fakeArr instanceof Array; // true
let a = 'aa';
a instanceof String; // false
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# constructor
- 当一个函数被定义时,JS 引擎会为函数添加 prototype 原型,然后再在 prototype 上添加一个 constructor 属性,并让其指向他的构造函数
let num = 18;
let str = "yhd";
let show = true;
let sym = Symbol();
let data = undefined;
let info = null;
console.log(num.constructor); // ƒ Number() { [native code] }
console.log(str.constructor); // ƒ String() { [native code] }
console.log(show.constructor); // ƒ Boolean() { [native code] }
console.log(sym.constructor); // ƒ Symbol() { [native code] }
console.log(data.constructor); // Cannot read property 'constructor' of undefined
console.log(info.constructor); // Cannot read property 'constructor' of null
let fun = function add() {};
let arr = ["yhd", "gsr"];
let obj = {name: "yhd", age: "23"};
let date = new Date();
console.log(fun.constructor); // ƒ Function() { [native code] }
console.log(arr.constructor); // ƒ Array() { [native code] }
console.log(obj.constructor); // ƒ Object() { [native code] }
console.log(date.constructor); // ƒ Date() { [native code] }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。
- 函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object
# toString
- toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object xxx] ,其中 xxx 就是对象的类型。
- 对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。
Object.prototype.toString.call(1); // [object Number]
Object.prototype.toString.call(''); // [object String]
Object.prototype.toString.call(true); // [object Boolean]
Object.prototype.toString.call(Symbol()); //[object Symbol]
Object.prototype.toString.call(undefined); // [object Undefined]
Object.prototype.toString.call(null); // [object Null]
Object.prototype.toString(Object); // [object Object]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(NaN) ; // [object Number]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- 什么类型都可以精准判断
# ES6 中的判断方法
- 判断数组:Array.isArray()
最近更新时间: 2021/08/25 17:25:09
- 01
- 2023/07/03 00:00:00
- 02
- 2023/04/22 00:00:00
- 03
- 2023/02/16 00:00:00