JS基础-1|原生数据类型和ES6数据类型以及数据类型检测
数据类型是实际开发中经常使用的知识,本篇沉淀一下数据类型的相关知识。
关于ECMAScript历史
在博客开始之前先了解一下JS和ECMAScript的历史和版本。
现在2021年了,每年一个版本,现在ECMAScript也更新到了ECMAScript2021了。其中变动比较大的属于ES5和ES6版本。
ECMAScript5: 也称为ES5,于2009年发布(并非2015年)。
ECMAScript2015:也称为ES6,于2015年发布(并非2016年)。
后续版本均已年份命名了,也可称为ES7、ES8、ES9...
关于ES的发展史可以参考以下文章:
- W3school的JavaScript 版本
- ECMA的官方网站
- zzfx博主的js版本规范的表示,图文描述比较形象
原生数据类型
数据类型是js基础中的基础,在实际工作中经常使用,如果面试被问到,你会怎么回答?
在这里,我们将数据类型分为三类进行回答:基础数据类型和复杂数据类型和ES6新增数据类型。
分别对三种类型详细说明,可以给面试官留下基础扎实、表达清晰的印象。
基础数据类型
最基本的数据类型:
null: 不存在的事物(万物从不存在开始)
undefined: 未定义(有变量没有值)
string:字符串,被引号包裹的值(值从字符开始)
number:数值,整数、小数、科学计数法的数字(123e5)(想想你口袋中的money)
boolean:布尔值,true和false(代码世界只有对错)
复杂数据类型
复杂的对象数据类型,包含:
object:对象,用花括号包裹的(一个人有很多属性)
array:数组,用中括号包裹的(类似一群人~)
ES6新增数据类型
Symbol:独一无二的值,属于基础数据类型
Set:类似于数组,但是值都是唯一的,属于数据结构
WeakSet:与Set类似,但WeakSet的值只能是对象,WeakSet 中的对象都是弱引用,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存
Map:类似于对象,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。属于数据结构
WeakMap:与Map结构类似,但WeakMap
只接受对象作为键名(null
除外),WeakMap
的键名所指向的对象,不计入垃圾回收机制
数据类型检测
以下是以往开发中常用的数据类型检测方法,并配置测试案例进行检测,归纳总结各个方法的特点。
解决方案一:typeof
typeof返回变量或表达式的类型,值有string、number、boolean、undefined、object、function
typeof ''; // 'string'
typeof 1; // 'number'
typeof false; // 'boolean'
typeof undefined; // 'undefined'
typeof {}; // 'object'
typeof function () {}; // 'function'
typeof Symbol(); // 'symbol'
// 以下检测失败
typeof []; // 'object'
typeof null; // 'object'
typeof new Set(); // 'object'
typeof new Map(); // 'object'
结论:只支持string、numbe、boolean、undefined、function、symbol等类型检测
解决方案二:instanceof
instanceof用于检测实例是否属于某个构造函数,返回true和false
(null) instanceof Null; // 报错
(undefined) instanceof Undefined; // 报错
('1') instanceof String; // false
(1) instanceof Number; // false
(Symbol()) instanceof Symbol // false
([]) instanceof Array; // true
({}) instanceof Object; // true
(function () {}) instanceof Function // true
// 拓展自定义构造函数
function App() {}
(new App()) instanceof App; // true
结论:支持Object、Array和自定义构造函数检测
解决方案三: constructor
constructor用于返回对象的构造函数。
(null).constructor.toString().indexOf('Null') > -1; // 报错
(undefined).constructor.toString().indexOf('Undefined') > -1; // 报错
('1').constructor.toString().indexOf('String') > -1;
(1).constructor.toString().indexOf('Number') > -1;
(true).constructor.toString().indexOf('Boolean')> -1;
(new Symbol()).constructor.toString().indexOf('Symbol') > -1; // 报错
({}).constructor.toString().indexOf('Object') > -1;
([]).constructor.toString().indexOf('Array') > -1;
(function(){}).constructor.toString().indexOf('Function') > -1;
// 拓展自定义构造函数
function App () {}
new App().constructor.toString().indexOf('App') > -1; // true
结论:null、undefined和Symbol无法检测,支持自定义构造函数检测
解决方案四:Object.prototype.toString.call()
该方法可以判断对象的类型
Object.prototype.toString.call(null) === '[object Null]';
Object.prototype.toString.call(undefined) === '[object Undefined]';
Object.prototype.toString.call('1') === '[object String]';
Object.prototype.toString.call(1) === '[object Number]';
Object.prototype.toString.call(true) === '[object Boolean]';
Object.prototype.toString.call(new Symbol()) === '[object Symbol]'; // 报错
Object.prototype.toString.call({}) === '[object Object]';
Object.prototype.toString.call([]) === '[object Array]';
Object.prototype.toString.call(function(){}) === '[object Function]';
// 拓展自定义构造函数
function App () {}
Object.prototype.toString.call(new App()) === '[object App]'; // false
结论:支持null和undefined,但不支持自定义构造函数检测
总结沉淀
对比以上四个检测方法,不难看出:
typeof
支持基础的字符串、数值、布尔值、undefined等检测,但不支持null、array、构造函数等。instanceof
支持Object、Array和自定义构造函数检测,但对基础类型不支持。constructor
支持基础类型和自定义构造函数,但是不支持null、undefined和SymbolObject.prototype.toString.call()
支持除Symbol外的所有类型,但是不支持自定义构造函数- ES5新增了Array.isArray用于检测数组的方法
因此:
- 若检测js数据类型
Object.prototype.toString.call()
是最强大的\ - 若检测ES6的Symbol使用
typeof
- 若检测自定义构造函数需要用
instanceof
或constructor
Symbol
Symbol是ES6新增的数据类型,用于表示唯一值。
var name1 = Symbol()
console.log(name) // Symbol()
var name2 = Symbol()
console.log(name1 === name2) // false
只打印了Symbol()
,而且两个变量值不相等,并没有实际的值。可以理解为程序内部唯一值。继续深入
const name = Symbol()
const obj = { [name]: '张三', age: 1 }
console.log(obj) // {age: 1, Symbol(): '张三'}
console.log(obj[name]) // '张三'
console.log(Object.keys(obj)) // ['age']
直接打印obj时key为Symbol()
,但是通过变量可以获取到obj的值,获取对象的key集合也没有Symbol,可以理解Symbol为Obj对象添加了私有变量。
Symbol的用法在Vue3中会有实战,在这里不在赘述,仅了解Symbol的特性即可,后续基于Symbol的特性进行实际场景应用。
相关试题
- JS中数据类型有哪些
- ES6新增的数据类型有哪些
- 如何判定数组的数据类型
- 通过构造函数创建的对象怎么检测类型
- Symbol数据类型的特点,实际应用有哪些?
转载自:https://juejin.cn/post/7035950371247751199