wns9778.com_威尼斯wns.9778官网

热门关键词: wns9778.com,威尼斯wns.9778官网
wns9778.com > 计算机教程 > 【wns9778.com】JavaScript 那些不经意间发生的数据类

原标题:【wns9778.com】JavaScript 那些不经意间发生的数据类

浏览次数:62 时间:2019-05-10

  JavaScript可以自由的进行数据类型转换,也提供了多种显式转换的方式。但是更多的情况下,是由JavaScript自动转换的,当然这些转换遵循着一定的规则,了解数据类型自由转换的规则是非常必要的。再次翻阅犀牛书后有了一些总结,与大家分享,有不严谨地方,望指正!

Javascript数据类型转换规则

前言

 

Javascript有7种数据类型,包括5种原始类型(也叫原始值)number、Boolean、string、null、undefined和2种复合类型object、array,它们之间可以根据某种规则相互转换。《Javascript权威指南》列出了在Javascript中如何进行类型转换,

 

 

 

其中原始值之间的转换没什么可说的,记住就好了,我们要关注的是复合值(即对象)与原始值之间的转换。原始值转换成对象直接调用Object()方法即可(null和undefined不可调用该方法),而对象转换成原始值呢?如空数组[]转换成数字为什么是0呢?

 

对象转换成原始值

 

对象转换成布尔值:所有对象转换成布尔值都是true,包括包装对象new Boolean(false)转换成布尔值也是true。

 

对象转换成字符串:如果对象有toString()方法,则调用这个方法,如果它返回原始值,将原始值转换成字符串后返回;如果对象没有toString()方法或调用toString()方法方法返回的不是原始值,则调用valueOf()方法,然后将valueOf()方法返回的原始值转换成字符串返回,如果valueOf()方法返回的还不是原始值,没救了,浏览器只好抛出类型异常的错误。

 

对象转换成数字:和对象转换成字符串过程类似,只不过先调的是valueOf()方法。

 

根据以上规则就可以知道为什么空数组转换成数字结果是0了:空数组先调用了valueOf()方法,返回了“”字符串,“”字符串是个原始值,再根据上面的表格,“”字符串转换成数字0。

 

隐式类型转换

 

来看一个例子:

 

"123" == 123

 

 

大家都知道结果是true,==运算符两边的操作数属于不同的数据类型,要判断是否相等,需要经过隐式类型转换成相同的数据类型才行。然而,是运算符左边的“123”转换成了数字123还是运算符右边的123转换成了字符串“123”呢?

 

规则是:

 

如果一个值是null,另一个是undefined,那么它们相等

如果一个值是数字,另一个是字符串,先将字符串转为数字再比较

如果其中一个值是true,将true转为1再比较,同理false转换成0再比较

如果一个值是对象,另一个是数字或字符串,则将对象转换成原始值再进行比较(日期对象转换成字符串,其它对象先尝试调用valueOf()方法再尝试使用toString())

其它不同类型的比较都不相等

显然上面的例子属于第二种情况,“123”被隐式转换为123了。

 

除了==运算符,诸如 、-、*、/、!、<、<=、>、>=等运算符两边的操作数类型不同时,都会发生隐式类型转换,还包括while()语句和if()语句内的条件语句,alert()语句会将()内的值隐式转换成字符串后再弹出。 

 

“ ”运算符

 

 二元加法运算符“ ”可以对两个数字做加法,也可以做字符串连接操作:

 

1 1               // 2

"hello" "world"   // "hello world"

 

 

当二元加法运算符“ ”遇到下面的运算时操作数会如何转换呢?试着想想答案再往下看

 

1 true

"1" true

1 "1"

{} 1

{} {}

 

 

隐式转换规则:

 

如果其中一个操作数是对象,对象会转换成原始值:日期对象通过toString()方法转换,其他对象通过valueOf()方法转换,如果valueOf()返回值不是原始值再使用toString()方法转换。

在进行了对象到原始值的转换后,如果其中一个操作数是字符串的话,另一个操作数也会转换为字符串,然后进行字符串拼接。

否则,两个操作数都将转换为数字(转换不了的将转换为NaN),然后进行加法操作。

根据规则,以上的例子结果是:

 

1 true       // true转换为1,然后加法得出结果2

"1" true     // true转换为"true",然后字符串拼接得出结果"1true"

1 "1"        // 数字1转换为"1",然后字符串拼接得出结果"11"

{} 1         // {}对象调用toString()方法转换为字符串"[object Object]",变成了"[object Object]" 1,匹配第二条规则,1将转换为字符串"1",然后字符串拼接得出结果"[object Object]1"

{} {}        // 自己想想过程吧

 

wns9778.com, 

当“ ”做为一元运算符时,会把操作数转换为数字(转不了的转成NaN)

 

“-”运算符

 

