文章目录
七种内置类型
类型是谁的类型?js的变量是没有类型的说法的,只有值才有类型。
只有当变量被赋值的时候它才看起来有了值的类型。他可以随时持有任何类型的值。
这就是js弱类型的体现,如果是强类型,会要求变量总是持有其初始化的类型的值。
变量没有赋值时,仅仅声明是没有类型可言的。
所以在表述上也应该注意,变量没有类型,值才有类型。
1、undefined
理解为未定义的值,即被var或者其他声明方式声明,但是没有赋值。
既是一种类型,也是值。
有一种还算贴切的表述是:从未赋过值。
var a;
console.log(a); // undefined
console.log(b); // b is not defined => undeclared 未声明
//注意;这是两码事哦 undefined 不等于 not defined
但是有个问题就是:声明过但未初始化的变量和从未声明的变量用typeof检测都是undefined。
关于undefined的另一种理解:
undefined是一个内置的标识符,他的值为undefined
可以用void获取该值。如 void 0/true… 源于C语言。
var per;
typeof per; //undefined per声明过但未初始化
typeof foo; //undefined foo从未声明
因此我们一般情况下,如果使用一个可能被赋值为对象的变量,初始化null。尽量不要使用undefined特殊值。
注意将undefined与null的用法对比。
2、null
空值,可能已经被声明了。只是没有赋值。
有一种还算贴切的表述是:曾经赋过值,现在没有值。或者现在是空值。
null的使用场景:
- 初始化一个可能赋值为对象的变量
- 和已经初始化的变量比较,该变量可以是对象也可不是
- 当函数参数或返回值期望是对象时,用作参数或者返回值。
//使用场景
var person = null; //初始化一个可能赋值为对象的变量
function getPer(){
per = person;
if(per !== null){ //和已经初始化的变量比较,该变量可以是对象也可不是
return other;
}else{
return null; //当函数参数或返回值期望是对象时,用作参数或者返回值。
}
}
不能使用null的场景:
- 不要用null检测是否传入了参数
- 不要用null检测未初始化的变量
//不应使用的场景
function getPer(arg1,arg2){
var per;
if(per !== null){ //,不推荐,不要用null检测未初始化的变量
return other;
}else if(arg1 == null){ //不推荐 不要用null检测是否传入了参数
return null;
}
最好的理解null的方法是把null当做对象的占位符。
3、boolean
布尔值
4、string
字符串。
学过一些其他语言的同学可能会将数组和字符串看作一种东西。但是js中不是这样的。
一个最明显的区别:字符串是不可变的,数组是可变的。
5、number
数字,不区分单精度双精度。统一用的IEEE 754 双精度的存储方式。因此12.0和12是一样的。
关于数字的一些杂七杂八
- 在js中,特别大或者特别小的数默认以指数形式展示。
- .优先识别为数字的小数点,然后才是对象的属性。
- 我们知道0.1+0.2 != 0.3,那么怎么避免呢?设置一个机器精度
Number.EPSILON = Math.pow(2,-52);//机器精度
function enoughEqual(n1,n2){
return Math.abs(n1-n2) < Number.EPSILON
}
- Number 定义了最大值和最小值,但是最小值不是负数,他无限接近于零。(0无法表示吗??)
- ES6有定义安全整数 Number.isSafeInteger()
- 在某种情况下,我们需要32位的有符号整数,可以用
a | 0
进行转换。32位之后的省略。 - NaN !== NaN true
- 关于 isNaN()—— ES5:window.isNaN() ES6:Number.isNaN() 一个是全局函数,表示不是数字,字符串也行。 一个是需要是数字且为NaN。
6、object
对象包括基本的对象,以及一些其他的对象子类型。比如数组、函数都是对象的子类型。他们都继承了对象,同时又有自己特殊的功能。
此外还有一些内置的对象,他们也是对象类型。比如基本类型的包装对象(String、Number…)、日期类型、正则类型、错误类型等等。
但是这些内置对象虽然称之为类型,他们实际上是一些内置的函数,这些函数可以当作构造函数来构造一些对象。
数组
数组是一种特殊的对象,他可以容纳任何类型的值。不用预先设置长度。
聊一聊数组length的一些问题
- 使用delete删除数组的元素,length不会改变
- a[0]和a[2]赋值,a[1]不作处理,此时length为3.且a[1]与手动设置为undefined是有区别的
- 数组的索引虽然可以是任何字符串,但是字符串的索引不计入length值,除非他可以被强制类型转为十进制。
数组中还有一个常见的变体——类数组。
我们通常用以下两种方式将类数组arr转成数组
- Array.prototype.slice.call(arr)
- Array.from(arr)
7、symbol
ES6新增。符号类型。
类型检测
普通的类型检测
- 检测boolean :
typeof true === ‘boolean’
true - 检测string :
typeof '123' === ‘string’
true - 检测number :
typeof 123 === ‘number’
true - 检测object :
typeof {a:123} === ‘object’
true 注意数组也是对象的一种。 - 检测symbol :
typeof Symbol() === ‘symbol’
true
特殊的类型检测
- 检测undefined :
typeof undefined === ‘undefined’
true 注意上文提到的:未声明和为定义都是一样的 - 检测null :
var a = null ;!a && typeof a === ‘object’
true
注意:null是唯一一个typeof不是本类型对应字符串的类型。它为什么等于object呢,这其实是js的一个bug,他的原理是这样的,不同类型的数据在底层都表示为二进制,js判断是不是object的方法是判断它的前三位是不是零。而null在地城的表示是所有位都是零,他的前三位自然也是000,因此执行typeof时返回’object’。 - 检测function
typeof function a(){} === 'function'
true
注意:function虽然也是对象,但是它的typeof的值是function而不是object,说明在底层还是通过标志位做了函数区分。
强制类型转换
我的另一篇文章专门介绍了js强制类型的转换,有帮助的话给个小心心哦。