type conversion
Type conversion tool methods
valueOf
: Returns the value of the primitive type that this object logically corresponds to . For example,String
if you wrap an objectvalueOf()
, you should return the string wrapped by this object.toString
: Returns the string representation of this object. Use a string to describe the contents of this object.
**All objects will inherit these two methods. The following is the behavior of some built-in object calls valueOf()
: **
object | return value |
---|---|
Array | The array itself (object type). |
Boolean | Boolean (primitive type). |
Date | The number of milliseconds since UTC midnight on January 1, 1970, since the encapsulated date (raw type). |
Function | The function itself (object type). |
Number | Numeric value (primitive type). |
Object | The object itself (object type). If the custom object does not override valueOf the method, it will be used. |
String | String value (primitive type). |
As can be seen from the above table, valueOf()
although it is expected to return a primitive type value, there are actually some objects for which the corresponding primitive value cannot be found logically, so the object itself can only be returned. toString()
It's different, because no matter what the object is, we always have a way to "describe" it, so javascript
the built-in object toString()
can always return a primitive string
type value. We toString()
should also return reasonable when rewriting string
.
valueOf()
and toString()
are often called internally during type conversion javascript引擎
, as we will talk about later ToPrimitive
. By appropriately overriding valueOf()
and on a custom object toString()
, you can control the type conversion of the custom object.
Internal methods for type conversion
ECMAScript
Four abstract operations related to type conversion are defined, which are javascript
used internally by the engine for type conversion. We cannot call these methods directly, but understanding these functions will help us understand the principles of type conversion.
-
ToPrimitive ( input [ , PreferredType ] )
: Will beinput
converted into a primitive type value.PreferredType
The parameter (expected type) is either not passed in or isNumber
orString
.-
If
PreferredType
the parameter isNumber
,ToPrimitive
execute like this:-
If
input
it is a primitive type, return it directlyinput
. -
Called
input.valueOf()
, if the result is a primitive type, this result is returned. -
Called
input.toString()
, if the result is a primitive type, this result is returned. -
Throws
TypeError
an exception.
-
-
The following is
PreferredType为String
the execution sequence:- If
PreferredType
the parameter isString
, exchange the order of steps 2 and 3 above, and the other execution processes are the same. - If
PreferredType
no parameters are passed in:- If
input
it is a built-inDate
type,PreferredType
treat it as suchString
. - Otherwise
PreferredType
regarded asNumber
- If
- If
-
-
ToBoolean ( argument )
:Parameter Type result Undefined Return false Null Return false Boolean Return argument Number Only when argument is +0, -0, or NaN
, return false; otherwise, always return trueString Only when argument is an empty string (length is 0), return false; otherwise, always return true Symbol Return true Object Return true -
ToNumber ( argument )
:Parameter Type result Undefined Return NaN
Null Return +0 Boolean If argument is true, return 1. If argument is false, return +0 Number Return argument directly String Convert the content in the string into numbers (such as "23"->23), and return if the conversion fails NaN
(for example"23a"->NaN
)Symbol throw TypeError
exceptionObject First primValue = ToPrimitive(argument, Number)
, thenprimValue
useToNumber(primValue)
ToNumber(function(){})
returnNaN
-
ToString ( argument )
:Parameter Type result Undefined Return “undefined” Null Return “null” Boolean If argument is true, return “true”. If argument is false, return “false” Number Represent this number as a string String Return directly argument
Symbol throw TypeError
exceptionObject primValue
= firstToPrimitive(argument, hint String)
, thenprimValue
useToString(primValue)
Rewriting (overwriting): Rewriting methods or properties in an inheritance relationship can also be understood as having a method to override the constructor of the prototype object.
//返回值[Object Object] 第一个Object表示类型,第二个表示构造函数,调用Object.prototype的toString方法
console.log(o.toString());
//返回值1,2,3,调用Array.prototype的toString方法
console.log([1, 2, 3].toString())
Note: parseInt
and parseFloat
are conversions (extraction methods) string
between number
and , not type conversion methods.
Explicit type conversion (casting)
There are only three methods for display type conversion Boolean(value)
: , Number(value)
and String(value)
these three methods; paseInt
, pasefloat
extract the string that can be converted.
显式(手动)调用Boolean(value)
、Number(value)
、String(value)
完成的类型转换,叫做显示类型转换。 其实这三个函数用于类型转换的时候,调用的就是 JavaScript
内部的ToBoolean ( argument )
、ToNumber ( argument )
、ToString ( argument )
方法。
注意:toString
与 ToString
是不同的方法
new String(45); //当构造函数使用,将一个值转换为String基本包装类型,ToString
String(45); // 当普通函数使用,将一个值转换为string值类型,ToString
String.prototype; // 当函数对象使用
var arr = [1, 2]
console.log(arr.toString()); //返回1,2
console.log(toString(arr)); //调用Object的toString,返回[Object, Array]
console.log(String(arr)); //返回1,2
// console.log(arr.ToString()); //报错
// console.log(ToString(arr)) //报错
隐式类型转换(自动类型转换)
当js
期望得到某种类型的值,而实际在那里的值是其他的类型,就会发生隐式类型转换。系统内部会自动调用我们前面说ToBoolean ( argument )
、ToNumber ( argument )
、ToString ( argument )
,尝试转换成期望的数据类型。
常见隐式类型转换规则
在某些情况下,即使我们不提供显示转换,Javascript
也会进行自动类型转换,主要情况有:
-
用于检测是否为非数值的函数:
isNaN(mix)
- 该函数会尝试将参数值用
Number()
进行转换,如果结果为“非数值”则返回true
,否则返回false
。
- 该函数会尝试将参数值用
-
递增递减操作符(包括前置和后置)、一元正负符号操作符,这些操作符适用于任何数据类型的值,针对不同类型的值,该操作符遵循以下规则(经过对比发现,其规则与
Number()
规则基本相同):- 如果是包含有效数字字符的字符串,先将其用
Number
进行转换再执行加减1的操作; - 如果是不包含有效数字字符的字符串,将变量的值设置为
NaN
; - 如果是布尔值
false
,先将其转换为0再执行加减1的操作; - 如果是布尔值
true
,先将其转换为1再执行加减1的操作; - 如果是浮点数值,执行加减1的操作;
- 如果是对象,对它用
Number()
转换,再执行加减1的操作。
- 如果是包含有效数字字符的字符串,先将其用
-
加号运算操作符在
Javascript
也用于字符串连接符,所以加号操作符的规则分两种情况:-
如果两个操作值都是数值,其规则为:
- 如果一个操作数为
NaN
,则结果为NaN
- 如果是
Infinity+Infinity
,结果是Infinity
(无穷大) - 如果是
-Infinity+(-Infinity)
,结果是-Infinity
- 如果是
Infinity+(-Infinity)
,结果是NaN
- 如果是
+0+(+0)
,结果为+0
- 如果是
(-0)+(-0)
,结果为-0
- 如果是
(+0)+(-0)
,结果为+0
- 如果一个操作数为
-
如果有一个操作值为字符串,则:
- 如果两个操作值都是字符串,则将它们拼接起来
- 如果只有一个操作值为字符串,则将另外操作值转换为字符串,然后拼接起来
- 如果一个操作数是对象、数值或者布尔值,则调用
valueOf()-toString()
方法取得字符串值,然后再应用前面的字符串规则。对于undefined
和null
,分别调用String()
显式转换为字符串。 - 可以看出,加法运算中,如果有一个操作值为字符串类型,则将另一个操作值转换为字符串,最后连接起来。
console.log(2 + [99]) //299 ToPrimitive([], "number") //0
-
-
乘除、减号运算符、取模运算符,这些操作符针对的是运算,所以他们具有共同性:如果操作值之一不是数值,则被隐式调用
Number()
函数进行转换。 -
逻辑操作符
!、&&、||
:- 逻辑非
!
操作符,首先通过Boolean()
函数将它的操作值转换为布尔值,然后求反。 - 逻辑与
&&
操作符,如果一个操作值不是布尔值时,遵循以下规则进行转换:- 如果第一个操作数经
Boolean()
转换后为true
,则返回第二个操作值,否则返回第一个值(不是Boolean()
转换后的值) - 如果有一个操作值为
null、NaN、undefined
,分别返回null、NaN、undefined
- 如果第一个操作数经
- 逻辑或
||
操作符,如果一个操作值不是布尔值,遵循以下规则:- 如果第一个操作值经
Boolean()
转换后为false
,则返回第二个操作值,否则返回第一个操作值(不是Boolean()
转换后的值) - 对于
undefined
、null
和NaN
的处理规则与逻辑与&&
相同
- 如果第一个操作值经
- 逻辑非
-
关系操作符
<, >, <=, >=
,与上述操作符一样返回Boolean
值,关系操作符的操作值也可以是任意类型的,所以使用非数值类型参与比较时也需要系统进行隐式类型转换:- 如果两个操作值都是数值,则进行数值比较
- 如果两个操作值都是字符串,则比较字符串对应的字符ASCII编码值(a=97,A=65,0=48)
- 如果只有一个操作值是数值,则将另一个操作值转换为数值,进行数值比较
- 如果一个操作数是对象,则调用
ToNumber
方法,结果按照前面的规则执行比较 - 如果一个操作值是布尔值,则将其转换为数值,再进行比较。
注:
NaN
是非常特殊的值,它不和任何类型的值相等,包括它自己,同时它与任何类型的值比较大小时都返回false
。 -
相等操作符
==
,相等操作符会对操作值进行隐式转换后进行比较:-
如果一个操作值为布尔值,则在比较之前先将其转换为数值
-
如果一个操作值为字符串,另一个操作值为数值,则通过
Number()
函数将字符串转换为数值 -
如果一个操作值是对象,另一个不是,则调用对象的
valueOf(), ToString()
方法,得到的结果按照前面的规则进行比较 -
null
与undefined
是相等的 -
如果一个操作值为
NaN
,则相等比较返回false
-
如果两个操作值都是对象,则比较它们是不是指向同一个对象 (比较两者是否是同一个引用地址)
var arr1 = []; var arr2 = []; console.log(arr1 == arr2); //false console.log(0 === -[]); //true console.log(Object.id(0,-[] )); //false
-
注意:
-
JavaScript
编程指南中表明尽量不使用==
,例如:1 “1” 与 1= “1”; -
且
JS
中会使用最少的转换次数来满足操作符的操作条件。