企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## 总结 简单数据类型:Undefined、Null、Boolean、Number、String、Symbol; 复杂数据类型:object ```js typeof val === 'object' Object.prototype.toString.call(obj) === '[object Object]' obj.constructor === Object obj instanceof Object 数组可通过Array.isArray()判断 ``` ## 具体 - 1, 六种简单数据类型:Undefined、Null、Boolean、Number、String、Symbol(新增); 一种复杂数据类型:Object; * (1)基本数据类型保存在栈内存中,是按值传递的,可以直接操作保存在变量中的实际值; * 复杂数据类型以堆的形式存储,地址(指向堆中的值)存储在栈中。 * (2)引用数据类型是保存在堆内存中的对象;JavaScript没有按引用传递,而是传递引用类型的参数(是按值传递,按引用访问),不可以直接访问堆内存空间中的位置和操作堆内存空间,只能操作对象在栈内存中的引用地址; - 2, 引用类型:Object、Array、Function、Date、RegExp、基本包装类型、单体内置对象(特殊引用类型) * (1)引用类型是一种数据结构,用以将数据和功能组合在一起; * (2)使用 new 创建的均为 Object 类型,所有引用类型默认都继承自 Object ; - 3, 基本包装类型:Boolean、Number、String; - 4,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使用过滤出自身可枚举属性 ```` ## 2 如何判断数据类型 > typeof、instanceof、 constructor、 prototype、 $.type()/jquery.type(), ### 2-1. typeof - 判断结果: 'string'、'number'、'boolean'、'undefined'、'function'、'symbol'、'bigInt'、'object'(Array, Date, RegExp会统一判别为object); - typeof 操作符适合确定除 Null 以外的简单数据类型; - 使用 typeof 操作符无法有效区分引用类型,只能知道他是对象,而不能知道是什么类型的对象,此时使用 instanceof 操作符; ``` // 数据类型与typeof结果表现形式不同: console.log(typeof function(){});  // 'function' console.log(typeof null);          // 'object' !!!!!!!!!!!!! console.log(typeof undefined) // undefined console.log(typeof []) //object // 对于null, Object及其派生类型(Array, Date, RegExp等),无法使用typeof进行类型的判断,需要使用instanceof console.log(typeof new Date());    // 'object' console.log(typeof new RegExp());  // 'object' ``` ### 2-2. instanceof *A instanceof B* , 即判断A是否为B类型的实例,也可以理解为B的prototype是否在A的原型链上 * instanceof 操作符可以用来判断new 出来基本类型(简单数据类型); - instanceof是通过原型链进行判断的,`A instanceof B`,在A的原型链中层层查找,查找是否有原型等于`B.prototype`,如果一直找到A的原型链的顶端,即`Object.prototype.__proto__`,仍然不等于`B.prototype`,那么返回**false**,否则返回**true** ``` console.log([] instanceof Array);                  // true console.log({a: 1} instanceof Object);             // true console.log(new Date() instanceof Date);           // true // 注意:对于基本类型,使用字面量声明的方式可以正确判断类型 console.log(new String('dafdsf') instanceof String) // true console.log('csafcdf' instanceof String) // false, 原型链不存在 ``` ### 2-3. constructor ``` console.log([].constructor === Array) // true console.log(new Date().constructor === Date) // true console.log(new RegExp().constructor === RegExp) // true // 特殊的, null和undefined无法使用这种方式判断,因为他们不是通过构造函数方式声明 val?.constructor === Object // 使用了 null 传导符(?.) 以防止出错!!!! ``` 在js中,一般会使用修改原型的方式实现js的继承,这种情况下一般要同步修改constructor 属性, 防止引用的时候出错, 例如: ``` functionAoo(){} functionFoo(){}  Foo.prototype = new Aoo(); Foo.prototype.constructor = Foo; var foo = new Foo();  console.log(foo instanceof Foo)//true console.log(foo instanceof Aoo)//true ``` ### 2-4. 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({}.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() 另外,数组可通过Array.isArray()判断