关于前端:JavaScript-这些数据类型检测你确定会了吗

42次阅读

共计 3637 个字符,预计需要花费 10 分钟才能阅读完成。

0 / JS 中创立值的两种形式

JS 中创立一个值有两种计划:① 字面量形式 ② 构造函数形式

留神:构造函数形式

① 不能 new Symbol/new BigInt

② 能够 Object(symbol)/Object(bigint) 其余数据类型值也能够,然而排除null/undefined

//=> 字面量形式
let n = 100;
let obj = {};

//=> 构造函数形式
let m = new Number(100);
let obj2 = new Object();

△ 创立值的两种形式

对于根本数据类型,两种创立形式后果是不一样的:

① 字面量形式失去的是根本数据类型,即:非凡的实例

② 而构造函数形式失去的是对象数据类型,即:正规的实例

对于援用数据类型,两种创立形式后果:除了语法上的区别,实质上是没有区别的,获取的都是对应类的实例对象

1 / JS 中数据类型检测

JS 中数据类型检测:

typeof value; 简略不便

Object.prototype.toString.call(value) 万全之策

prop instanceof constructor 长期当“壮丁”

constructor 长期当“壮丁”

2 / typeof

△ 图 1_typeof 判断数据类型

typeof 检测数据类型:

1、能够无效的检测出大部分的数据类型

2、typeof null检测的后果是object

JS 设计的如此:数据值都是依照二进制存储的

1 整数,010 浮点数,100 字符串,110 布尔,000 对象,-2^30undefined,000000null…………

即:typeof 检测数据类型时,依照二进制存储的值检测的,把 null 认为是对象了

3、typeof 不会细分具体的对象数据类型值,所有的对象数据类型值,检测进去都是"object"

4、typeof 检测基于构造函数创立进去的,根本数据类型的实例对象,后果也是"object"

△ 图 2_基于构造函数创立进去的根本数据类型的实例对象

3 / Object.prototype.toString.call()

Object.prototype.toString.call() 检测每个对象的类型

1、大部分内置类的原型上都有 toString 办法,但个别都是转为字符串,只有 Object.prototype 上的 toString 办法应用来返回以后实例对象所属的信息

"[object 所属的构造函数信息]"

2、所属的构造函数信息:是依据 Symbol.toStringTag 来获取的,【有,是依据它;没有,是浏览器本人计算的】

var toString = Object.prototype.toString;

toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]

△ Object.prototype.toString

var class2type = {};
var toString = class2type.toString;

toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]

△ ({}).toString

function* fn() {}
console.log(Object.prototype.toString.call(fn)); //->"[object GeneratorFunction]" 

△ 结构器函数

function Fn() {}
Fn.prototype[Symbol.toStringTag] = 'Miao~';
let f = new Fn;
console.log(Object.prototype.toString.call(f)); //=>"[object Miao~]"

△ 自定义类,指定 toStringTag 的值

4 / instanceof

instanceof 运算符检测构造函数的 prototype 属性是否呈现在某个实例对象的原型链上

∴ 基于 instanceof 能够细分不同类型的对象,也能够检测基于构造函数形式创立的根本数据类型对象的值

然而,长期拉来当“壮丁”,有一些注意事项:

1、检测原理:构造函数[Symbol.hasInstance](实例)

2、检测原理:检测以后构造函数的原型 prototype 是否呈现在以后实例所处的原型链上 \__proto__,即:只有能呈现后果就为 true

3、在 JS 中原型链是能够手动改的,检测后果不精确

4、所有的实例的原型链最初都指向了 Object.prototype,即: 实例 instanceof Object后果都会为 true

5、字面量形式创立的根本数据类型值是无奈基于 instanceof 检测的(浏览器不会把它转为 new 的形式),即:字面量创立的根本数据类型值不是对象,不存在 \__proto__这个货色

6、…………

var n = 100;
var m = new Number(1000);
console.log(n instanceof Number); //=> false
console.log(m instanceof Number); //=> true
console.log(m instanceof Object); //=> true

var arr = [1,2,3];
var obj = {name:'晚霞的光影笔记', id:'zhaoxiajingjing'};
console.log(arr instanceof Array); //=> true
console.log(obj instanceof Object); //=> true
console.log(arr instanceof Object); //=> true

△ 字面量和构造函数创立值

class Fn {static[Symbol.hasInstance](){console.log('miao~');
        return false;
    }
}
let f = new Fn;
console.log(f instanceof Fn);
//=> 输入后果:// miao~
// false

△ 调用:构造函数的 Symbol.hasInstance

function Fn(){}
Fn.prototype = Array.prototype;
let f = new Fn;
console.log(f instanceof Array); //=> true

△ 手动批改原型指向

5 / constructor

constructor结构器,被拉来检测数据类型,也是长期抓来的“壮丁”

它的问题:能够手动被批改掉

var n = 100;
var m = new Number(1000);
console.log(n.constructor === Number); //=> true
console.log(m.constructor === Number); //=> true

var arr = [1,2,3];
var obj = {name:'晚霞的光影笔记', id:'zhaoxiajingjing'};
console.log(arr.constructor=== Array); //=> true
console.log(obj.constructor === Object); //=> true
console.log(arr.constructor === Object); //=> false

△ 通过 constructor 检测

function Fn(){}
Fn.prototype = {constructor:Array};
let f = new Fn;
console.log(f.constructor === Fn); //=> false
console.log(f.constructor === Array); //=> true

△ 能够手动批改 constructor 指向

6 / 小结

JS 中检测数据类型的形式 4 种:

1、typeof,无奈辨别对象数据类型值

2、Object.prototype.toString,万全之策,次要检测 Symbol.toStringTag 的值,没有就按浏览器计算的

3、instanceof,“壮丁”

① 检测原理:构造函数[Symbol.hasInstance]()

② 检测构造函数的 prototype 原型是否呈现在实例对象的原型链上

=> JS 的原型链是能够手动批改指向的

=> JS 的原型也是能够手动批改的

③ 不能检测字面量创立的根本类型值

4、constructor,“壮丁”能够进行手动批改指向

– end-

正文完
 0