ECMAScript® 2024 Language Specification

Draft ECMA-262 / February 15, 2024

13.5 Unary Operators

Syntax

UnaryExpression[Yield, Await] : UpdateExpression[?Yield, ?Await] delete UnaryExpression[?Yield, ?Await] void UnaryExpression[?Yield, ?Await] typeof UnaryExpression[?Yield, ?Await] + UnaryExpression[?Yield, ?Await] - UnaryExpression[?Yield, ?Await] ~ UnaryExpression[?Yield, ?Await] ! UnaryExpression[?Yield, ?Await] [+Await] AwaitExpression[?Yield]

13.5.1 The delete Operator

13.5.1.1 Static Semantics: Early Errors

UnaryExpression : delete UnaryExpression Note

The last rule means that expressions such as delete (((foo))) produce early errors because of recursive application of the first rule.

13.5.1.2 Runtime Semantics: Evaluation

UnaryExpression : delete UnaryExpression
  1. Let ref be ? Evaluation of UnaryExpression.
  2. If ref is not a Reference Record, return true.
  3. If IsUnresolvableReference(ref) is true, then
    1. Assert: ref.[[Strict]] is false.
    2. Return true.
  4. If IsPropertyReference(ref) is true, then
    1. Assert: IsPrivateReference(ref) is false.
    2. If IsSuperReference(ref) is true, throw a ReferenceError exception.
    3. Let baseObj be ? ToObject(ref.[[Base]]).
    4. Let deleteStatus be ? baseObj.[[Delete]](ref.[[ReferencedName]]).
    5. If deleteStatus is false and ref.[[Strict]] is true, throw a TypeError exception.
    6. Return deleteStatus.
  5. Else,
    1. Let base be ref.[[Base]].
    2. Assert: base is an Environment Record.
    3. Return ? base.DeleteBinding(ref.[[ReferencedName]]).
Note 1

When a delete operator occurs within strict mode code, a SyntaxError exception is thrown if its UnaryExpression is a direct reference to a variable, function argument, or function name. In addition, if a delete operator occurs within strict mode code and the property to be deleted has the attribute { [[Configurable]]: false } (or otherwise cannot be deleted), a TypeError exception is thrown.

Note 2

The object that may be created in step 4.c is not accessible outside of the above abstract operation and the ordinary object [[Delete]] internal method. An implementation might choose to avoid the actual creation of that object.

13.5.2 The void Operator

13.5.2.1 Runtime Semantics: Evaluation

UnaryExpression : void UnaryExpression
  1. Let expr be ? Evaluation of UnaryExpression.
  2. Perform ? GetValue(expr).
  3. Return undefined.
Note

GetValue must be called even though its value is not used because it may have observable side-effects.

13.5.3 The typeof Operator

13.5.3.1 Runtime Semantics: Evaluation

UnaryExpression : typeof UnaryExpression
  1. Let val be ? Evaluation of UnaryExpression.
  2. If val is a Reference Record, then
    1. If IsUnresolvableReference(val) is true, return "undefined".
  3. Set val to ? GetValue(val).
  4. If val is undefined, return "undefined".
  5. If val is null, return "object".
  6. If val is a String, return "string".
  7. If val is a Symbol, return "symbol".
  8. If val is a Boolean, return "boolean".
  9. If val is a Number, return "number".
  10. If val is a BigInt, return "bigint".
  11. Assert: val is an Object.
  12. NOTE: This step is replaced in section B.3.6.3.
  13. If val has a [[Call]] internal slot, return "function".
  14. Return "object".

13.5.4 Unary + Operator

Note

The unary + operator converts its operand to Number type.

13.5.4.1 Runtime Semantics: Evaluation

UnaryExpression : + UnaryExpression
  1. Let expr be ? Evaluation of UnaryExpression.
  2. Return ? ToNumber(? GetValue(expr)).

13.5.5 Unary - Operator

Note

The unary - operator converts its operand to a numeric value and then negates it. Negating +0𝔽 produces -0𝔽, and negating -0𝔽 produces +0𝔽.

13.5.5.1 Runtime Semantics: Evaluation

UnaryExpression : - UnaryExpression
  1. Let expr be ? Evaluation of UnaryExpression.
  2. Let oldValue be ? ToNumeric(? GetValue(expr)).
  3. If oldValue is a Number, then
    1. Return Number::unaryMinus(oldValue).
  4. Else,
    1. Assert: oldValue is a BigInt.
    2. Return BigInt::unaryMinus(oldValue).

13.5.6 Bitwise NOT Operator ( ~ )

13.5.6.1 Runtime Semantics: Evaluation

UnaryExpression : ~ UnaryExpression
  1. Let expr be ? Evaluation of UnaryExpression.
  2. Let oldValue be ? ToNumeric(? GetValue(expr)).
  3. If oldValue is a Number, then
    1. Return Number::bitwiseNOT(oldValue).
  4. Else,
    1. Assert: oldValue is a BigInt.
    2. Return BigInt::bitwiseNOT(oldValue).

13.5.7 Logical NOT Operator ( ! )

13.5.7.1 Runtime Semantics: Evaluation

UnaryExpression : ! UnaryExpression
  1. Let expr be ? Evaluation of UnaryExpression.
  2. Let oldValue be ToBoolean(? GetValue(expr)).
  3. If oldValue is true, return false.
  4. Return true.