当“-”做为二元运算符时,会把操作数转换为数字(转不了的转成NaN) 

 

当“-”做为一元运算符时,会把操作数转换为数字(转不了的转成NaN),同时改变运算结果的符合 

 

比较运算符(">"、">="、"<"、"<=")

 

比较操作符的操作数可能是任意类型,然而只有数字和字符串才能真正执行比较操作,因此其它类型的操作数都将进行类型转换,具体规则如下:

 

如果操作数为对象,那么这个对象将转换为原始值:同上,日期对象通过toString()方法转换,其他对象通过valueOf()方法转换,如果valueOf()返回值不是原始值再使用toString()方法转换。

在对象转换为原始值后,如果两个操作数都是字符串,将依次比较每个字符串的Unicode大小。

在对象转换为原始值后,如果至少有一个操作数不是字符串,那么两个操作数都将转换为数字进行比较,如果其中某个操作数无法转换为数字,这个操作数将转换为NaN,比较结果为false。

"*"、"/"、"%"、"!"

 

 "*"、"/"、"%"会把操作数转换为数字(转不了的转成NaN) 

 

"!"会把操作数转换为布尔值

http://www.bkjia.com/Javascript/1030474.htmlwww.bkjia.comtruehttp://www.bkjia.com/Javascript/1030474.htmlTechArticleJavascript数据类型转换规则 前言 Javascript有7种数据类型,包括5种原始类型(也叫原始值)number、Boolean、string、null、undefined和2种复合类型obje...

数据类型

  聊到数据类型转换,就不得不提到JavaScript的数据类型:原始类型(Number , String , Boolean , undefined ,  null ,  Symbol),对象类型 (Object)。当然Object有可以细分出 Array , Date , RegExp等对象。

  既然分为这么多种数据类型,每种数据类型肯定会有特定的用途,那么当提供的值的数据类型与预期不符时要怎么办呢,比如我需要在控制语句中使用到 boolean 值,提供的值却是 string 。当然我们可以显式转换 Boolean( a : string) ,但是根据日常经验,我们知道其实不需要这么复杂,可以在控制语句中直接用这个string类型的变量 ,也可以达到预期的效果。如下:

wns9778.com 1

 

可见自动转换方便很多,但是在这个过程中到底是按照什么规则处理的呢?

自动转换

   什么时候会发生自动转换呢 ?

    犀牛书上是这样描述的: 当JavaScript期望使用一个布尔值的时候,你可以提供任意类型值,JavaScript将根据需要自行转换类型。一些值(真值)转换为true , 一些值(假值)转换为false 。这在其他类型中同样适用:如果JavaScript期望使用一个字符串,它把给定的值转换为字符串。如果JavaScript期望一个数字,它把给定的值转换为数字(如果转换结果毫无意义的话,将会返回NaN)。

    简而言之就是:JavaScript有一些语句/运算符对数据类型有要求,但我们提供的与预期不符时,就会发生自动类型转换。

  对数据类型有期待的语句和表达式:

    1、期待boolean类型的 : if 语句 、 do while 语句 、 while do 语句 、 &&  ||   ! (与或非逻辑表达式)  、 ? : ( 三目运算符)

    2、期待number类型的 :   - * / % (算数运算符) 、    --  (增量/减量运算符) 、 > 、  >= 、 <  、 <= 数字比较

    3、期待字符串的: (字符串连接) 、 > 、  >= 、 <  、 <=  字母排序比较

    4、特殊的 : ==  、 !=  (不)相等运算符,在检测两个操作数是否相等时,会进行类型转换;(注意 :  === 、!==  是(不)严格相等运算符,是不会进行类型转换的)

  需要说明的是,1中当然可以传入表达式,但是表达式返回的结果也肯定会返回boolean类型的值,或者返回值被转换为boolean;2和3有一些重复的运算符 : 、 > 、  >= 、 <  、 <= ,这些运算符在不同场景下发生自动转换的时候,会有不同的优先级。有如下场景:

//   的场景    有两种作用:算数运算和字符串连接。所以期待的是数字和字符串!
// 1、两个操作数同为数字,或者同为字符串,不需要进行转换
    1   1   // 2  
    '1'   '1'  // '11'  
// 2、有一个操作数是字符串,则另外一个也会转换为字符串
    '1'   1   // "11"
    '1'   null   //  "1null"
    '1'   {}   //  "1[object Object]"
    '1'   new Date()  //  "1Wed Jun 20 2018 11:49:55 GMT 0800 (中国标准时间)"
// 3、如果有一个操作数是对象的话,会转化为原始值(除了Date对象是调用toString()方式转换 , 其他对象都会调用 valueOf() 进行转换 , 但是由于多数对象只是简单的继承了valueOf() , 只会返回对象,而不是一个原始值,所以会再调用toString进行转换) , 所以这里可以简单的理解为:都会转换为字符串 。 另一个操作数也会转换为字符串
    1   {}   // "1[object Object]"
    1   new Date()  //  "1Wed Jun 20 2018 11:56:56 GMT 0800 (中国标准时间)"
    1   []   //  "1"
