Posted on: November 18, 2022|6 min read|Amrish Kushwaha

How do Unary Plus and Unary Negation operators behave in Javascript?

How do Unary Plus and Unary Negation operators behave in Javascript?

The behaviour of Unary Plus and Unary Negation operators:

Are you sometimes think that how unary operators such as unary plus and unary negation process the operand behind the scene? Are you clueless in your coding and confused that how the conversion of values or data types happens under the hood, especially with unary operators such as unary plus and unary negation? This article will give the answer to all of your questions related to this topic and will reduce your anxiety :).

In javascript, there are many unary operators such as unary plus, unary minus, logical NOT, bitwise NOT etc. Since javascript is not strictly typed language, so when we apply operators on data types, coercion of the data types happens under the hood such as in the case of unary plus, the operand will be converted to number type. The same kind of coercion happens with the unary negation operator.

So, it is very much important to know what is happening under the hood in order to correctly predict the coercion of the data types so that you can be very confident in your coding.

In this article, I am going to discuss 2 different unary operators - unary plus and unary negation operators.

Since unary plus and unary negation internally use ToNumber conversion, so I will first discuss the rules for conversion of any value (data types) to number (data types) in javascript so that it would be piece of cake to calculate the corresponding number.

Rules for conversion of any value to the number:

I will assume that there is a provided value and there is a ToNumber function which will take the provided value as an argument and return the converted value. I am doing so to make it understand the conversion or coercion in an easy way.

  1. If provided value is of the number type, return it (return that number).
  2. If provided value is of BigInt or Symbol type, throw TypeError.
  3. If provided value is undefined, return NaN.
  4. If provided value is null, return +0 which is 0.
  5. If provided value is true, return 1 and If provided value is false, return 0.
  6. If provided value is of string type
    1. If the string contains only StringNumericLiteral
      • process the string and returns the corresponding number value.
    2. else return NaN means if it contains NonStrNumericLiteral, then return NaN.
  7. If provided value is of object type
    1. then convert it into the corresponding primitive value and then convert that primitive to number.

I will also list the rule for conversion from object to primitive to make the process clear.

Rules for conversion of Object to Primitive

In this conversion also, I will assume that there is a provided value of the type object and a ToPrimitive function that will take the provided value as an argument and return the converted value.

  1. First check if the object is having valueOf and toString methods, If no, throw Error.
  2. Check the value of the result of invoking the valueOf method. If it is not the object type, then return the result otherwise move to step 3.
  3. Check the value of the result of invoking the toString method. If it is not the object type, then return the result otherwise throw Error.

Now we know the rules for used conversion in the process, we can now go to the definition and corresponding examples for unary plus and unary negation operators.

Unary plus operator ( + ) :

The unary plus operator is a unary operator that converts the operand to number type if that is not already. That’s all it does. So we can say that the unary plus operator is the fastest way to convert any value into the number type.

Syntax:

// +operand or // +expression

This is the syntax for the unary plus operator. The unary plus operator can be applied to an operand or expression.

Execution step:

Now comes the execution step for the evaluation of unary plus

  1. The first operand or expression will be evaluated
  2. Then unary plus ( + ) operator will convert that evaluated value into the number.

For example:

console.log(+("john doe" + 1)) // These are execution steps // 1. +("john doe" + 1) // 2. +("john doe1") // 3. NaN // logs NaN as result.

Common examples:

console.log(+[]) // 0 console.log(+[""]) // 0 console.log(+[null]) // 0 console.log(+[undefined]) // 0 console.log(+[0]) // 0 console.log(+[NaN]) // NaN console.log(+["abc"]) // NaN console.log(+[[]]) // 0 console.log(+[{}]) // NaN console.log(+{}) // NaN console.log(+{ a: "b" }) // NaN console.log(+true) // 1 console.log(+false) // 0 console.log(+0) // 0 console.log(+1) // 1 console.log(+1.23) // 1.23 console.log(+-1.23) // -1.23 console.log(+-0.23) // -0.23 console.log(+NaN) // NaN console.log(+null) // 0 console.log(+undefined) // NaN console.log(+"") // 0 console.log(+"abc") // NaN console.log(+"123") // 123 console.log(+"0") // 0 console.log(+" ") // 0 console.log(+" 123 ") // 123 console.log(+" 1.23e10 ") // 12300000000 console.log(+" 1.23e10 + ") // NaN console.log(+function abc() {}) // NaN const sym = Symbol("1") console.log(+sym) // Throw TypeError console.log(+2n) // Throw TypeError

Unary negation operator ( - ) :

The unary negation operator is the unary operator that when applied to some operand, it tries to convert the operand to the numeric value and then negate it. After the conversion of the operand, if it is of number type, then it negates that number. After the conversion of the operand, if it is of BigInt type, then it does the corresponding negation of that Big Int.

Syntax:

// -operand or // -expression

As you can see in the above code block, that is the syntax for the unary negation operator. A unary negation operator can be applied to an operand or expression.

Execution Step:

Now comes the execution step for the evaluation of unary negation

  1. The first operand or expression will be evaluated
  2. Then unary negation ( - ) operator will convert that evaluated value into the numeric type ( either in number type or in BigInt type ).
  3. Then that numeric value will be negated

For example:

console.log(-(10 - "2")) // These are execution steps // 1. -(10 - "2") // 2. -(8) // 3. -8 // logs -8 as result.

Common examples:

console.log(-[]) // -0 console.log(-[""]) // -0 console.log(-[null]) // -0 console.log(-[undefined]) // -0 console.log(-[0]) // -0 console.log(-[NaN]) // NaN console.log(-["abc"]) // NaN console.log(-[[]]) // -0 console.log(-[{}]) // NaN console.log(-{}) // NaN console.log(-{ a: "b" }) // NaN console.log(-true) // -1 console.log(-false) // -0 console.log(-0) // -0 console.log(-1) // -1 console.log(--0.23) // Syntax Error console.log(-1.23) // -1.23 console.log(-NaN) // NaN console.log(-null) // -0 console.log(-undefined) // NaN console.log(-"") // -0 console.log(-"abc") // NaN console.log(-"123") // -123 console.log(-"0") // -0 console.log(-" ") // -0 console.log(-" 123 ") // -123 console.log(-" 1.23e10 ") // -12300000000 console.log(-" 1.23e10 + ") // NaN console.log(-function abc() {}) // NaN const sym = Symbol('1'); console.log(-sym) // Throw TypeError console.log(-2n) // -2n. It doesn't throw TypeError as the unary plus throw.

This is how unary plus and unary negation operators behave under the hood. I hope that now you are confident enough to predict the result just by seeing it and calculating it in your mind.

If you wanna check these rules, you can go to ECMAScript language specification - https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-unary-plus-operator and https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-unary-minus-operator.

I hope that you have liked the article.

Keep coding and keep solving problems.

About author:

Amrish Kushwaha

Amrish Kushwaha

I am Amrish Kushwaha. Software Engineer, Maker, Writer. I am currently focused on frontend development with curiosity of building end to end software system. Currently I am working at Rafay Systems. I love to write as well as build side projects when I am free.

Frontendroom
© 2023 · Copyright Frontendroom