和PHP一样JS在变量定义中不需要 (或不支持) 明确的类型定义;变量类型是根据使用该变量的上下文所决定的(自动转换)
基本知识
变量的数据类型转换:将一种数据类型转换为另外一种数据类型
- 自动数据类型转换(隐式转换)
- 强制数据类型转换(显式转换)
通常有三种形式的类型转换:
- 转换为字符串类型
- 转换为数字型
- 转换为布尔型
你会专门把某个数据类型转换成 null 或者 undefined 吗?不会,因为这样做,没有意义。
typeof 运算符
typeof()
表示“获取变量的数据类型”,返回的是小写,语法为:(两种写法都可以)
// 写法1
typeof 变量;
// 写法2
typeof(变量);
typeof 这个运算符的返回结果就是变量的类型。那返回结果的类型是什么呢?是字符串。
返回结果:
typeof 的代码写法 | 返回结果 |
---|---|
typeof 数字 | number |
typeof 字符串 | string |
typeof 布尔型 | boolean |
typeof 对象 | object |
typeof 方法 | function |
typeof null | object |
typeof undefined | undefined |
备注 1:为啥 typeof null
的返回值也是 object 呢?因为 null 代表的是空对象。
备注 2:typeof NaN
的返回值是 number,上一篇文章中讲过,NaN 是一个特殊的数字。
返回结果举例:
console.log(typeof []); // 空数组的打印结果:object
console.log(typeof {}); // 空对象的打印结果:object
代码解释:这里的空数组[]
、空对象{}
,为啥他们在使用 typeof 时,返回值也是 object
呢?因为这里的 返回结果object
指的是引用数据类型。空数组、空对象都是引用数据类型 Object。
typeof 无法区分数组,但 instanceof 可以。比如:
console.log([] instanceof Array); // 打印结果:true
console.log({} instanceof Array); // 打印结果:false
关于 instanceof 的详细内容,以后讲对象的时候,会详细介绍。
自动类型转换
+ 转换为String
- 任何类型值和字符串相加,都会转换为字符串,实质是先调用String()函数再运算
- 可以利用该特点,将任意数据类型转化为string
+ 运算符自动向高精度转换
- JS基本数据类型精度 Boolean < Number < String
- 在运算时,数据类型会自动向高精度转换
- 任何类型值和字符串相加,都会转换为字符串
a++
是个特例,如果a是字符串结果为number
var a;
a = true + 1.1; // number 2.1
a = true + 1.1 + '2'; // string 2.12
document.write(typeof a);
document.write(a);
根据上下文自动转换
- 算数运算符
+
,数据类型会自动向高精度转换 - 算数运算符
+
,任何类型值和字符串相加,会隐式调用String()
函数,可将任意值转换为字符串 - 除了
+
的算数运算符,会隐式调用Number()
函数,将任意值转换为Number
,然后再进行运算 - 一元运算符,会隐式调用
Number()
函数,将任意值转换为Number
,然后再进行运算 - 自增/自减运算符,会隐式调用
Number()
函数,将任意值转换为Number
,然后再进行运算 - 比较运算符,会隐式调用
Number()
函数,将任意值转换为Number
,一般为字符串到数字的自动转换, - 逻辑运算符,会隐式调用
Boolean()
函数,将任意值转换为bool,然后再进行运算
var a;
// 算数运算符 + 自动向高精度转换
a = true + 1.1 + ''; // string 2.1
// 其他算数运算符,会隐式调用Number() 方法,然后再进行运算
a = '12a' - 1; // number NaN
a = '' - 1; // number -1
a = true - 1; // number 0
a = null - 1; // number -1
a = undefined - 1; // number NaN
document.write(typeof a);
document.write(a);
//比较运算符 == ,会隐式调用Number() 方法,字符串到数字的自动转换
// ' ' == 0 ---> true
// '2' == 2 ---> true
// true == 1 ---> true
// false == 0---> true
//逻辑运算符`&& || !`,会隐式调用Boolean() 方法,其他类型到布尔型的转换
// - 数字转Boolean除了 `0` 和 `NaN`,其余都是true
// - 字符串转Boolean除了`空字符串`其余都为true
// - `null`和`undefined`转为bool都是false
强制类型转换
将一个数据类型强制转换为其他数据类型
类型转换主要是指将其他数据类型转化为String Number Boolean
转换为String
方式1:调用被转换数据类型的 toString() 方法
- 并没有改变
a
本身的数据类型,只是把返回的结果类型改变了 - 可以把返回值赋给
a
,从而改变a
的数据类型 null
和undefined
这两个值没有toString()
方法
var a = 123;
a = a.toString(); // string '123'
a = true;
a = a.toString(); // string 'true'
/*
a = null;
a = a.toString(); // 报错
a = undefined;
a = a.toString(); // 报错
*/
方式2:调用 String()
函数
- 调用
String()
函数,并将被转换的数据作为参数传递给函数 - 对于
Number
和Boolean
实际上就是调用toString()
方法 - 对于
null
和undefined
就不会调用toString()
方法,直接给数据加引号,数据类型不变
var a = 123;
a = String(a); // string '123'
a = true;
a = String(a); // string 'true'
// 下面比较奇怪 值转换为了字符串 但数据类型却不是字符串
a = null;
a = String(a); // object 'null'
a = undefined;
a = String(a); // undefined 'undefined'
document.write(typeof a);
document.write(a);
转换为Number
方式1:调用 Number()
函数 link
- Number()函数能将所有数据类型转为Number类型
- 字符串转数字,纯数字值为数字,有非数字内容值为NaN,全是空格值为0
- 布尔转数字,true值为1,false值为0
null
转数字,值为0undefined
转数字,值为NaN
var a = '123';
// a = Number(a); // number 123
// a = '123ABC';
// a = Number(a); // number NaN
// a = '';
// a = Number(a); // number 0
// a = ' ';
// a = Number(a); // number 0
// a = true;
// a = Number(a); // number 1
// a = null;
// a = Number(a); // number 0
a = undefined;
a = Number(a); // number NaN
document.write(typeof a);
document.write(a);
方式2:调用 parseInt() 和 parseFloat() 函数 link link
parseInt()
和parseFloat()
专门用来提取字符串中的有效数字并将其转换为Number
- 若字符串中没有有效数字,值转为
NaN
- 对于
非String
使用该函数,它会先将其转换为String
然后再操作 - parseInt() 函数把一个字符串转换为整数,只取整数位
- parseFloat() 函数把一个字符串转换为整数,取整数位和小数位
var a = '1ab2';
// a = parseInt(a); // number 1
// a = '1.23ab2';
// a = parseFloat(a); // number 1.23
// a = 'aa11';
// a = parseInt(a); // number NaN
// a = ' ';
// a = parseInt(a); // number NaN
// a = true;
// a = parseInt(a); // number NaN (先转为字符串'true',然后再操作,下面一样)
// a = null;
// a = parseInt(a); // number NaN
// a = undefined;
// a = parseInt(a); // number NaN
document.write(typeof a);
document.write(a);
补充:parseInt() 函数还可以进制转换 ------------- 见文章最后
转换为Boolean
调用Boolean() 函数,我所知道的,只有JS能强制将其他类型转换为Boolean
- 数字转Boolean除了
0
和NaN
,其余都是true - 字符串转Boolean除了
空字符串
其余都为true null
和undefined
转为bool都是false
注意,空数组和空对象,转换结果是 true,这个一点,很多人都不知道
// 数字转bool除了 0 0.0 和NaN,其余都是true
var a = 0;
a = Boolean(a); // boolean false
a = 0.0;
a = Boolean(a); // boolean false
a = NaN;
a = Boolean(a); // boolean false
// 字符串转bool除了空字符串其余都为true
a = '';
a = Boolean(a); // boolean false
// null和undefined转为bool都是false
a = null;
a = Boolean(a); // boolean false
a = undefined;
a = Boolean(a); // boolean false
document.write(typeof a);
document.write(a);
parseInt() 补充说明
parseInt(string, radix) 函数可解析一个字符串,并返回一个整数
当参数 radix 的值为 0,或没有设置该参数时,parseInt() 会根据 string 来判断数字的基数
当忽略参数 radix , JavaScript 默认数字的基数如下:
- 如果 string 以 “0x” 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。
- 如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。
- 如果 string 以 1 ~ 9 的数字开头,parseInt() 将把它解析为十进制的整数。
本来不设置第二个参数也没问题,但是不同浏览器解析不一样,比如 var a = 010
,原本想表示8进制,可能ie输出为10,火狐输出为8,会乱套,此时需要参数 radix 强制规定一下
带两个参数时,表示在转换时,强制规定了a的进制,代码举例:
var a = '010';
var num = parseInt(a); // edge解析为10 火狐可能为8
num = parseInt(a, 16); // 强制将 a 当成 十六进制 来看待 结果16
document.write(num);
无论 parseInt() 里面radix规定a的进制是多少,最终的转换结果是十进制
var a = '5';
var num = parseInt(a, 2); // 将 a 当成 二进制 来看待,转换成 十进制 的 num
console.log(num); // 打印结果:NaN。因为 二进制中没有 5 这个数,转换失败。