// 4、 其他情况都会转换为数字
    1   null  // 1
    1   undefined   // NaN

  从例子中可以看到, 的转换其实是优先转换为字符串的,如果操作数中又字符串或者对象(对象在这里会转换为字符串),则会按照 字符串连接进行操作的。从例子的第3个可以看到,第一个操作数都是数字,但是会转化为字符串。例子中的第4个,没有对象和字符串,null 和 undefined 都转换为 数字进行算数运算,其中undefined -> number 会返回 NaN , 所以计算结果为NaN。

  “ ”还有特殊的用法,就是转换为数字,如下。会将 后的操作数转换为数字,具体的转换规则后续会说明。

  null   //  0
  undefined  //  NaN
  {}  //  NaN
  new Date()  //  1529467646682
  ["5"]  //  5
  "4"  //  4

   > 、  >= 、 <  、 <=  这些比较运算符的规则和 类似,不过是会优先转换为数字进行比较。

// 作用 : 比较数值大小或者再字母表中的位置。也是期待数字和字符串!
1、两个操作数中只要有一个不是字符串,则两个值都转为数字
 "3" > "11"    //  true   字符串比较
  3 > "11"      // false   11 转换为数字
 true > '0'    // true true 和 ‘0’ 都转换为数字 
2、对象同样会转换为原始值(不过这里的Date对象也是优先调用valueOf ,返回的是毫秒数,其他的和上述   的一样),如果转换后有一个字不是字符串,则两个值也都需要转换为数字
    1000 > new Date()  // false
    100000000000000000000000 > new Date()  //  true   date对象转换为数字
    "100000000000000000000000" > new Date()  //  true  左值也随着 date对象一起转换为数字
    '11' > ["3"]  //  false  数组转为字符串,所以这里是字符串比较

   这里需要注意的是,只要在转换为数字的过程中,有一个值是NaN,那么比较的结果肯定是false。

   == 、 !=  (不)相等运算符是不严格的比较,所以,如果两个操作数不是同一类型,那么会尝试进行一些类型转换,然后进行比较。有以下规则和类型转换:

  1、一个值是undefined,一个值是null,则相等

  2、一个值是数字,一个值是字符串,则字符串转换为数字进行比较

  3、true 和 false 会分别转换为 1 和 0 

  4、一个值是字符串或者数字,另一个是对象,对象转换为原始值(Date类只调用toString,其他的和之前的一致),然后进行比较。

  5、其他的比较,全是false。

null == undefined  // true  1
null == 0    //  false  5
1 == '1'  //  true   2
1 == true  //  true  3 
2 == true  //  false  3
1 == [1]  // true  4
'1' == ['1']  // true  4   数组转为字符串
1 == ['1']  //  true  4  数组转为字符串再转为数字

  

  还有一种自动转换也很容易被忽略,但是经常见到。那就是对象包装 

  思考一个问题,为什么数字是原始类型,却可以使用toString方法? 只有对象才会有方法的,为什么数字却可以使用。

 

let x = 1
x.toString()  //   "1"

 

  因为在x需要使用方法的时候,JavaScript会通过调用 new Number(x) 的方式将它暂时转换为对象,它继承了Number对象的方法,所以就可以调用toString了。同样的还有字符串、布尔值,也是通过各种的构造函数进行转换。这也是为什么undefined和null,不可以使用toString的原因,因为它们没有构造函数。

x = null
x.toString()
//VM289:1 Uncaught TypeError: Cannot read property 'toString' of //null
//   at <anonymous>:1:3
//(anonymous) @ VM289:1


x = undefined
x.toString()

//VM305:1 Uncaught TypeError: Cannot read property 'toString' of //undefined
//    at <anonymous>:1:3

  目前我所了解的自动转换就只有这么多,后续再继续补充。那么自动转换的过程中,又有哪些规则呢?

 

any -> boolean

  在其他类型的值转换为boolean是,只有这几个会转换为false,其他都是true : undefined 、 null 、 "" 、 0 、-0 、NaN。

Boolean(0)  //  false
Boolean("") //false
Boolean(NaN)  //false
Boolean(undefined)  //false
Boolean(null)  // false

// 空对象 空数组 空函数 都会true
Boolean({})  // true
Boolean([])   //true
Boolean(function () {})   // true

// 此时是一个boolean对象,而不是原始值,所以是true
Boolean(new Boolean(false))  // true

 

本文由wns9778.com发布于计算机教程,转载请注明出处:【wns9778.com】JavaScript 那些不经意间发生的数据类

关键词: wns9778.com

上一篇:wns9778.comJS基础——事件操作总结

下一篇:没有了