数据类型回顾——数据类型转换(显式和隐式)—JS学习笔记2015-6-3(第47天)

对于JS这种语言来说,因为它是一种动态类型语言,变量是没有类型的,可以随时赋予任意值。

但是,数据本身和各种运算是有类型的,因此运算时变量需要转换类型。

大多数情况下,这种数据类型转换是自动的,但是有时也需要手动强制转换。

首先看下强制类型转换(显式)

之前提到的Namber、parseInt、parseFloat 都是强制类型转换;

这里在看阮一峰博客(http://javascript.ruanyifeng.com/grammar/conversion.html#toc1)

Number方法的转换,这里再做下记录:

(1)原始类型值的转换规则

  • 数值:转换后还是原来的值。

  • 字符串:如果可以被解析为数值,则转换为相应的数值,否则得到NaN。空字符串转为0。

  • 布尔值:true转成1,false转成0。

  • undefined:转成NaN。

  • null:转成0。

(2)对象的转换规则

       对象的转换规则比较复杂。

  1. 先调用对象自身的valueOf方法,如果该方法返回原始类型的值(数值、字符串和布尔值),则直接对该值使用Number方法,不再进行后续步骤。

  2. 如果valueOf方法返回复合类型的值,再调用对象自身的toString方法,如果toString方法返回原始类型的值,则对该值使用Number方法,不再进行后续步骤。

  3. 如果toString方法返回的是复合类型的值,则报错。

也提到了2种妙味课堂老师暂时没提到的方法:

String函数:强制转换成字符串

(1)原始类型值的转换规则

  • 数值:转为相应的字符串。

  • 字符串:转换后还是原来的值。

  • 布尔值:true转为“true”,false转为“false”。

  • undefined:转为“undefined”。

  • null:转为“null”

(2)对象的转换规则

    如果要将对象转为字符串,则是采用以下步骤。

  1. 先调用toString方法,如果toString方法返回的是原始类型的值,则对该值使用String方法,不再进行以下步骤。

  2. 如果toString方法返回的是复合类型的值,再调用valueOf方法,如果valueOf方法返回的是原始类型的值,则对该值使用String方法,不再进行以下步骤。

  3. 如果valueOf方法返回的是复合类型的值,则报错。

// String方法的这种过程正好与Number方法相反

还有阮老师也提到了,布尔值转换

Boolean函数:强制转换成布尔值

(1)原始类型值的转换方法

以下六个值的转化结果为false,其他的值全部为true。

  • undefined
  • null
  • -0
  • +0
  • NaN
  • ''(空字符串)

(2)对象的转换规则

所有对象的布尔值都是true,甚至连false对应的布尔对象也是true。

Boolean(new Boolean(false))
// true

请注意,空对象{}和空数组[]也会被转成true。

Boolean([]) // true

Boolean({}) // true




下面谈下隐式类型转换,或者说(js内部自动转换)
那么什么时候会发生隐式类型转换呢?

当遇到以下几种情况,JavaScript会自动转换数据类型:

  • 不同类型的数据进行互相运算;

  • 对非布尔值类型的数据求布尔值;

  • 对非数值类型的数据使用一元运算符(即“+”和“-”)。

首先妙味老师提到的集中隐式类型转换情况:

隐式类型转换:
+           200 + '3' 变成字符串
- * / %         '200' - 3 变成数字
++ --        变成数字
> <         数字的比较 、字符串的比较
! 取反            把右边的数据类型转成布尔值
==

// alert( Number('……') ); NaN
// alert( '……'-9 ); NaN


//NaN 数据类型转换失败的时候,会返回NaN;

// alert( '2' == 2 );

// alert('10'>9) 返回true, 此时是数字的比较
// alert( '10000000' > '9' ); 返回false,此时是字符串的比较,比较的是二者的编码;
// > < 是数字的比较与字符串的比较

// alert(!'ok'); 这时候返回false,为什么?
// 看了阮一峰的JS教程,我才明白,在预期为布尔值的地方,系统会自动调用内部的Boolean方法来转换
// Boolean方法 可以将任意类型的变量转为布尔值

另外需要一提的是 + 运算符,

有运算中存在a、 字符串的情况   // 两个运算子之中,只要有一个是字符串,则另一个不管是什么类型,都会被自动转为字符串,然后执行字符串连接运算

                 b、两个运算子都为数值或布尔值   //   这种情况下,执行加法运算,布尔值转为数值(true为1,false为0)

             C、运算子之中存在对象

                     运算子之中存在对象(或者准确地说,存在非原始类型的值),则先调用该对象的valueOf方法。如果返回结果为原始类型的值,则运用上面两条规则;否则继续调用该对象的toString方法,对其返回值运用上面两条规则。 (这一块暂时还不理解,等学到object之后再仔细研究)

关于两个等号的数值转换

详见司徒正美的博客:http://www.cnblogs.com/rubylouvre/p/3990290.html
另外为了避免这一问题的出现,大多数公司可能都要求,禁止使用双等号,直接使用三等号就好了
/*
这里说的隐性类型转换,是==引起的转换。

如果存在NaN,一律返回false
再看有没有布尔,有布尔就将布尔转换为数字
接着看有没有字符串, 有三种情况,对方是对象,对象使用toString进行转换;对方是数字,字符串转数字;对方是字符串,直接比较;其他返回false
如果是数字,对方是对象,对象取valueOf进行比较, 其他一律返回false
null, undefined不会进行类型转换, 但它们俩相等
这个顺序一定要死记,这是面试时经常问到的。

下面是一些杂题,自己做做

0 == undefined // false

1 == true // true

2 == {valueOf: function(){return 2}} // true

NaN == NaN // false

8 == undefined // false

1 == undefined // false

null == {toString: function(){return 2}} // false

0 == null // false

null == 1 // false



{ toString:function(){ return 1 } , valueOf:function(){ return [] }} == 1

*/

 

还有慕课老师PPT(帮助理解):

由于数据类型存在隐式转换,所以按照阮老师建议是:

由于自动转换有很大的不确定性,而且不易除错,建议在预期为布尔值、数值、字符串的地方,全部使用Boolean、Number和String方法进行显式转换

关于加、 减符号,慕课网《深入浅出javascript》当中也有提到

利用这种隐式转换的特性,如果我们想让那个一个变量的数据类型转换为数字,那么 num - 0 ; 此时这个num就是被隐式转换成了数字;

同理,想让一个变量的数据类型转换为字符串,那么 num + '' ;  变量加上一个空的字符串,此时num就被转换成了字符串

var num = 23; typeof(num + '')
"string"
var num = 'sg'; typeof(num-0)
"number"

写在最后:

tips:通过对比妙味课堂的视频和网上的一些教程内容(个人博客,阮一峰,司徒正美等)发现都没有全部包含了数据类型转换的所有情况,所有在学习JS的时候,还需要自己多看,多动手,这样才更加准确和深刻理解。

原文地址:https://www.cnblogs.com/zhangxg/p/4550658.html