亲宝软件园·资讯

展开

JavaScript隐式类型转换(详解 +,-,*,/,==)

whosmeya 人气:2
JavaScript 在 运算 或 比较 之前, 会自动进行隐式类型转换. 下面我们来仔细讲一讲 + - * / == 运算符经历了哪些过程. ## 类型转换 ECMAScript 运行时系统会在需要时从事自动类型转换。为了阐明某些结构的语义,定义一集转换运算符是很有用的。__这些运算符不是语言的一部分__;在这里定义它们是为了协助语言语义的规范。 * ToPrimitive * ToNumber * ToString * ToBoolean * ToInteger * ToInt32:(32 位有符号整数) * ToUint32:(32 位无符号整数) * ToUint16:(16 位无符号整数) * ToObject 下面详细讲讲前三种 ### ToPrimitive 转为原始类型. ```js ToPrimitive(input, PreferredType) ``` |输入类型|结果| |-|-| |Undefined|结果等于输入的参数(不转换)。| |Null|结果等于输入的参数(不转换)。| |Boolean|结果等于输入的参数(不转换)。| |Number|结果等于输入的参数(不转换)。| |String|结果等于输入的参数(不转换)。| |Object|返回该对象的默认值。
对象的默认值由把 PreferredType 传入作为hint参数调用对象的内部方法[[DefaultValue]]得到| #### 对象内部方法 [[DefaultValue]] (hint) 当用 String hint 调用 O 的 [[DefaultValue]] 内部方法,采用以下步骤: 1. str = O.toString(); 2. 如果str为原始值,返回str; 3. val = O.valueOf(); 4. 如果val为原始值,返回val; 5. 抛出一个 TypeError 异常。 当用 Number hint 调用 O 的 [[DefaultValue]] 内部方法,采用以下步骤: 1. val = O.valueOf(); 2. 如果val为原始值,返回val; 3. str = O.toString(); 4. 如果str为原始值,返回str; 5. 抛出一个 TypeError 异常。 __当不用 hint 调用 O 的 [[DefaultValue]] 内部方法时, 如果 O 为Date, 则hint=String, 除此之外, hit=Number。__ 例子: ```js ToPrimitive({}) 解析: 数据类型为 Object, 调用[[DefaultValue]] 没有用 hint 调用, 则 hint 为 Number val = O.valueOf(); val 是 {}, 不是原始值 str = O.toString(); str 是 '[object Object]', 是原始值, 返回'[object Object]' 结果: '[object Object]' ``` ### ToNumber 转为数字类型.(是 Number(value) 的实现) |Input Type|Result| |-|-| |Undefined|NaN| |Null|+0| |Boolean|true: 1, false: +0| |Number|结果等于输入的参数(不转换)。| |String|将字符串转换为数字。| |Object|Apply the following steps:
1. Call ToPrimitive(input argument, hint Number).
2. Call ToNumber(Result(1)).
3. Return Result(2).| ### ToString 转为字符串类型.(是 String(value) 的实现) |输入类型|结果| |-|-| |Undefined|"undefined"| |Null|"null"| |Boolean|如果参数是 true,那么结果为 "true"。
如果参数是 false,那么结果为 "false"。| |Number|将数字转换为字符串。| |String|结果等于输入的参数(不转换)。| |Object|Apply the following steps:
1. Call ToPrimitive(input argument, hint String).
2. Call ToString(Result(1)).
3. Return Result(2).| 例子: ```js var obj = { valueOf: function () { return 1; }, toString: function () { return 2; } } Number(obj) 解析: obj 类型 Object, 调用 ToPrimitive(obj, Number) 用 Number hint 调用 obj 的 [[DefaultValue]] 内部方法 调用 obj 的 valueOf 方法, 结果为 1 返回 ToNumber(1) 结果: 1 String(obj) 解析: obj 类型 Object, 调用 ToPrimitive(obj, String) 用 String hint 调用 obj 的 [[DefaultValue]] 内部方法 调用 obj 的 toString 方法, 结果为 2 返回 ToString(2) 结果: '2' ``` ## 类型转换的实际运用 ### 加号运算符 + lval + rval 运算流程如下: 1. 令 lprim 为 ToPrimitive(lval). 2. 令 rprim 为 ToPrimitive(rval). 3. 如果 Type(lprim) 为 String 或者 Type(rprim) 为 String,则: 返回由 ToString(lprim) 和 ToString(rprim) 连接而成的字符串. 4. 返回将加法运算作用于 ToNumber(lprim) 和 ToNumber(rprim) 的结果. 例子: ```js ([] + {}) 解析: 1. lprim = ToPrimitive([]); // '' 2. rprim = ToPrimitive({}); // '[object Object]' 3. lprim 和 rprim 都为字符串, 返回 ToString('') + ToString('[object Object]') // '[object Object]' 结果: '[object Object]' (undefined + {}) 解析: 1. lprim = ToPrimitive([]); // undefined; 2. rprim = ToPrimitive({}); // '[object Object]'; 3. Type(rprim) 为 String, 返回 ToString(undefined) + ToString('[object Object]') // 'undefined[object Object]' 结果: 'undefined[object Object]' (undefined + 1) 解析: 1. lprim = ToPrimitive([]); // undefined; 2. rprim = ToPrimitive(1); // 1; 3. Type(lprim) Type(rprim) 都不是 String; 4. 返回 ToNumber(undefined) + ToNumber(1) // NaN 结果: NaN ``` ### 其他运算符 - * / lval 和 rval 的 - * / 运算符流程如下: 1. 令 lnum 为 ToNumber(lval). 2. 令 rnum 为 ToNumber(rval). 3. 返回 ToNumber(lprim) 和 ToNumber(rprim) 运算的结果. ### 非严格相等比较
被比较值 B
Undefined Null Number String Boolean Object
被比较值 A Undefined true true false false false IsFalsy(B)
Null true true false false false IsFalsy(B)
Number false false A === B A === ToNumber(B) A=== ToNumber(B) A== ToPrimitive(B)
String false false ToNumber(A) === B A === B ToNumber(A) === ToNumber(B) ToPrimitive(B) == A
Boolean false false ToNumber(A) === B ToNumber(A) === ToNumber(B) A === B ToNumber(A) == ToPrimitive(B)
Object false false ToPrimitive(A) == B ToPrimitive(A) == B ToPrimitive(A) == ToNumber(B)

A === B

例子: ``` [] == {} -> this == this -> false [] == 0 -> ToPrimitive([]) == 0 -> '' == 0 -> ToNumber('') == 0 -> 0 == 0 -> true [0] == 0 -> ToPrimitive([0]) == 0 -> '0' == 0 -> ToNumber('0') == 0 -> 0 == 0 -> true [11] == 11 -> true ['0'] == false -> ToPrimitive(['0']) == ToNumber(false) -> '0' == 0 -> 0 == 0 -> true ({} == '[object Object]') -> ToPrimitive({}) == '[object Object]' -> '[object Object]' == '[object Object]' -> true ```   __参考__ * [ECMAScript5.1中文版](http://yanhaijing.com/es5/#201) * [JavaScript 中的相等性判断](https:/https://img.qb5200.com/download-x/developer.mozilla.org/zh-CNhttps://img.qb5200.com/download-x/docs/Web/JavaScript/Equality_comparisons_and_sameness)

加载全部内容

相关教程
猜你喜欢
用户评论