js 隐式转换 toString valueOF

 


Conversion, toString and valueOf

 

JS中有三种对象可以转换成原始数据类型
1.Numeric 2.String 3.Boolean
原始数据类型:
1.undefined/null
2.string
3.boolean
4.number

 

String: output, uses toString.
Numeric: maths, operators, uses valueOf -> toString.
Boolean: converts according to the table.

 


Value Converted to…
true/false no conversion
undefined, null false
Number 0, NaN become false, others - true.
String "" becomes false, any other - true
Object true

 

字符串转换发生在对象需要进行字符串表示时(output时)
toString for Objects outputs: [object Object]alert( [1,2] )
toString for Arrays lists elements "1,2"
toString for Dates outputs the date as a string
显示转换(String(obj))
可以自定义toString方法

 


Numeric conversion
数制转换主要发生在两种情况下:

  1. 需要数字的函数如Math,isNaN,parseInt 以及算数操作符时
  2. 在比较的时候(除了===)这个很重要的撒

首先 valueOf 如果返回原始数据类型,则返回 然后toString若返回原始数据类型则返回,否则抛出异常
显示转换 Number(obj)
Numeric 转换并不意味着一定会返回一个数字,只要返回原始数据类型就行。

 

Because of that, a good way to convert an object to a string is the binary addition:
var arr = [1,2,3]
alert( arr + '' )
// first tries arr.valueOf(), but arrays have no valueOf 【算术运算符‘+’】
// so arr.toString() is called and returns a list of elements: '1,2,3'
//但这仍然叫做numeric转换

 

Other mathematical functions not only perform the numeric conversion, but enforce a number. For example, the unary addition +arr would give NaN:

 

The default implementation of Array#toString lists it’s comma-delimited values:

 

Boolean context

 

There is one more standard conversion in JavaScript, called [[toBoolean]] in the specification.

 

If happens in boolean context, like if(obj)while(obj) etc.

 

Object may not implement such conversion on their own, there is no magic method. Instead, there is a hardcoded table of conversions:

 

ValueConverted to…
true/false no conversion
undefinednull false
Number 0NaN become false, others - true.
String "" becomes false, any other - true
Object true

 

 

 

'

 

 

 

Unlike many programming languages (for example PHP), "0" is true in JavaScript.

 

 

 

In the example below, we have numeric conversion (equality does it):

1    alert( [0] == 0 )  // true
2    alert( "\n0\n" == 0 ) // true
3    alert( "\n0\n" == false ) // true

 

 

So one may guess that [0] and "\n0\n" are falsy, because they equal 0.

 

But now let’s see how the left part behaves in boolean context:

 

 

1	if ([0]) alert(1)  // 1, if treats [0] as true
2	if ("\n0\n") alert(2) // 2, if treats "\n0\n" as true

  

 

It is possible that a == b, but in boolean context a is true and b is false.

 

A way to frighten Java programmers.

To convert a value to boolean, you may use double-negation: !!val or direct callBoolean(val).

Of course, we never use new Boolean for any purpose. Funny things happen if we do.

For example, let’s try to get a boolean out of zero:

 

alert( new Boolean(false) ) // false

  

But…

 

1	if ( new Boolean(false) ) {
2	  alert(true) // true
3	}

  

That’s because new Boolean is an object. The alert converts it to String, and it becomes "false"… Right.

But if converts it to boolean primitive, and here any object is true… Wops!

Java programmers’ eyes usually pop out when they see that.

 

 

 

Why they are equal?

1	alert( [] == ![] ) // true

  

Solution
  1. First, the two sides of comparison are evaluated. The right side is ![]. Logical NOT'!' converts to boolean. According to the table, an object [] is true. So, the right side becomes ![] = !true = false. It brings us to:
    [] == false

  2. The equality check between an object and a primitive converts the object to primitives in numeric way.

    The array has no valueOf, but has toString which converts it to a comma-delimited list of items. In our case, no items lead to an empty string:

    '' == false

     

  3. Comparison between different primitives converts them to numbers:
    0 == 0
    

      


    Now the result is obvious.

 

posted @ 2013-08-22 19:44  rainbowi  阅读(1056)  评论(0编辑  收藏  举报