• JavaScript
  • Your first website: Adding interactivity
  • Introduction
  • Functions
  • Regular expressions
  • Using classes
  • Internationalization
  • Client-side web APIs
  • Enumerability and ownership of properties
  • Memory Management
  • Array
  • AsyncGeneratorFunction
  • BigInt64Array
  • Date
  • encodeURIComponent()
  • escape() Deprecated
  • Float16Array
  • Generator
  • Int8Array
  • InternalError Non-standard
  • Iterator
  • NaN
  • parseInt()
  • ReferenceError
  • SharedArrayBuffer
  • Temporal Experimental
  • Uint8ClampedArray
  • unescape() Deprecated
  • WeakSet
  • Assignment (=)
  • Bitwise AND (&)
  • Bitwise OR assignment (|=)
  • Comma operator (,)
  • Destructuring
  • Exponentiation (**)
  • Greater than (>)
  • import.meta.resolve()
  • Inequality (!=)
  • Less than (<)
  • Logical NOT (!)
  • Multiplication assignment (*=)
  • Nullish coalescing assignment (??=)
  • Optional chaining (?.)
  • Right shift (>>)
  • Strict inequality (!==)
  • this
  • Unsigned right shift (>>>)
  • yield*
  • Block statement
  • continue
  • export
  • for...in
  • if...else
  • let
  • try...catch
  • with Deprecated
  • get
  • The arguments object
    1. callee Deprecated
    2. extends
    3. Static initialization blocks
  • Character class escape: \d, \D, \w, \W, \s, \S
  • Input boundary assertion: ^, $
  • Modifier: (?ims-ims:...)
  • Quantifier: *, +, ?, {n}, {n,}, {n,m}
  • Errors
    1. RangeError: argument is not a valid code point
    2. RangeError: invalid array length
    3. RangeError: repeat count must be less than infinity
    4. ReferenceError: assignment to undeclared variable "x"
    5. SyntaxError: 'arguments'/'eval' can't be defined or assigned to in strict mode code
    6. SyntaxError: \ at end of pattern
    7. SyntaxError: await is only valid in async functions, async generators and modules
    8. SyntaxError: continue must be inside loop
    9. SyntaxError: function statement requires a name
    10. SyntaxError: identifier starts immediately after numeric literal
    11. SyntaxError: invalid assignment left-hand side
    12. SyntaxError: invalid class set operation in regular expression
    13. SyntaxError: invalid property name in regular expression
    14. SyntaxError: invalid unicode escape in regular expression
    15. SyntaxError: missing ) after argument list
    16. SyntaxError: missing } after property list
    17. SyntaxError: missing variable name
    18. SyntaxError: numbers out of order in {} quantifier.
    19. SyntaxError: property name __proto__ appears more than once in object literal
    20. SyntaxError: rest parameter may not have a default
    21. SyntaxError: super() is only valid in derived class constructors
    22. SyntaxError: unlabeled break must be inside loop or switch
    23. TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed
    24. TypeError: "x" is not a function
    25. TypeError: BigInt value can't be serialized in JSON
    26. TypeError: can't convert BigInt to number
    27. TypeError: can't redefine non-configurable property "x"
    28. TypeError: class constructors must be invoked with 'new'
    29. TypeError: Initializing an object twice is an error with private fields/methods
    30. TypeError: Iterator/AsyncIterator constructor can't be used directly
    31. TypeError: property "x" is non-configurable and can't be deleted
    32. TypeError: X.prototype.y called on incompatible type
    33. JavaScript technologies overview
    34. Strict mode
    35. Proxy and Proxy objects allow you to intercept certain operations and to implement custom behaviors.

      For example, getting a property on an object:

      js
      const handler = {
        get(target, name) {
          return name in target ? target[name] : 42;
        },
      };
      
      const p = new Proxy({}, handler);
      p.a = 1;
      console.log(p.a, p.b); / 1, 42
      

      The Proxy object defines a target (an empty object here) and a handler object, in which a get trap is implemented. Here, an object that is proxied will not return undefined when getting undefined properties, but will instead return the number 42.

      Additional examples are available on the Proxy reference page.

  • Terminology

    The following terms are used when talking about the functionality of proxies.

    handler

    Placeholder object which contains traps.

    traps

    The methods that provide property access. (This is analogous to the concept of traps in operating systems.)

    target

    Object which the proxy virtualizes. It is often used as storage backend for the proxy. Invariants (semantics that remain unchanged) regarding object non-extensibility or non-configurable properties are verified against the target.

    invariants

    Semantics that remain unchanged when implementing custom operations are called invariants. If you violate the invariants of a handler, a TypeError will be thrown.

    Handlers and traps

    Revocable Proxy

    The Proxy.revocable() method is used to create a revocable Proxy object. This means that the proxy can be revoked via the function revoke and switches the proxy off.

    Afterwards, any operation on the proxy leads to a TypeError.

    js
    const revocable = Proxy.revocable(
      {},
      {
        get(target, name) {
          return `[[${name}]]`;
        },
      },
    );
    const proxy = revocable.proxy;
    console.log(proxy.foo); / "[[foo]]"
    
    revocable.revoke();
    
    console.log(proxy.foo); / TypeError: Cannot perform 'get' on a proxy that has been revoked
    proxy.foo = 1; / TypeError: Cannot perform 'set' on a proxy that has been revoked
    delete proxy.foo; / TypeError: Cannot perform 'deleteProperty' on a proxy that has been revoked
    console.log(typeof proxy); / "object", typeof doesn't trigger any trap
    

    Reflection

    proxy handler's.

    Reflect is not a function object.

    Reflect helps with forwarding default operations from the handler to the target.

    With in operator as a function:

    js
    Reflect.has(Object, "assign"); / true
    

    A better apply() function

    Before Reflect, you typically use the array-like object).

    js
    Function.prototype.apply.call(Math.floor, undefined, [1.75]);
    

    With Reflect.apply this becomes less verbose and easier to understand:

    js
    Reflect.apply(Math.floor, undefined, [1.75]);
    / 1
    
    Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]);
    / "hello"
    
    Reflect.apply(RegExp.prototype.exec, /ab/, ["confabulation"]).index;
    / 4
    
    Reflect.apply("".charAt, "ponies", [3]);
    / "i"
    

    Checking if property definition has been successful

    With Reflect.defineProperty() returns a Boolean success status, you can just use an if...else block here:

    js
    if (Reflect.defineProperty(target, property, attributes)) {
      / success
    } else {
      / failure
    }