In JavaScript {}+{}

Source: Internet
Author: User
Tags add numbers object object

In JavaScript, the rule of addition is actually simple, in only two cases:

    • Add numbers and Numbers

    • Add a string and a string

All other types of values are automatically converted to these two types of values. In order to figure out how this implicit conversion works, we first need to understand some basic knowledge.

Note : When referring to a section in the following article (such as §9.1), it refers to the chapters in the ECMA-262 Language specification (ECMAScript 5.1).

Let's review it quickly. In JavaScript, there are two kinds of values:

    • Original Value (Primitives)

      1. Undefined

      2. Null

      3. Boolean

      4. Number

      5. String

    • The object value (objects).

In addition to the original values, all other values are values of the object type, including arrays (array) and functions.

Type conversions

The addition operator triggers three types of conversions:

    1. Convert to original value

    2. Convert to Digital

    3. Convert to String

Convert a value to the original value by Toprimitive ()

The abstract operation inside the JavaScript engine ToPrimitive() has such a signature:

ToPrimitive(input,PreferredType?)

Optional parameters PreferredType can be Number either String . It only represents a conversion preference, and the conversion result must not necessarily be the type that the parameter refers to (Khan), but the conversion result must be a primitive value. If it is PreferredType marked Number , the following action is performed to convert input (§9.1):

    1. If input it is a raw value, it is returned directly.

    2. Otherwise, if input it is an object. The method is called obj.valueOf() . If the return value is an original value, the original value is returned.

    3. Otherwise, the obj.toString() method is called. If the return value is an original value, the original value is returned.

    4. Otherwise, an TypeError exception is thrown.

If it is PreferredType marked String , the second and third steps of the conversion operation are reversed. If you do not have PreferredType this parameter, PreferredType the value is automatically set according to the following rules:

    • DateObject of type will be set to String ,

    • Other types of values are set to Number .

Convert a value to a number by Tonumber ()

The table below explains ToNumber() How to convert the original value to a number (§9.3)

Parameters Results
Undefined NaN
Null +0
Boolean True is converted to 1,false to +0
Number No conversion required
String Parsed by a string into a number. For example, "324" is converted to 324

If the value entered is an object, it is first called to ToPrimitive(obj, Number) convert the object to the original value, and then the call converts the ToNumber() original value to a number.

Convert a value to a string by ToString ()

The following table explains ToString() How to convert the original value to a string (§9.8).

Parameters Results
Undefined "Undefined"
Null "NULL"
Boolean "True" or "false"
Number Number as a string. For example, "1.765"
String No conversion required

If the value entered is an object, it is first called to ToPrimitive(obj, String) convert the object to the original value before calling to ToString() convert the original value to a string.

Practice a bit

The following object allows you to see the conversion process inside the engine.

Varobj = {valueof: function  () {console. Log ({}; //not a Primitive},tostring: function  () {console. Log ( "toString" {}; //not a Primitive}}         

NumberWhen called as a function (rather than as a constructor call), the operation is invoked inside the engine ToNumber() :

> Number(obj)valueOftoStringTypeError: Cannot convert object to primitive value
Addition

There is an addition operation like the following.

value1 + value2

In evaluating this expression, the internal steps are as follows (§11.6.1):

    1. Convert two operands to the original value (the following is the pseudo-code for mathematical notation, not the JavaScript code that can be run):

      javascript prim1 := ToPrimitive(value1) prim2 := ToPrimitive(value2)

      PreferredTypeis omitted, so Date the value of the type is taken String , and other types of values are used Number .

    2. If either PRIM1 or PRIM2 is a string, the other is converted to a string, and then the result of the two string connection operation is returned.

    3. Otherwise, convert both PRIM1 and prim2 to numeric types, returning their and.

The expected results

When you add two arrays, the result is exactly what we expect:

> [] + []‘‘

[]is converted to a primitive value: First try valueOf() the method, which returns the array itself ( this ):

> var arr = [];> arr.valueOf() === arrtrue

At this point the result is not the original value, so the method is called toString() , returning an empty string ( string the original value). Therefore, [] + [] the result is actually a connection of two empty strings.

By adding an array and an object, the results still match our expectations:

> [] + {}‘[object Object]‘

Parse: When you convert an empty object to a string, the following results are generated.

> String({})‘[object Object]‘

So the end result is to "" connect the "[object Object]" two strings together.

More objects are converted to the original value example:

> 5 + new Number(7)12> 6 + { valueOf: function () { return 2 } }8> "abc" + { toString: function () { return "def" } }‘abcdef‘
Unexpected results.

If the + first operand of the addition operation is an empty object literal, there will be a bizarre result (running results in Firefox console):

> {} + {}NaN

Oh, my God! God horse situation? The reason for this is that JavaScript interprets the first one {} as an empty block of code and ignores it. NaNis actually +{} the result of an expression calculation ( + Plus and second {} ). The plus sign you see here is + not a two-dollar operator "addition," but a unary operator that converts the operands after it to a number, Number() exactly as the function does. For example:

> +"3.65"3.65

The following expression is its equivalent form:

+{}Number({})Number({}.toString())  // {}.valueOf() isn’t primitiveNumber("[object Object]")NaN

Why is the first one {} parsed into a code block? Because the entire input is parsed into a statement: If the opening brace appears at the beginning of a statement, the opening brace is parsed into the beginning of a block of code. So, you can also fix the result by forcing the input to parse into an expression: we expect it to be an expression, and the result is parsed into a statement.

> ({} + {})‘[object Object][object Object]‘

The parameters of a function or method are also parsed into an expression:

> console.log({} + {})[object Object][object Object]

You should not be surprised at the results of the calculations below, as explained above:

> {} + []0

Once explained, the above input is parsed into a block of code followed by an expression +[] . The steps for conversion are this:

+[]Number([])Number([].toString())  // [].valueOf() isn’t primitiveNumber("")0

Interestingly, the REPL of node. js, when parsing similar inputs, is different from the parsing results of Firefox and Chrome (as with node. js using the V8 engine). The following input is parsed into an expression that is more consistent with our expectations:

> {} + {}‘[object Object][object Object]‘> {} + []‘[object Object]‘

In most cases, it's not hard to figure out how the numbers in JavaScript + work: You can add numbers and numbers together, or strings and strings. The object value is converted to the original value before it is evaluated. If you add more than one array, you may have unexpected results.

If you want to concatenate multiple arrays, you need to use the Concat method of the array:

> [1, 2].concat([3, 4])[1, 2, 3, 4]

There are no built-in methods in JavaScript to "connect" (merge) Multiple objects. You can use a JavaScript library, such as underscore:

> var o1 = {eeny:1, meeny:2};> var o2 = {miny:3, moe: 4};> _.extend(o1, o2){eeny: 1, meeny: 2, miny: 3, moe: 4}

Note: Array.prototype.concat() Unlike a method, the extend() method modifies its first argument instead of returning the merged object:

> o1{eeny: 1, meeny: 2, miny: 3, moe: 4}> o2{miny: 3, moe: 4}

JavaScript {}+{}

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.