JavaScript series article: Automatic type Conversion-cont.

Source: Internet
Author: User
Tags object object

In the previous article, we explained in detail the automatic type conversion in JavaScript, which was not covered by any of the conversion rules due to space limitations, and is ready to be explained in detail.

The last time we talked about object type conversion rules when participating in an operation:

1). When executing in a logical environment, it is converted to true

2). In a string environment and a digital environment, its valueof () method and the ToString () method are called sequentially, and then converted again based on the return value. First, the ValueOf () method is called, and if its return value is the underlying type, the return value is converted to the target type, and if the return value is not the underlying type, then an attempt is made to call the ToString () method and then transform the return value. If the final return value is not the underlying type, the transformation throws an exception, and if it is the underlying type, it is converted to a string or number accordingly.

Then last time, when the plus sign "+" is applied as a unary operator above the object type, the ValueOf () and ToString () methods will have the opportunity to be called, and the final return value will be converted to the numeric type, and we will get a number or Nan. Let's take a look at the order in which valueof () and ToString () are called:

var o = {    function() {        return ' 3 ';    },      function() {        return ' 5 ';    }}; var foo = +o;console.log (foo);     // 3

As you can see, the ValueOf () method is called, returns the ' 3 ' of the string type, and then is converted to 3 of the number type, and the ToString () method is not called, and we remove the ValueOf () method again:

var o = {    function() {        return ' 5 ';    }}; var foo = +o;console.log (foo);     // 5

The ToString () method is called, and the object is successfully converted to the number 5 according to its return value ' 5 '.

It is estimated that many beginners will feel that if the valueof () method is defined, the call to the valueof () method, if not defined, to call the ToString () method, is actually inaccurate.

In fact, the ValueOf () method is always called in the first time, as for the ToString () method call or not, it depends on the return value of the ValueOf () method, we also mentioned above, if its return value is the underlying type, then the ToString () method has no chance to be called , and if its return value is a reference type, then it attempts to call the ToString () method to get the final value.

Typically, the valueof () method in an object prototype returns its own reference , taking the example above:

var o = {    function() {        return ' 5 ';      = = = O); // true

We use the congruent (= = =) operator to compare the return value of its valueof () and its own, found to be exactly the same, proving that the return value of valueof () in the object prototype is indeed itself, the result of which is equivalent to the following code:

// overrides the ValueOf () method in the instance whose return value is the object itself var o = {    function() {        returnthis;    },     function () {        return ' 5 ';      = = = O); // true

Now, with a little modification, we can see exactly what happened during the type conversion process:

varo ={};object.prototype.valueof=function() {Console.log (' ValueOf () called '); return[];};o Bject.prototype.toString=function() {Console.log (' ToString () called ')            return' 5 ';}varA = +o;//output:valueof () called//output:tostring () calledConsole.log (a); //5varb = O + ';//output:valueof () called//output:tostring () calledConsole.log (b); //' 5 '

In the above code, we changed the prototype method valueof () and ToString () to add the console output statement inside the method, and in valueof () we returned an array object. When the object participates in the operation, it can be seen that two methods are called sequentially, whether it is a digital environment or a string environment, the valueof () method is called first, and since the return value is not the underlying type, the ToString () method needs to be called again to get a final return value and then convert it to the target type. If we replace the array return value in valueof () with an underlying type, the ToString () method will not have a chance to execute, and you can try it yourself.

As mentioned above, the valueof () method of the object prototype defaults to returning the object itself, and in fact, the valueof () method of the Common object type returns itself:

 var  o = {};  var  fn = function   () {};  var  ary = [];                 var  regex =/./;o.valueof ()  = = = = O; //  true               fn.valueof ()  = = = fn; //  true             ary.valueof ()  = = = ary; //  true         regex.valueof ()  = = = = Regex; //  

However, with a special exception, the date type valueof () returns a number of milliseconds:

var New Date (1, 1); var time = date.valueof (); Console.log (time);                       // 1485878400000  = = = Date.gettime ());    // true

So it's easy to see how a unary plus operator is used on a date instance to return a number:

var New Date (1, 1); var time = +Date;console.log (time);     // 1485878400000

But date is a magical species, and if we add it directly to a time-millisecond number, we don't get the desired result:

var New Date (1, 1); var time = date + 10000; Console.log (time);     // ' Wed Feb 00:00:00 gmt+0800 (CST) 10000 '

It turned into a string, and then a string connection operation with the number! Why would it be like this? The reason is that for unary plus operator operation, the purpose is very clear, is to be positive operation, so the engine called its valueof () method, return timestamp number, and for the latter of the two plus plus sign operation operation, there is the addition and the connector of the two semantics, So the engine can selectively convert the operand to a different target type, and unlike other objects, the date type prefers to convert to a string type, so ToString () is called in advance. The following statement is a description of the date type to the underlying type in the ECMA specification:

Presumably, when an object is moved to the underlying type, it usually calls a method such as toprimitive (hint), passes in a hint parameter, specifies its target type, and if not specified, the default value of the other object is number, and the date type is different. Its default value is string.

We also mentioned above, the unary plus operator is a positive operation, so the engine can recognize and specify the number target type, and the two-dollar plus operator is ambiguous, the engine uses the default as the hint parameter, the date type is considered a value of string, So we also understand the above example, even if the date object and the number add, it will not call the valueof () method to get the number, but first call ToString () to get a string.

The above explained so much, I believe that everyone of the object type of transformation rules are familiar with, then for the common object, how is the basic type? As an example:

var foo = +[];            // 0 ([], 0) var foo = +[3];           // 3 ([3], ' 3 '--3) var foo = +[3, 5];        // Nan ([3, 5], ' 3,5 ')

As can be seen from the above code, for an array object to be converted to a number, it is necessary to follow the transformation rules of the object type, because the valueof () method of the array prototype returns its own reference, so eventually it tries to call its ToString () method, and its ToString () will return a string, which is a comma-delimited set of array elements, it is easy to understand that for an empty array, it is necessary to return an empty string, and then the empty string transformed into a number will be 0, and for a non-empty array, if there is only one element and the element can be converted to a number, The result is the number of the first element, and if more than one element, because the comma is present in the result that ToString () returns, it cannot be successfully transformed and returns a Nan.

But if we try to add an array and a number, we will still get the result of a string:

var foo = [] + 3;          // ' 3 ' var foo = [3] + 3;     // ' a ' var foo = [3, 5] + 3;     // ' 3,53 '

You might say, isn't it much like the date type above? Yes, the result looks very similar, but its internal execution process is still different, its valueof () will be executed first, the result above, is because valueof () returned this, and then call ToString () returned the string, The plus operator is here as a string connector.

Similar to the literal object, see the following example:

var foo = {} + 0;        // ' [Object object]0 ' var foo = {} + [];       // ' [Object Object] ' var foo = {} + {};       // ' [Object Object][object object] '

However, if you enter the following expression directly on the command line, the results will differ:

{} + 0;        // 0 + [];       // 0 + {};       // NaN

The reason for this is that the preceding literal object is interpreted as a block of code, there is no participation in the operation, only the latter part will return the final result, the subsequent conversion process can refer to the above we explain the content.

The type conversion rules of an object, just here, the type conversions in the comparison operators .

There are several comparison operators: >=, <, <=, = = = = =. In addition to the last strict equality operator, several other types of data in comparison to different types have a value conversion.

For the first four types, the following rules are followed:

1). When the two operands are of type string, no data type conversions are performed, and each character is directly compared

