你不知道的类型转换

栏目: JavaScript · 发布时间: 5年前

内容简介:相信我们在工作中经常会遇到类型转换的需求。但是类型转换也分为隐式强制类型转换”(implicit coercion)和“显式强制类型转换”(explicit coercion)。 例如:显式强制类型转换明确告诉我们哪里发生了类型转换,有助于提高代码可读性和可维 护性。 隐式强制类型转换则没有那么明显,是其他操作的副作用。尤其是 == 时,有时候我们就会迷糊,不知道过程中发生了什么,感觉上好像是显式强制类型转 换的反面,实际上隐式强制类型转换也有助于提高代码的可读性,今天我们就来讲一讲两种强制类型转换.显式强

相信我们在工作中经常会遇到类型转换的需求。但是类型转换也分为隐式强制类型转换”(implicit coercion)和“显式强制类型转换”(explicit coercion)。 例如:

var a = 42;
var b = a + ""; // 隐式强制类型转换 
var c = String( a ); // 显式强制类型转换
复制代码

显式强制类型转换明确告诉我们哪里发生了类型转换,有助于提高代码可读性和可维 护性。 隐式强制类型转换则没有那么明显,是其他操作的副作用。尤其是 == 时,有时候我们就会迷糊,不知道过程中发生了什么,感觉上好像是显式强制类型转 换的反面,实际上隐式强制类型转换也有助于提高代码的可读性,今天我们就来讲一讲两种强制类型转换.

显式强制类型转换

显式强制类型转换是那些显而易见的类型转换,旨在让代码更加清晰易读

字符串和数字之间的显式转换

var a = 42;
     var b = String( a );
     var e = a.toString();
     var c = "3.14";
     var d = Number( c );
     var f = +c;
     b; // "42"
     e; // ''42
     d; // 3.14
     f; //3.14
复制代码

toString()其中涉及隐式转换。因为 toString() 对 42 这样的基本类型值不适用,所以 JavaScript 引擎会自动为 42 创建一个封 装对象,然后对该对象调用 toString().

一元运算 + 被普遍认为是显式强制类型转换

显式解析数字字符串

解析字符串中的数字和将字符串强制类型转换为数字的返回结果都是数字。但解析和转换 两者之间还是有明显的差别.解析允许字符串中含有非数字字符,解析按从左到右的顺序,如果遇到非数字字符就停 止。而转换不允许出现非数字字符,否则会失败并返回 NaN

var a = "42";
     var b = "42px";
    Number( a );    // 42
     parseInt( a );  // 42
     Number( b );    // NaN
     parseInt( b );  // 42
复制代码

显式转换为布尔值

我们可以使用Boolean(..) 和!!,但是!!是我们会常用的。

var a = "0";
     var b = [];
     var c = {};
     var d = "";
     var e = 0;
     var f = null;
     var g;
     !!a; // true
     !!b; // true
     !!c; // true
     !!d; // false
     !!e; // false
     !!f; // false
    !!g; // false
复制代码

隐式强制类型转换

隐式强制类型转换指的是那些隐蔽的强制类型转换,副作用也不是很明显,会让代码变得晦涩难懂

字符串和数字之间的隐式强制类型转换

根据规范,如果某个操作数是字符串或者能够通过以下步骤转换为字符串 的话,+ 将进行拼接操作。如果其中一个操作数是对象(包括数组),则首先对其调用 ToPrimitive 抽象操作,该抽象操作再调用 [[DefaultValue]],以数字作为上下文。 如果 + 的其中一个操作数是字符串(或者通过以上步骤可以得到字符串), 则执行字符串拼接;否则执行数字加法

var a = 42;
     var b = a + "";
     b; // "42"
复制代码

这里有一个小差别需要注意:a + ""(隐式)和前面的String(a)(显式)之间有一个细微的差别需要注意。根据 ToPrimitive抽象操作规则,a + ""会对a调用valueOf()方法,然后通过ToString抽象 操作将返回值转换为字符串。而 String(a) 则是直接调用 ToString()。 例如:

var a = {
         valueOf: function() { return 42; },
         toString: function() { return 4; }
     };
     a + "";         // "42"
     String( a );    // "4"
复制代码

如果执行-操作,它们首先被转换为字符串(通过toString()),然后再转换为数字。

var a = [3];
     var b = [1];
    a - b; // 2
复制代码

布尔值到数字的隐式强制类型转换

以下情况中,非布尔值会被隐式强制类型转换为布尔值,遵循前面介绍过的 ToBoolean 抽 象操作规则 (1)if (..)语句中的条件判断表达式。 (2)for ( .. ; .. ; .. )语句中的条件判断表达式(第二个)。 (3) while (..) 和 do..while(..) 循环中的条件判断表达式。 (4)? :中的条件判断表达式。 (5) 逻辑运算符 ||(逻辑或)和 &&(逻辑与)左边的操作数(作为条件判断表达式)。

