您的位置:首页 > Web前端 > JavaScript

JavaScript中的隐式类型转换

2015-07-11 22:03 567 查看
版权声明:本文为博主原创文章,如需转载请注明出处。 https://blog.csdn.net/vv314/article/details/46845113

数据类型

JavaScript有五种基本类型(primitive type):

null
undefined
boolean
string
number
,一种引用类型:
object
。可以通过
typeof
操作符来判断数据类型。由于js是弱类型语言,变量类型可在运行时动态改变。当使用运算符操作不同类型的数据时,js将自动转换为同一类型进行计算,因为这一过程是透明的、不易察觉的,因而也称作隐式类型转换。

typeof result
11 number
NaN number
“11” string
true boolean
undefined undefined
null object
{} object
[] object
/\d/ object
function() {} function

注意当

typeof
操作符对
null
,对象,数组,正则表达式的判断结果均为
object

Number数值转换

上边提到JavaScript有五种基本数据类型,其中

string
number
boolean
类型分别有着对应的包装类型
String
Number
Boolean
。包装类型对象将在读取基本类型变量值的时候在后台被创建,读取后被立即销毁。
js中各种操作符引起的类型转换,通常是将其他类型转换为数值类型的操作。这就不得不要提到
Number()
构造器的转换规则:

  • 如果是
    Boolean
    值,
    true
    转换为1,
    false
    转换为0。
  • 如果是
    null
    ,返回0。
  • 如果是
    undefined
    ,返回
    NaN
  • 如果是字符串,遵循以下规则:
    字符串为纯数字,转换为十进制数值;
  • 字符串为浮点数,转换为对应浮点数值;
  • 字符串为16进制数值,如
    "0xf"
    ,转换为对应10进制数值;
  • 空字符串,转换为0;
  • 包含字母等其他字符,返回
    NaN
  • 如果是对象,则调用对象的
    valueOf()
    方法,然后依照前面规则转换返回的值。如果转换结果为
    NaN
    ,则调用对象的
    toString()
    方法,然后再依照前面的规则转换返回的字符串值。
  • 隐式类型转换

    alert()
    方法接收字符串参数,将会在后台调用参数对象或其包装对象的
    toString()
    方法。

    alert(100) // '100' -> Number(100).toString() -> '100'

    算数操作符

    ++,–

    • 操作数为纯数字字符串,字符串被转换为数值后操作。
    • 操作数包含非数字字符串,返回
      NaN
    var a = "10",
    b = "hello";
    console.log(typeof a++);    // number
    console.log(typeof --a);    // number
    console.log(b++);           // NaN

    +,-,*,/

    • 字符串与数字相加,数字转字符串,返回字符串拼接结果。
    • -
      *
      /
      ,操作数包含纯数字字符串,转换为数值后操作;否则返回
      NaN
    • 一元加(
      +
      )减(
      -
      )操作符相当于调用
      Number()
      构造器进行转换。
    + "5";           // 5
    - "5";           // -5
    + new Date();    // 1436700521490,new Date().valueOf()
    
    10 + "5";        // "105"
    "5" + 10;        // "510"
    
    "10" - "5";      // 5
    10 - true;       // 9
    "5" - [10];      // -5
    10 * "5";        // 50
    10 * "5s";       // NaN
    10 / "";         // Infinity

    逻辑操作符

    • 逻辑非将操作数转化为
      boolean
      值,并取反。可使用
      !!
      模拟
      Booelan()
      转型。
    • if()
      while()
      等语句中,条件参数将被转换为
      boolean
      型:正数,非空字符串,对象返回
      true
      ,其余操作数返回
      false
    !! (Boolean()) result
    1 true
    {} true
    “hello” true
    0 false
    “” false
    null false
    undefined false
    NaN false

    关系操作符

    ==,<,>,<=,>=

    这些都属于二元操作符,同类型情况下的比较不再赘述。需要注意的是字符串间的大小比较是基于每一位字符的字符编码比较。对于不同的数据类型,实际上都其将转换为数值作为中间类型相比较:

    • 字符串和数值比较,字符串转数值。
    • 有操作数是布尔值,布尔值转数值。
    • 对于相等性(
      ==
      )比较,
      undefined
      等于
      null
      ,不能将它们转换为其他值。
    • NaN
      不等于任何值,包括
      NaN
      本身。
    • 有一个操作数是对象,则调用对象的
      valueOf()
      方法,按基本类型值进行比较。如果对象没有
      valueOf()
      方法,则调用
      toString()
      方法对转换结果执行比较。

    先来看大小比较:

    10 > 5;           // true
    10 > "5";         // true
    true > false;     // true,1 > 0
    
    "Abc" > "abc";    // false,字符编码比较"A":65 < "a":97
    "10" > [5];       // false,[5] -> "5",字符编码比较"10" < "5"

    再来看相等比较:

    '0' == 0;            // true
    '0' == false;       // true
    
    undefined == null;    // true
    null == false;       // false
    undefined == false;  // false
    
    NaN == NaN;          // false
    NaN == false;        // false
    
    0 == [];             // true,Number([]) -> 0
    0 == {};             // false,Number({}) -> NaN

    引用类型的转换

    回顾前面的例子可以发现,基本数据类型与数值类型间的数据转换,近似于将待转换类型作为参数传入

    Number()
    构造函数,生成一个新数值型实例的过程。
    if()
    while()
    等语句中,若单独以引用类型作为条件参数,均返回
    true
    。而在其他的比较中,则常常将引用类型转换为基本数值比较。在前面的例子中大家也许会对包含数组的比较存在疑惑,接下来我们就一起剖析一下它们内在的转换过程。
    首先来看关于引用型操作数的转换规则:

    如果有一个操作数是对象,则调用对象的

    valueOf()
    方法,按基本类型值进行比较。如果对象没有
    valueOf()
    方法,则调用
    toString()
    方法对转换结果执行比较。

    这里提到两个关键方法:

    valueOf()
    toString()
    。在JavaScript中这两个方法默认继承自
    Object
    对象,并由它们当前所在对象的原型方法重写,还可被用户自定义的同名实例方法覆盖。

    valueOf()

    JavaScript调用

    valueOf()
    方法将一个对象转换为原始类型(基本类型)值,通常我们不必显式的调用它,因为当遇到一个存在原始值的对象时,JavaScript将会自动调用他它的
    valueOf()
    方法读取原始值。

    一般的,基本类型值的包装类型对象均包含原始值,也就是基本类型值本身。

    var boo = new Boolean(true);
    num = new Number(10);
    str = new String("hello");
    boo.valueOf();      // true
    num.valueOf();      // 10
    str.valueOf();      // "hello"

    对于没有原始值的对象,调用

    valueOf()
    方法返回对象本身。

    /\d/.valueOf();                     // /\d/
    /\d/.valueOf() instanceof RegExp;   // true
    [1, 2].valueOf();                   // [1, 2]
    [1, 2].valueOf() instanceof Array;  // true
    [1, 2].valueOf()[1];                // 2

    toString()

    每个对象都有一个

    toString()
    方法,当对象要表示为文本值或被指定为字符串形式时,
    toString()
    方法将自动被调用。默认的,
    toString()
    继承自object对象。如果这个方法没有在自定义对象中被重写,
    toString()
    将返回“
    [object type]
    ”,其中
    type
    表示对象类型。

    在JavaScript的几个内置对象中,大多都重写了

    toString()
    方法。
    String
    Number
    Boolean
    对象调用
    toString()
    返回基本类型值的字符串形式,
    RegExp
    对象返回表达式字面量。

    var boo = new Boolean(true);
    num = new Number(10);
    str = new String("hello");
    boo.toString();     // "true"
    num.toString();     // "10",Number的toString()方法可接收一个参数,表示进制
    str.toString();     // "hello"
    /\d/.toString();    // "/\d/"

    Array
    对象也重写了
    toString()
    方法,它将会调用数组每一项的toString()方法,最后返回由每一项值的字符串形式拼接而成的一个以逗号分隔的字符串。

    typeof [1].toString();  // string
    [1,2,3].toString();     // "1, 2, 3"
    [].toString();          // ""

    我们再来回顾之前的例子:

    "10" > [5];     // false

    分析这条语句,有一个操作数是对象,先将对象转换为基本类型值。对象为数组类型,则调用数组的

    toString()
    方法,之后根据再关系操作符转换规则进一步转换,以下为分解步骤:

    "10" > [5]              // 原式
    "10" > [5].toString     // 调用数组toString()方法
    "10" > (5).toString()   // 对数组每一项调用toString()方法
    "10" > "5"              // 原式转化为两个字符串间的比较
    "10".charCodeAt(0) > "5".charCodeAt(0)  // 比较每一位的字符编码
    49 > 53                 // 原式转化为两个数值间的比较
    true                    // 返回结果

    类似的,

    true
    [1,2]
    之间的比较将转换为数值
    1
    和字符串
    "1,2"
    的比较,字符串
    "1,2"
    将进一步转换为数字:
    Number("1,2") -> NaN
    ,最终便转换为
    1
    NaN
    的比较。

    自定义对象

    自定义对象将继承

    object
    valueOf()
    toString()
    方法。默认的,
    valueOf()
    返回对象本身,
    toString()
    返回
    "[object Object]"

    可以在对象中重写继承来的
    valueOf()
    toString()
    方法,重写后的调用规则为:首先检查
    valueOf()
    是否被重写,是则调用重写后的方法,否则继续检查
    toString()
    是否被重写,是则调用重写后的方法,否则按照普通对象的规则调用默认方法。

    var obj = {name:"Lee"};
    obj.valueOf = function (){ return 1;};
    obj.toString = function (){ return this.name;};
    
    obj + 1;            // 2, 重写的valueOf()先被调用
    delete a.valueOf;   // 删除自定义的valueOf()
    obj + 1;            // "Lee1", 调用重写的toString()

    最后,关于引用类型之间的比较,比较的是内存地址,不再赘述。

    var a = [];
    var b = [];
    var c = a;
    a == b;     // false
    a == c;     // true

    显式转换

    string
    number
    boolean
    之间的显示转换,直接调用转型方法或构造函数进行转换。

    转字符串

    • 使用
      String()
      构造函数
    • 调用对象的
      toString()
      方法
    • 使用”
      +
      “号操作符
    String(true);       // "true"
    (10).toString();    // "10"
    true.toString();    // "true"
    10 + "";            // "10"

    转数值

    • 使用
      Number()
      构造函数
    • 使用
      window.parseInt()
      方法
    • 使用一元”
      +
      “操作符
    Number("10");       // 10
    parseInt("10a");    // 10
    + true;             // 1
    + undefined;        // NaN
    + null;             // 0

    转Boolean值

    • 使用
      Boolean()
      构造函数
    • 使用”
      !!
      “操作符
    Boolean("");    // false
    Boolean(1);     // true
    !!undefined;    // false
    !!null;         // false
    !!"hello";      // true
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: