一. js数据类型
- String
- Number
- Boolean
- null
- Undefined
- Object(包含js派生类:Array, Function, Set, Map, Date, RegExp, WeakMap, WeakSet)
- Symbol
- BigInt(ES2020, 用来示意大于 js中最大整数2^53 - 1 的整数)
分为根本类型(除Obejct类型外的类型)和援用类型(复合类型,Object类型)
- 根本数据类型:值类型, 变量存储在栈内存中
- 援用数据类型:变量存储在堆内存和栈内存中,栈内存中存储变量的标识符和指向堆内存中该对象的指针即堆内存中该对象的地址),援用类型的值是按援用拜访的
undefined与null区别以及应用场景
null 指代空对象指针应用场景:(1)开释内存(2)空值判断undefined 示意此处应该有一个值,然而还没有定义应用场景:(1)变量被申明了,但没有赋值时,就等于undefined。(2)调用函数时,应该提供的参数没有提供,该参数等于undefined。(3)对象没有赋值的属性,该属性的值为undefined。(4)函数没有返回值时或者return前面什么也没有,返回undefined初始化变量时可依据心愿寄存类型指定let a = null; // 寄存对象let b = undefined; //寄存数值
symbol类型
symbol用于模仿公有办法或属性, 任意一个symbol数据是一个举世无双的值symbol属性名以及对象各类属性的属性名遍历:let obj = Object.create({}, { getFoo: { value: function() { return this.a; }, enumerable: false, }})obj.a = 1,obj.b = function() {},obj[Symbol('a')] = 2,Object.getOwnPropertySymbols(obj); //[Symbol(a)] 遍历本身symbol类型属性Object.getOwnPropertyNames(obj); //['a', 'b', 'getFoo'] 遍历本身非symbol类型属性(包含不可枚举属性)Reflect.ownKeys(obj); //[Symbol(a), 'a', 'b', 'getFoo'] 遍历本身所有类型属性,包含不可枚举和symbol类型Object.keys(obj); //['a', 'b'] 遍历本身可枚举属性, // for...in遍历可枚举属性(包含继承而来的), 搭配hasOwnProperty应用过滤出本身可枚举属性
二. 数据类型的判断形式
- typeof
- instanceof
- constructor
- Object.prototype.toString.call()
- typeof
判断后果: 'string'、'number'、'boolean'、'undefined'、'function' 、'symbol'、'bigInt'、'object'
非凡情景
// 数据类型与typeof后果表现形式不同:console.log(typeof function(){}); // 'function'console.log(typeof null); // 'object'// 对于null, Object及其派生类型(Array, Date, RegExp等),无奈应用typeof进行类型的判断,须要应用instanceofconsole.log(typeof new Date()); // 'object'console.log(typeof new RegExp()); // 'object'
- instanceof
语法:A instanceof B , 即判断A是否为B类型的实例,也能够了解为B的prototype是否在A的原型链上
console.log([] instanceof Array); // trueconsole.log({a: 1} instanceof Object); // trueconsole.log(new Date() instanceof Date); // true// 留神:对于根本类型,应用字面量申明的形式能够正确判断类型console.log(new String('dafdsf') instanceof String) // trueconsole.log('csafcdf' instanceof String) // false, 原型链不存在
- constructor
当一个函数F被定义时,JS引擎会为F增加prototype原型,而后在prototype上增加一个constructor属性,并让其指向F的援用,F利用原型对象的constructor属性援用了本身,当F作为构造函数创建对象时,原型上的constructor属性被遗传到了新创建的对象上,从原型链角度讲,构造函数F就是新对象的类型。这样做的意义是,让对象诞生当前,就具备可追溯的数据类型
console.log([].constructor === Array) // trueconsole.log(new Date().constructor === Date) // trueconsole.log(new RegExp().constructor === RegExp) // true// 非凡的, null和undefined无奈应用这种形式判断,因为他们不是通过构造函数形式申明
在js中,个别会应用批改原型的形式实现js的继承,这种状况下个别要同步批改constructor 属性, 避免援用的时候出错, 例如:
function Aoo(){}function Foo(){} Foo.prototype = new Aoo();Foo.prototype.constructor = Foo;var foo = new Foo(); console.log(foo instanceof Foo)//true console.log(foo instanceof Aoo)//true
- Object.prototype.toString.call()
console.log(Object.prototype.toString.call(1)) // '[object Number]'console.log(Object.prototype.toString.call(1n)) // '[object BigInt]'console.log(Object.prototype.toString.call('123')) // '[object String]'console.log(Object.prototype.toString.call(null)) // '[object Null]'console.log(Object.prototype.toString({})) // '[object Object]'console.log(Object.prototype.toString.call([])) // '[object Array]'console.log(Object.prototype.toString.call(function a() {})) // '[object Function]'
综上可得,最能精确判断数据类型的形式为Object.prototype.toString.call()
特地的,理论我的项目开发中,常常用于判断对象和数组的几种形式:
- instanceof
- isPrototypeOf: Array.isPrototypeOf({} | []), 基于原型链的概念
- constructor: [] | {}.constructor = Array
- isArray
- Object.prototype.toString.call({} | [])