JavaScript 类型转换
一、typeof()方法
typeof() 能区分数据是什么类型的,比如一个数字123,一个字符串"123"
var num = 123; console.log(typeof(num)); // number var num = "123"; console.log(typeof(num)); // string
true返回boolean类型
var mode = true; console.log(typeof(mode)); // boolean
数字、字符串、布尔这是三种基本的值,
typeof能返回六种数据类型 number、string、boolean、object、undefined、function
什么样的值返回object呢?
对象是肯定返回的是object,但这时候object指的不是单纯的对象,它是泛泛指的是一种引用值
var obj = {}; console.log(typeof(obj)); // object
也就说数组返回的也是object,泛泛的引用值它都返回的是object
var arr = []; console.log(typeof(arr)); // object
还有一种数据叫 null 是原始值之一,会发现null返回的也是object
var mode = null; console.log(typeof(mode)); // object
为什么原始值null返回的是object呢?
原始值和引用值没关系,这就涉及浏览器的一个历史遗留问题,
最早的null是作为代替空对象的形式出现的,它是给对象来占位的,所以那个时候系统认为null是对象,tpyeof的时候就是对象了,直到现在也没改过来,null是原始值不假,但typeof返回的是object类型。
undefined 返回的是 undeined
var a = undefined; console.log(typeof(a)); // undefined
function函数会返回function
var fn = function(){} console.log(typeof(fn)); // function
typeof()有两种写法,第一种写法加括号,第二种是不加括号用空格隔开,最好加括号看起来有归属感
var a = 123; console.log(typeof(a)); // number console.log(typeof a); // number
typeof能帮我们区分数据是什么类型的下面马上就知道了
二、类型转换
数字1加上数字1肯定等于2
var num = 1 + 1; console.log(typeof(num) + ": " + num); // number: 2
数字1加上字符串"1",返回的是字符"11"
var num = 1 + "1"; console.log(typeof(num) + ": " + num); // string: 11
数字1乘以字符串"1",返回的是数字类型的1
var num = 1 * "1"; console.log(typeof(num) + ": " + num); // number: 1
数字1减字符串"1"能减吗?能减,返回的是数字类型的0
var num = 1 - "1"; console.log(typeof(num) + ": " + num); // number: 0
字符串"2"减去字符串"1",这样还是可以的,返回的是数字类型的1
var num = "2" - "1"; console.log(typeof(num) + ": " + num); // number: 1
字符串"2" 乘 字符串"1",返回的是数字类型的2
var num = "2" * "1"; console.log(typeof(num) + ": " + num); // number: 2
这种语法在其它语言里没有只有js独有,为什么可以这样?
因为js里有一个类型转换,
类型转换分两种,上面的是“隐士类型转换”,在这之前我们必须先了解“显式类型转换”。
三、显示类型转换
Number(mix)
parseInt(string,radix)
parseFloat(string)
toString(radix)
String(mix)
Boolean()
1、Number(mix)
Number() 方法执行完后会把字符串"123",转成数字123并返回给我们
var str = "123"; var num = Number(str); // 括号里面是字符串的"123" console.log(typeof(num) + ": " + num); // number: 123(转换成数子123了)
布尔值true转换成数字是 1
var bool = true; var num = Number(bool); console.log(typeof(num) + ": " + num); // number: 1
布尔值false转换成数字是 0
var bool = false; var num = Number(bool); console.log(typeof(num) + ": " + num); // number: 0
null转换成数字是 0
var a = null; var num = Number(a); console.log(typeof(num) + ": " + num); // number: 0
undefined不能被转成数字,这是特殊的一个,虽然返回的是NaN但依然是数字类型,也就是说经历Number方法后,不管能不能转换成真实的数,反正都会变成数字类型,转不成的都变成NaN
var a = undefined; var num = Number(a); console.log(typeof(num) + ": " + num); // number: NaN
字符串"a"不能转化成数字返回NaN(没有转成ASCII码97),这种看起来就不是数字的就转不成数字
var mode = "a"; var num = Number(mode); console.log(typeof(num) + ": " + num); // number: NaN
基本所有情况都在Number里面得出的结果试过了,现在如果字符串"-123"转成数字是-123
var mode = "-123"; var num = Number(mode); console.log(typeof(num) + ": " + num); // number: -123
字符串"123abc",不能转成数字返回NaN
var mode = "123abc"; var num = Number(mode); console.log(typeof(num) + ": " + num); // number : NaN
Number是把给它的数据转化为数字,下面是parseInt(string,radix)
2、parseInt(string,radix)
parse是转化的意思,
Int是整型的意思
parseInt(string, radix)的目的不是转化成 数 而是转化成整形的数,parseInt就是转化成整数,凡是有小数点的都给去掉,Ps: 数学整数是Z来表示、Q是有理数
parseInt把字符串"123"转化数字123
var mode = "123"; var num = parseInt(mode); console.log(typeof(num) + ": " + num); // number: 123
parseInt好像也能转化数子
如果让parseInt转化布尔值true呢?true转化成NaN
var bool = true; var num = parseInt(bool); console.log(typeof(num) + ': ' + num); // number: NaN
false也转成NaN
var bool = false; var num = parseInt(bool); console.log(typeof(num) + ': ' + num); // number: NaN
parseInt和Number的侧重点不一样
Number 是想把数据转换成数字,所以它会千方百计的转化成数字
parseInt 不管那么多,parseInt是要把数转换成整的形
如果是字符串数"123"转化成数123,如果是正常的数 123.3 这样的数给转化成整形123,所以它不会关注true、false、nudefined、null,这些parseInt转化全是NaN
var mode = null; var num = parseInt(mode); console.log(typeof(num) + ': ' + num); // number: NaN var mode = undefined; var num = parseInt(mode); console.log(typeof(num) + ': ' + num); // number: NaN
如果是123.3转成123
var mode = 123.3; var num = parseInt(mode); console.log(typeof(num) + ' : ' + num); // number : 123
不是四舍五入,是直接去掉小数点,123.9直接去的小数返回123
var mode = 123.9; var num = parseInt(mode); console.log(typeof(num) + ' : ' + num); // number : 123
如果是字符串"123.9",一样也是直接去小数点返回数字123
var mode = "123.9"; var num = parseInt(mode); console.log(typeof(num) + ' : ' + num); // number : 123
这是parseInt的第一点用途转成整形,它还有第二点用途parseInt(demo ,radix),后面参数英文名radix是基底的意思。
什么是基底?
如果后面参数radix写16,它就会认为10(读一零)是十六进制的10,以十六进制为基底,把10转化为十进制。
把10(一零)当成十六进制转换为十进制的数是 16
// PS: 这里说的基底,就是别的教程里,进制的权值 var mode = "10"; var num = parseInt(mode ,16); // 以目标进制radix为基底转换成十进制(以十六进制为基底转换成十进制) console.log(typeof(num) + ': ' + num); // number: 16
进制的意思:
0到9在往上是10,9上面也可以不是10,也可以是a因为进制不同,这个10之所以叫做十进制,满十就进一,一就变成零(10)。
还有一种进制叫十六进制,满10变成a然后是b、c、d、e、f
16(f)再加1(f + 1 = 10)就变成一零了(10),这个10(一零)比较有含金量,这个1是十六进制的一,这一个1代表16,这个20的2代表两个16是32。
十六进制:0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F
如果换成b,b在十进制里是11
var mode = "b"; var num = parseInt(mode ,16); console.log(typeof(num) + ' : ' + num); // number: 11
radix取值范围是 2 - 36 可能还要饶一个0没有1,没有一进制,一进制太奔放了永远不可能有尽头,一进制不存在
如果2进制转换为10进制的数,3能转化吗?3不行返回NaN,二进制没有3,连2都没有,只能写1010……
var mode = "3"; var num = parseInt(mode ,2); console.log(typeof(num) + ': ' + num); // number: NaN
二进制里只有1和0
var mode = "10101010"; var num = parseInt(mode ,2); console.log(typeof(num) + ': ' + num); // number: 170
Ps:
没有一进制,一进制不存在
一些转换进制的练习
var mode = "20"; var num = parseInt(mode ,16); console.log(typeof(num) + ': ' + num);//number: 32 var mode = "21"; var num = parseInt(mode ,16); console.log(typeof(num) + ': ' + num);//number: 33 //在二进制里,10是十进制的2 var mode = "10"; var num = parseInt(mode ,2); console.log(typeof(num) + ': ' + num);//number: 2 //在三进制里,11是十进制的4 var mode = "11"; var num = parseInt(mode ,3); console.log(typeof(num) + ': ' + num);//number: 4
再看parseInt的基本用法,如果字符串"123abc"转化整形为123
var mode = "123abc"; var num = parseInt(mode); console.log(typeof(num) + ': ' + num); // number: 123
parseInt有一个独特都功能,它是从数字位开始往后看,一直看到非数字位截止 123abc 把之前的返回,这是砍断原则。
所以字符串 123.3abc 这个小数点是非数字给砍断了,以数字位开始看,看到非数字位截止,直接返回前面数。
var mode = "123.3abc"; var num = parseInt(mode); console.log(typeof(num) + ': ' + num); // number: 123
后期会遇到最典型的例子"100px"是字符串值,把100取出来parseInt是最好的办法
var mode = "100px"; var num = parseInt(mode); console.log(typeof(num) + ': ' + num); // number: 100
3、parseFloat(string)
parseFloat和parseInt极其相似,而且parseFloat没那么复杂,parseFloat就是把字符串 "100.2" 转化成浮点类型,换句话说转换成正常的数100.2,浮点数就是正常的小数
var mode = "100.2"; var num = parseFloat(mode); console.log(typeof(num) + ': ' + num); // number: 100.2
字符串"100.2.3"转换还是100.2
var mode = "100.2.3"; var num = parseFloat(mode); console.log(typeof(num) + ': ' + num); // number: 100.2
字符串"100.2abcd"转换成小数是100.2,parseFloat也是从数字位开始看,看到除了第一个点以外的非数字位截止,把前面的返回
var mode = "100.2abcd"; var num = parseFloat(mode); console.log(typeof(num) + ': ' + num); // number: 100.2
parseFloat没有基底只有一个参数
4、String(radix)
String和Number是一样的,
Number 致力于把变量转化成数字,
String 致力于转化成字符串
下面String方法把数字123.234转化字符串"123.234",写什么都会转化成字符串
var demo = 123.234; var str = String(demo); console.log(typeof(str) + ': ' + str); // string: 123.234
写undefined会变成字符串"undefined"
var demo = undefined; var str = String(demo); console.log(typeof(str) + ': ' + str); // string: undefined
写什么都会变字符串,写布尔值true转化成字符串"true"
var demo = true; var str = String(demo); console.log(typeof(str) + ': ' + str); // string: true
只要放到String(demo)里面,它就会把这个东西转换成字符串
5、Boolean()
Boolean(demo) 试图把里面的东西转化成布尔值
布尔值的规则,除了认定为false的六值 undefined、null、NaN、 ""、0、false,其它都是true。
""空字符串,转化为布尔值false
var demo = ""; var bool = Boolean(demo); console.log(typeof(bool) + ': ' + bool); // boolean: false
字符串"123"转化为布尔值true,Boolean致力于把里面的东西转化成布尔类型
var demo = "123"; var bool = Boolean(demo); console.log(typeof(bool) + ': ' + bool); // boolean: true
6、toString(radix)
toString()也是转化成字符串,只不过它的用法与String有点区别
toString不在是填值了,是想把谁转化成字符串,就用谁取调用toString()
var demo = 123; var str = demo.toString(); // demo调用toString console.log(typeof(str) + ': ' + str); // string: 123
布尔值true调用toString转为字符串"true"
var demo = true; var str = demo.toString(); console.log(typeof(str) + ' : ' + str); // string : true
toString()和String()差不多但有个特殊点,有两个不能用,undefined和null不能用toString()
试一下,下面undefined调用toString方法会报错
var demo = undefined; var str = demo.toString(); // Uncaught TypeError: Cannot read property 'toString' of undefined
报错信息:undefined没有toString这个属性,为什么没有?讲原型的时候会知道的
这块记住undefined不能用toString,null也不能用toString
var demo = null; var str = demo.toString(); // Uncaught TypeError: Cannot read property 'toString'
一般情况也没人用toString一般用String,或者直接加空字符串直接变字符串,任何数据加空字符串都成转化为字符串形式。
toString有另一个用法
toString(redix)里面还可以写一个redix参数,参数redix也是基底的意思,但这个基底不在是parseInt那个基低的用途了,toString的基低是以十进制为基底转化为目标进制。
比如数字123转化为八进制,123转换成八进制是173
var demo = 123; var str = demo.toString(8); // 8是目标进制,把123转化成八进制 console.log(typeof(str) + ': ' + str); // string: 173
来个简单点的,把10转化成八进制,toString(8)就是以十进制为基底转换成目标进制,目标进制是八进制
var demo = 10; var str = demo.toString(8); // 以十进制为基低,把目标转换成八进制 console.log(typeof(str) + ': ' + str); // string: 12
20转化成八进制是24
var demo = 20; var str = demo.toString(8); console.log(typeof(str) + ' : ' + str); // string : 24
24的2,代表2乘以8(2 * 8),24是16 + 4
看一道题
给你一个二进制的数 10101010 转成十六进制的怎么做?
思路:二进制可以转成十进制,十进制可以转成十六进制,先parseInt再toString
parseInt toString
2 --- 10 --- 16
var num = 10101010; var test = parseInt(num , 2); // 二进制转换为十进制,以目标进制2为基低转换为十进制 var test = test.toString(16); // 转换十六进制 console.log(test); // aa
二进制 10000 代表十进制16
var num = 10000; var test = parseInt(num ,2); // 16 var test = test.toString(16); // 10 console.log(test); // 10
parseInt做的是以目标进制转换为十进制的过程,toString做的是以十进制转换为目标进制的过程
四、隐式类型转换
isNaN() —>Number()
++/— +/-(一元正负)
+
*/%
&& || !
< > <= >=
== !=
隐式类型转换的特点,它内部隐式调用的都是显示类型转换的方法。
1、isNaN()
isNaN() —> Number()
把一个数放到isNaN()的括号里面,能判断这个数是不是NaN,然后返回来true或false
如果放的是一个NaN呢?判断NaN必须返回 true
console.log(isNaN(NaN)); // true
数字类型123不是NaN,所以返回 false
console.log(isNaN(123)); // false
字符串"123"不是NaN,所以返回 false
console.log(isNaN("123")); // false
见证奇迹的时刻,字符串"abc"是NaN吗?它是NaN返回 true
console.log(isNaN("abc")); // true
为什么 isNaN("abc") 返回的是NaN呢?
1. isNaN("abc") 它内部做了一件事,它会把字符串"abc"先放到 Number("abc") 里面去转化
2. 通过Number转化 Number("abc") --> NaN ,转化出的结果再和NaN去比对,如果是NaN相等就返回true
3. Number("abc") 转化出的结果是NaN,所以说里面经历的内部隐式转化的过程是Number方法,这个number没有显示的调用,但是隐式的调用了
既然知道里面隐式调用的是Number()方法了,如果 isNaN(null) 里面填null,返回的是true还是false?
1. null经历 Number(null) 的转化返回的是0
console.log(Number(null)); // 0
2. 0不是NaN,所以 isNaN(null) 返回 false
console.log(isNaN(null)); // false
umdefined经历Number转化为NaN,所以 isNaN(umdefined) 返回的是 true
console.log(Number(undefined)); // NaN console.log(isNaN(undefined)); // true
这种隐式类型转换,要是不懂显示类型转换的规则,只能是干背了undefined是true、null是falase
2、++加加、--减减
字符串类型"123"不是数字能加加运算吗?能加加,运算返回数字类型 124
var a = "123"; a ++; console.log(typeof(mode) + ': ' + mode); // number: 124
为什么字符串"123"能加加运算?
1. a ++ 加加这个符号往这一立,还没有进行运算(运算分写前、写后)之前,它就把前面的变量a给转换了
2. 怎么转换?先调用 Number("123") 转化成数字再说,还是隐式的去调用显示的方法,先转成数字所以能计算返回数字类型的 124
那字符串"abc"能计算吗?
1. 有一个趋势调用 Number("abc") 转成数字,但是没转成数字转成NaN了,
2. 所以最后 a++ 返回的是NaN,
3. tpyeof a 返回的是number类型,经历这样隐式类型转换之后,即使转不能数字也是数字类型了
var a = "abc"; a ++; console.log(a); // NaN console.log(typeof(a)); // number
经历了加加运算后即使转不成数字,也是数字类型了
加加和减减类似,写前写后也类似,反正都会被转成数字类型,重点是下面
3、+、- (一元正和负,不是加减)
正号或负号都会把字符串"abc"变换成数字类型
var a = "abc"; + a; // 正号 - a; // 负号 console.log(typeof(a) + ": " + mode); // number: NaN
这样 +"abc" 正号直接加在字符串上,变量a变成NaN转成nubmer数字类型
var a = +"abc"; console.log(typeof(a) + ": " + mode); // number: NaN
尽管转的不是真实的数字,但也要转换成数字类型,因为里面调用的是Number()方法
负号的 -"abc" 字符串,隐式调用的也是Number方法
var mode = -"abc"; console.log(typeof(mode) + ": " + mode); // number: NaN
4、+ 加号
加号的隐式类型转换调用的是 String() 方法
加号是一个特别特殊的语法,当加号两侧有一个是字符串,它就会调用 String() 把两边全变成字符串
var demo = "a" + 1; console.log(typeof(demo) + ": " + demo); // string : a1 var demo = "123" + 456; console.log(typeof(demo) + ": " + demo); // string: 123456
5、-、*、/、%(减号、乘号、除号、取模)
它们(减号、乘号、除号、取模)隐式类型转换调用的还是 Number() ,所以字符串"1"乘以数字1,它居然等于数字类型的 1,只要相乘两侧必须转换成数字类型的
var demo = "1" * 1; console.log(typeof(demo) + " : " + demo); // number : 1
如果字符串"a"乘数字1呢?
1. 还是调用Number方法 Number("a") 的结果 * Number(1) 的结果
2. 最后是 NaN * 1 还是NaN,但是类型变number了
var demo = "a" * 1; console.log(typeof(demo) + " : " + demo); // number : NaN
加法、减法、除法、模2都一样就不说了
6、&&、||、!(与、或、非)
! 非的类型转换就不说了,是布尔在取反
&& 、 || (与、或)的隐式类型转换,
之前学的时候是看,第一个表达式的结果转化的布尔值,然后再看第二个表达式结果是true还是false,
还是有隐式类型转换的过程,只不过返回的是表达式的值,不是隐式类型转化的值,但判断的是类型转换的值,还是进行boolen去隐式类型转化。
7、< 、> 、<= 、>= (大于号、小于号、大于等于号、小于等于号)
数字1大于字符串"2"吗?有数字相比较的就会隐式类型转化成数字
var demo = 1 > "2"; console.log(typeof(demo) + ": " + demo); // boolean: false
字符串"3"与字符串"2"比较,这个没有类型转换,字符串和字符串比,比较的是ASCII码顺序
var demo = "3" > "2"; console.log(typeof(demo) + ": " + demo); // boolean: true
但是字符串"3"和数字2比较,字符串和数字比就把字符串会转化成数字了,调用Number转换成数字
var demo = "3" > 2; console.log(typeof(demo) + " : " + demo); // boolean : true
8、==、!= (等号和非等号 )
数字1 == 字符串"1" 吗?这里也有隐式类型转化,它是相等的
var demo = 1 == "1"; console.log(typeof(demo) + ": " + demo); // boolean: true
数字1等于布尔值true吗,它们是相等的,有隐式类型转化
var demo = 1 == true; console.log(typeof(demo) + ": " + demo); // boolean: true
非等于(不等于)也一样,有隐式类型转化
var demo = 1 != true; console.log(typeof(demo) + ": " + demo); // boolean: false
9、看几个特殊的
false > true 会转换成数字 0 > 1
var demo = false > true; console.log(typeof(demo) + ": " + demo); // boolean: false
2 > 1 > 3
1. 2 > 1 结果是true
2. true > 3 转成 1 > 3
var demo = 2 > 1 > 3; console.log(typeof(demo) + ": " + demo); // boolean:false
2 > 3 < 1
var demo = 2 > 3 < 1; // false > 3 // 0 < 1 console.log(typeof(demo) + ": " + demo);//boolean: true
10 > 100 > 0
var demo = 10 > 100 > 0; //false > 0 //0 > 0 console.log(typeof(demo) + ": " + demo); // boolean: false
100 > 10 > 0
var demo = 100 > 10 > 0; // true > 0 // 1 > 0 console.log(typeof(demo) + ": " + demo); // boolean: true
上面这些是挨个算的,先算前面的结果得true或false,再和后边的在比,挨个来比
10、下面看几个最好玩的
undefined不大于0,不小于0,不等于0
var demo = undefined > 0; console.log(demo); // false var demo = undefined < 0; console.log(demo); // false var demo = undefined == 0; console.log(demo); // false
然后null不大于0,不小于0,不等于0
var demo = null > 0; console.log(demo); // false var demo = null < 0; console.log(demo); // false var demo = null == 0; console.log(demo); // false
null和undefined很像,他俩是相等的,这是隐式类型里面最特殊没有规则的,系统就这么规定的用Number解释不了
var demo = null == undefined; console.log(demo); // true
唯一自己都不等于自己的就是非数,NaN连自己都不等于自己,它就不可能等于任何东西
var demo = NaN == NaN; console.log(demo); // false
==(等于)有隐式类型转换有时候对我们是很不利的,比如字符串"1"和数字1是相等的,形式上是不等的,这样会造成误差,有没有不发生类型转换的?
11、绝对等于"==="、绝对不等于"!=="
不发生类型转换的绝对等于"===" 和绝对不等于"!=="
===三个等号叫绝对等于,数字1绝对等于数字1吗?绝对等于
var demo = 1 === 1; console.log(demo); // true
数字1绝对等于字符串"1"吗?不等于
var demo = 1 === "1"; console.log(demo); // false
数字1绝对不等于字符串"1"吗?绝对不等于
var demo = 1 !== "1"; console.log(demo); // true
数字1绝对不等于数字1吗?等于自己
var demo = 1 !== 1; console.log(demo); // false
这次左右两侧不发生类型转换,差一点都不行。
但是NaN在任何一种情况它都不等于自己,这是一个特例
var demo = NaN === NaN; console.log(demo); // false
12、再说一个特殊的
如果变量a没定义就访问肯定报错
// var a; console.log(a); // Uncaught ReferenceError: a is not defined
有一种级特殊的情况是不报错的,把未定位的变量放到了typeof a里面是不报错的,并打印出值 undefined
// var a; console.log(typeof(a)); // undefined
看下面 typeof(typeof(a))返回什么?里面的结果返回undefind,然后 typeof undefined ,考的是typeof返回的结果是什么类型,返回的是字符串"undefined"
console.log(typeof(typeof(a))); // string
一般笔试题会这样考,第一个typeof返回的是undefined,返回的是字符串的"undefined"
console.log(typeof(typeof(undefinede))); // var demo = typeof(undefinede); // 里面 // console.log(typeof(demo) + " : " + demo); // 外边
typeof返回的六种类型都是字符串类型
五、作业练习
01/
console.log(typeof(a)); // 返回结果是字符串类型的"undefined" console.log(typeof(undefined)); // 返回的也是字符串类型"undefined" console.log(typeof(NaN)); // number console.log(typeof(null)) // 历史遗留问题返回 object
02/
var a = "123abc"; console.log(typeof(+a)); // 一元正负运算符给它隐式类型转换成数字,不管能否转换成正式的数字反正是数字类型,转换完是NaN打印出来是number console.log(typeof(!!a));// bollen类型 console.log(typeof(a + "")); // a加空串转换字符串类型string
03/
console.log(1 == "1"); // 有隐式类型转换的等于,相等返回true console.log(NaN == NaN); // NaN不等于任何东西返回false console.log(NaN == undefined); // 都说NaN不等于任何东西了返回 false
04/
console.log("11" + 11); // 打印的是四个一 "1111" 千万不能是22 console.log(1 === "1"); // false
05/
console.log(parseInt("123abc")); // parseInt有截断数字的作用返回123
06/
toFixed是科学计数法保留几位有效数字, 123123.345789..toFixed(3) 参数放3就保留3位有效数字,并且四舍五入123123.346
var num = 123123.345789; console.log(num.toFixed(3)); // 参数放3就保留3位有效数字并且四舍五入123123.346
07/
typeof(typeof(a)) 第一点考的是未经声明使用的变量a,这种情况是唯一不报错的情况,然后返回一个字符串"undefined",字符串的"undefined"再typeof字符串"undefined"返回string
console.log(typeof(typeof(a))); // string
08/
+ 200 + "3" 变成字符串
-*、% "200" - 3 变数字
>< "2" > 1 转换数字
!取反 !"ok" 转布尔值
!100
== "2" == 2 转字符串
===