2). When two operands are not both strings, convert the operand to a numeric type, and then compare

3). If an object type exists in the operand, the object is first converted to the underlying type, and then the value is compared against the above two.

for the "= =" operator, there is a special rule: null and undefined do not convert data during comparisons, null and self comparisons, null and undefined comparisons will return true, and other value comparisons will return false , undefined and self comparison, undefined, and null comparisons both return True, and the comparison with other values will return FALSE.

Data type conversions do not exist for the following comparison operations:

' A3 ' < ' B3 ';          // true null = = undefined;    // true null = = 0;            // false

Note that the last expression, as we mentioned in the previous article, is that the null value will be transformed to 0 in the digital environment, and many people feel that the result of this expression is true, but don't ignore the above rules about null and undefined, there is no type conversion to take place.

In the following expressions, the operands are not all strings, so the operands are converted to numbers before being compared:

3 = = ' 3 ';             // true3 < ' 5 ';            // true //        true0 = = "; // true false;    // true true;            // true null >= 0;            // true     

Note that null in the last expression is converted to the number 0 when encountering the >, >=, <, <= operators, which differs from the rule above.

Finally, when the object participates in the logical operation, it also follows the previous transformation rules:

var o = {    function() {        return ' 3 ';    },      function() {        return ' 5 ';     > 4;        // true

It is particularly important to note that the object is treated as true in the conditional statement, but avoid the following comparison, as we described earlier:

if ([]) {    //  todo}iftrue) {    // Todo}

The second conditional statement block is not executed, because the empty array object is converted to the number 0, and true is converted to the number 1, the result of the comparison is false, so the code inside can never be executed, development should be wary of such a notation.

Write so much about the automatic type conversion content, we can also realize how flexible JS, want to master this language, not an easy thing, but also need to carefully understand, good research.

The end of this article.

Resources:

http://es5.github.io/#x11.8.5

http://es5.github.io/#x11.9.3

Http://www.2ality.com/2012/01/object-plus-object.html

Http://www.2ality.com/2013/04/quirk-implicit-conversion.html

https://www.united-coders.com/matthias-reuter/all-about-types-part-2/

Http://www.adequatelygood.com/Object-to-Primitive-Conversions-in-JavaScript.html

JavaScript series article: Automatic type Conversion-cont.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.