var a = 42;
     var b = "abc";
     var c;
     var d = null;
     if (a) {
         console.log( "yep" ); // yep
    }
    while (c) {
       console.log( "nope, never runs" );
     }
    c = d ? a : b; 
    c;  // "abc"
    if ((a && d) || c) {
      console.log( "yep" );  // yep
    }
复制代码

符号的强制类型转换

宽松相等(loose equals)== 和严格相等(strict equals)=== 都用来判断两个值是否“相 等”,但是它们之间有一个很重要的区别,特别是在判断条件上,即== 允许在相等比较中进行强制类型转换,而 === 不允许。

字符串和数字之间的相等比较

字符串和数字相互比较时,首先将字符中转换为数字再来比较。 (1) 如果 Type(x) 是数字,Type(y) 是字符串,则返回 x == ToNumber(y) 的结果。 (2) 如果 Type(x) 是字符串,Type(y) 是数字,则返回 ToNumber(x) == y 的结果

var a = 42;
     var b = "42";
     a == b // true
复制代码

其他类型和布尔类型之间的相等比较

字符串或数字等其他类型与布尔类型比较时,先将布尔类型转换为数字再来和字符串比较,接下来就是进行的字符串和数字之间的相等比较,再进行一轮转换来比较。 (1) 如果 Type(x) 是布尔类型,则返回 ToNumber(x) == y 的结果; (2) 如果 Type(y) 是布尔类型,则返回 x == ToNumber(y) 的结果

var x = true;
     var y = "42";
     x == y; // false
复制代码

null 和 undefined 之间的相等比较

(1) 如果 x 为 null,y 为 undefined,则结果为 true。 (2) 如果 x 为 undefined,y 为 null,则结果为 true 在 == 中 null 和 undefined 相等(它们也与其自身相等),除此之外其他值都不存在这种 情况

var a = null;
    var b;
     a == b;     // true
     a == null;  // true
     b == null;  // true
     a == false; // false
     b == false; // false
     a == "";    // false
     b == "";   // false
     a == 0;  // false
     b == 0;  // false
复制代码

对象和非对象之间的相等比较

对象和非对象之间的比较,首先对对象进行ToPromitive转换,再进行比较。 (1) 如果 Type(x) 是字符串或数字,Type(y) 是对象,则返回 x == ToPrimitive(y) 的结果; (2) 如果 Type(x) 是对象,Type(y) 是字符串或数字,则返回 ToPromitive(x) == y 的结果

var a = 42;
   var b = [ 42 ];
   a == b; // true
复制代码

比较少见的情况

1.隐式转换返回其他数字

Number.prototype.valueOf = function() {
         return 3;
     };
     new Number( 2 ) == 3;   // true
复制代码

Number(2) 涉及 ToPrimitive 强制类型 转换,因此会调用 valueOf()返回3. 思考题:下面代码中 a 在什么情况下会打印 1?

var a = ?;
if(a == 1 && a == 2 && a == 3){
 	conso.log(1);
}
复制代码
  1. 完整性检查
"0" == null;           // false
        "0" == undefined;      // false
        "0" == false;          // true -- 晕!
        "0" == NaN;            // false
        "0" == 0;              // true
        "0" == "";             // false
        false == null;         // false
        false == undefined;    // false
        false == NaN;          // false
        false == 0;            // true -- 晕! 
        false == "";           // true -- 晕!
        false == [];           // true -- 晕!
        false == {};           // false
        "" == null;            // false
        "" == undefined;       // false
        "" == NaN;             // false
        "" == 0;               // true -- 晕! 
        "" == [];              // true -- 晕!
        "" == {};              // false
        0 == null;             // false
        0 == undefined;        // false
        0 == NaN;              // false
        0 == [];               // true -- 晕! 
        0 == {};               // false
        [] == ![]              // true -- 反人类
复制代码

我们来看看[] == ![] 的转换过程

[] == ![] // =>
[] == false // => 
[] == 0 // =>
0 == 0 // true
复制代码

按照上述规范推敲两边的值,基本就不会出错。并且这两个原则可以让我们有效地避免出错 • 如果两边的值中有 true 或者 false,千万不要使用 ==。 • 如果两边的值中有 []、"" 或者 0,尽量不要使用 ==。

参考链接:《你不知道的javascript》


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

计算机动画的算法基础

计算机动画的算法基础

鲍虎军 金小刚 彭群生 / 浙江大学出版社 / 2000-12 / 60.00元

《计算机应用技术前沿丛书:计算机动画的算法基础》主要内容简介:20世纪是一个科技、经济空前发展的时代,从世纪初相对论、量子理论的创立到今天以信息产业为龙头的高科技产业成为经济发展的第一支柱,人类社会发生了根本性的变革。而在这场以科学技术为社会发展直接动因的变革中,意义最深远、影响最广泛的就是计算机及其相关技术的发展和应用。在过去的50年里,计算机已从最初的协助人类进行精密和复杂运算的单一功能的运算......一起来看看 《计算机动画的算法基础》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试