一,js的数据类型
目前有以下七种:
UndefinedNullBooleanStringNumberSymbolObject
🌊Undefined
Undefined 类型表示未定义,它的类型只有一个值,就是undefined。任何变量在赋值前都是 Undefined 类型、值为 undefined。
但是呢,因为在js中,undefined不是关键字,而是一个变量。于是这就导致了,它可以被重新赋值,也就是人们常说的重写。
虽然说,undefined 在 ES5 中已经是全局对象的一个只读(read-only)属性了,它不能被重写。但是在局部作用域中,还是可以被重写的。
例如:
(function() {var undefined = 10;console.log(undefined);// 10 -- chrome})();
这将意味着以下这种写法判断变量是否undefined的失效:
(function() {var undefined = 10;console.log(undefined);// 10 -- chrome已经把undefined这个变量重写为10了var aconsole.log(a)// undefinedif(a===undefined){//这里的写法会失效console.log("a是undefined类型的数据")}})();
为了避免这种情况,之前的代码(上古浏览器时代)是使用void来处理的;void是js中的一个函数,无论传入啥表达式,都不会有返回,也就是它的值就是undefined,而最简单的表达式是0,于是人们常常用它来代替undefined。
于是有:
function isUndefined(value){//获得undefined,保证它没有被重新赋值var undefined = void(0);return value === undefined;}
所以,在实际编程时,我们一般不会把变量赋值为 undefined,这样可以保证所有值为 undefined 的变量,都是从未赋值的自然状态。
值得注意的是,在var,let,const三者中,undefined的出现又不同
var变量定义而未赋值,则为undefinedconst常量必须初始化,也就是只有赋值为undefined才为undefinedlet变量定义而未赋值,则为undefined
🌊null
Null 类型也只有一个值,就是 null,它的语义表示空值,与 undefined 不同,null 是 JavaScript 关键字,所以在任何代码中,你都可以放心用 null 关键字来获取 null 值。
在初始化对象等复合数据类型的时候,我们通常让其指向null:
let obj=null
🌊Boolean
Boolean 类型有两个值, true 和 false,它用于表示逻辑意义上的真和假,同样有关键字 true 和 false 来表示两个值。
而布尔值很常见的js场景就是布尔值的隐式转化:
值得注意的是,空格字符串和字符串“0”是转化为true的。
console.log(Boolean(""))//falseconsole.log(Boolean(" "))//trueconsole.log(Boolean("0"))//trueconsole.log(" "==false)//在相等符号中,如果一个操作数是字符串,另一个操作数是数值,在比较之前先将字符串转换为数值,空格转化出来是数值0,结果是true
🌊String
JavaScript 中的字符串是永远无法变更的,一旦字符串构造出来,无法用任何方式改变字符串的内容,所以字符串具有值类型的特征。
🌊Number
Number 类型表示我们通常意义上的“数字”。
JavaScript 为了表达几个额外的语言场景(比如不让除以 0 出错,而引入了无穷大的概念),规定了几个例外情况:
NaN,占用了 9007199254740990,这原本是符合 IEEE 规则的数字;Infinity,无穷大;-Infinity,负无穷大。
另外,值得注意的是,JavaScript 中有 +0 和 -0,在加法类运算中它们没有区别,但是除法的场合则需要特别留意区分,“忘记检测除以 -0,而得到负无穷大”的情况经常会导致错误,而区分 +0 和 -0 的方式,正是检测 1/x 是 Infinity 还是 -Infinity。
当然,在计算机中,我们有一定的精度限制。
同样根据浮点数的定义,非整数的 Number 类型无法用相等和全等来比较,一段著名的代码,为什么在 JavaScript 中,0.1+0.2 不能 =0.3:
console.log( 0.1 + 0.2 == 0.3);//false
浮点数运算的精度问题导致等式左右的结果并不是严格相等,而是相差了个微小的值。
所以实际上,这里错误的不是结论,而是比较的方法,正确的比较方法是使用 JavaScript 提供的最小精度值:
console.log( Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON);
检查等式左右两边差的绝对值是否小于最小精度(Number.EPSILON是js的最小误差或者说精度),才是正确的比较浮点数的方法。
🌊Symbol
ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值,最大的用法是用来定义对象的唯一属性名。
let sy = Symbol("key1");let syObject = {};syObject[sy] = "kk";console.log(syObject); // {Symbol(key1): "kk"}
Symbol 值作为属性名时,该属性是公有属性不是私有属性,可以在类的外部访问。但是不会出现在 for…in 、 for…of 的循环中,也不会被 Object.keys() 、 Object.getOwnPropertyNames() 返回。如果要读取到一个对象的 Symbol 属性,可以通过 Object.getOwnPropertySymbols() 和 Reflect.ownKeys() 取到。
let syObject = {"first":"第一个","second":"第二个"};let sy = Symbol("key1");syObject[sy] = "kk";console.log(syObject);for (let i in syObject) {console.log(i);} // first secondconsole.log(Object.keys(syObject)); // [ 'first', 'second' ]const test1=Object.getOwnPropertySymbols(syObject); console.log(test1) //获取symbols类型key组成数组 [ Symbol(key1) ]const test2=Reflect.ownKeys(syObject); console.log(test2) // 所有key组成数组:[ 'first', 'second', Symbol(key1) ]
🌊Object
JavaScript 中的几个基本类型,都在对象类型中有一个“亲戚”。它们是:
NumberStringBooleanSymbol
所以,我们必须认识到 3 与 new Number(3) 是完全不同的值,它们一个是 Number 类型, 一个是对象类型。
二,typeof进行类型判断
也就是说typeof是不能用来区分对象和数组的。