【You Don't Know JS: Types & Grammar】Chapter 4-1 笔记

转换值

将一个值从某个型别转换至另一个型别的动作,叫做「型别转换(type casting)」。

因为值的使用规则而被迫转型的,叫做「强制转型(coercion)」。

JS强制转型(coercion)的结果永远都会是纯量的基型值。

明确的强制转型:能够从程式码看出型别转换动作是刻意进行的。

隐含的强制转型:型别转换因其他作业而产生较不明显的副作用。

http://img2.58codes.com/2024/20112573JEs3X1v4me.jpg

执行b = a + "",由于+的运算子,其中一个运算元是string的话,那这个运算式就会执行string的串接动作,而(隐藏)的副作用,就是会将42(number)转换成"42"(string)

至于c = String( a ),则是很明显地将a的值明确地换成string

以上2者都可以达到相同的效果:42(number)转换成"42"(string)

如果你很清楚执行b = a + ""的结果,那这个执行对你来说,是「明确」的;但不清楚c = String( a )的结果,这个执行则算是「隐含」的。

要记住的一点是,我们撰写的程式码,很少是给自己看的。就算已经是专家等级了,但还是得考虑到团队成员的程度,对他们来说,你的「明确」与「隐含」是否是他们能理解的呢?

ToString

将任何非string值强制转型成string表示值。

基型值的转型:null=>"null"undefined=>"undefined"true=>"true"

如果物件本身拥有自己的toString( )方法,而这个物件被当作string使用,那它的toString( )就会被自动呼叫。

array的toString( )结果:
http://img2.58codes.com/2024/20112573jzRvDTTdyO.jpg
输出string,每个值都以" , "隔开。

ToNumber

如果有任何非number值被当作number值来使用,就会进行转换,例如数学运算。

基型值的转型:tru1=>1undefined=>NaN、但是null=>0

object和array会先转成他们的基型等效值,如若不是一个number值,会再次转型为number值。

再转型之前,JS会先确认目标值是否有valueOf( )方法,若有且回传基型值的话,那个值就会被用于强制转型;如果没有valueOf( )方法,会使用toString( )方法(如果有的话)。

如果以上2种执行都无法提供基型值的话,就会掷出TypeError。

ToBoolean

在其他程式语言中,1与0分别代表true与false,但在JS中number就是number,boolean就是boolean。可以把1强制转型成true,0强制转型成false(反之亦然),但实际上,他们并不相同。
1并不等于true,0也不等于false。

Falsy值

JS所有的值可以被分为2种:被强制转型为boolean型别后,不是true就是false。

会被称为「falsy(假值的)」的值:

undefinednullfalse+0、-0、NaN" "

以上的值,如果转型成boolean会成为flase。

如果某个值不在这清单上,那已较合乎逻辑的想法,我们可以判定它就在另一个清单「truthy」上。

Truthy值

http://img2.58codes.com/2024/201125735SGWSyYX4J.jpg

d的结果为true。请注意,以上的值虽然乍看之下会转为false,但实际上,它们的型别都是string,既然如此,结果当然为true。

http://img2.58codes.com/2024/20112573WoIZq0HNJt.jpg

d的结果仍为true。切记,只要是没在falsy清单的值,都为truthy值。

truthy与flasy的重要性在于,一个值转型成boolean时,会有怎样的行为。

明确转型:Strings <--> Numbers

直接看範例:
http://img2.58codes.com/2024/20112573uyLdnkkSaj.jpg
String( )方法会把任何值强制转型成string,Number( )方法则是会把任何值强制转型成number。

以上的方式之所以称为「明确转型」,是因为可以从程式码很明显的看出执行作业的结果。

除了上述的方式之外,也有其他方式能进行「明确转型」:
http://img2.58codes.com/2024/20112573LSgZKIYM2o.jpg

执行a.toString( ),从表面看来,toString( )是执行了「明确转型」,但这里有个「隐含转型」的存在。toString( )是个方法,所以无法用在像是42这种基型值上。JS会自动地把42「封装」在一个物件包裹器(object wrapper)之中,如此一来,便具有object的行为了,就能呼叫toString( )

至于+c,这个看起来很特别的运算式,只有单一运算元的运算子,不会执行数学运算或string的串接。+运算子会明确地把它的运算元转型成number值。

http://img2.58codes.com/2024/20112573RwRV9HHMka.jpg
-运算子也会像+一样转型,但它会反转数值的正负号。且我们不能把2个相邻的符号放在一起(--),这样会被解读为递减运算子,应该要在中间加上空格,- -"3.14"

http://img2.58codes.com/2024/20112573fQP79L14Wz.jpg

如果会与其他运算子紧密相邻,应该就要避免使用单一运算子的方式来进行强制转换,以免造成混淆。

日期转数字

单一+运算子的另一个用途是将Date object强制转型成number,结果会是那个日期时间值的unix时间戳(从1970年1月1日 00:00:00 UTC 开始,所经过的毫秒数)。

取得当下的时间戳:
http://img2.58codes.com/2024/20112573Vw05mkommg.jpg

有2种非强制转型的方式:
http://img2.58codes.com/2024/201125737WnG7ytJZX.jpg
以及ES5新增的,建议使用
http://img2.58codes.com/2024/20112573A8y7E8uxXs.jpg

明确地:剖析数值字串

将一个string的内容剖析出number的动作,可以达成类似将string强制转换成number的效果,但这种执行与之前讨论的string转型成number还是有所差异。
http://img2.58codes.com/2024/20112573BduRfLTuoa.jpg

剖析数值的动作能够接受非数值字元,从左至右剖析,遇到非数值字元便会停止,输出剖析成功的数值。

强制转型无法接受任何非数值字元,转型会失败,产生NaN。

如果对于剖析的对象并无要求是否全部为数值,可以使用parseInt( ),但若只能接受数字,譬如"42px"不该视为数字的话,那就使用强制转型。

parseInt( )只能用于string值。如果传入一个非string值,该值会先被强制转型为string,这是一种隐含地强制转型,这是不好的,请避免这种行为。

明确地:* --> Boolean

使用Boolean( )进行强制转型:
结果为true
http://img2.58codes.com/2024/20112573w2uPbWDFyV.jpg

结果为false
http://img2.58codes.com/2024/20112573j6z647zhfe.jpg

虽然Boolean( )可以明确地转型,但并不普遍。

如同+运算子一样,!也会强制地将某个值转型成反向的Boolean值,因此我们会使用!!双否定运算子再做一次反向。

http://img2.58codes.com/2024/20112573q29DznyRXQ.jpg

if(...)叙述式,会强制将值转换为boolean。

http://img2.58codes.com/2024/20112573poccwCehPg.jpg

上面为三元运算子(ternary operator),会依据a的boolean值,判断指定true或false给b。

表面看起来是明确地强制转换,但实际上,a运算式会隐含地强制转型成boolean,才能进行判断。

就明确转型来说,Boolean(a)!!a都是比较好的选择。

参考来源:
http://img2.58codes.com/2024/201125739FY75WdXxA.jpg

此为You Don't Know JS系列的笔记。


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章