Considerations for switching JavaScript modes

  • Release version: Xanadu
  • Updated August 1, 2024
  • 3 minutes to read
  • Summarize
    Summarized using AI
    This content was generated using new OpenAI-powered functionality. Results are provided on an as is basis and are not guaranteed to be accurate or complete.

    Summary of Considerations for switching JavaScript modes

    Switching the JavaScript mode in a ServiceNow application or script can significantly impact how existing scripts behave. It is important for customers to understand these behavior changes to avoid unexpected issues and ensure smooth transitions. This guidance compares three JavaScript modes used in ServiceNow environments: Compatibility Mode (pre-ES5), ES5 Standards Mode, and ECMAScript 2021 (ES12).

    Show full answer Show less

    Key Behavior Differences Across JavaScript Modes

    • Arguments Object:
      • In Compatibility Mode, the arguments object is not strict, so modifications affect original parameters.
      • ES5 and ES12 use strict mode where arguments do not reflect parameter modifications and throw errors if misused.
    • Boolean Overrides:
      • Primitive Booleans can be overridden in Compatibility Mode, causing unexpected behavior.
      • ES5 and ES12 restrict Boolean overrides, with ES12 enforcing stricter protections, especially in conditional expressions.
    • Syntax Errors:
      • Compatibility Mode has inconsistent runtime error handling.
      • ES5 improves syntax error detection and provides clearer error messages.
      • ES12 further enhances error robustness and clarity.
    • Increment/Decrement Operations:
      • Allowed on variables in all modes, but ES5 and ES12 provide improved clarity and stricter rules, especially with const.
    • Line Continuations:
      • Allowed with backslash in Compatibility and ES5 modes but discouraged due to readability.
      • ES12 introduces template literals as a better alternative for multiline strings.
    • Missing Semicolons:
      • Compatibility Mode performs automatic semicolon insertion (ASI), which can cause unexpected behavior.
      • ES5 and ES12 throw syntax errors if semicolons are missing, encouraging explicit usage.
    • Calling Non-Existent Functions:
      • Compatibility Mode throws ReferenceError.
      • ES5 throws TypeError if a non-function is called.
      • ES12 throws an EcmaError for non-existent functions or properties.
    • Accessing Non-Existent Properties:
      • All modes return undefined without throwing errors when accessing missing properties.
    • Numeric Literals:
      • Compatibility Mode supports basic decimal and hexadecimal literals.
      • ES5 adds stricter parsing and better handling.
      • ES12 adds binary (0b), octal (0o), and BigInt (123n) literals for enhanced numeric handling.
    • Reserved Keywords as Properties:
      • Compatibility Mode disallows reserved keywords as property names.
      • ES5 and ES12 allow reserved keywords as property names without errors.
    • Treating let and yield as Keywords:
      • Compatibility Mode allows these as identifiers.
      • ES5 treats let as a keyword and reserves yield in strict mode.
      • ES12 treats both as keywords and throws syntax errors if used as identifiers.

    Practical Implications for ServiceNow Customers

    When switching JavaScript modes, ServiceNow customers should expect stricter syntax enforcement, improved error handling, and enhanced language features in ES5 and ES12 modes compared to Compatibility Mode. This transition can help write more predictable and maintainable scripts but may require revisiting existing code to address stricter rules (such as explicit semicolons, reserved keywords, and argument behavior).

    Understanding these distinctions aids in troubleshooting issues arising post-switch and encourages adoption of modern JavaScript practices supported by ServiceNow’s evolving platform.

    Switching the JavaScript mode for an application or script might change the behavior of existing scripts. Review some examples of behavior changes before switching JavaScript modes or to troubleshoot any issues that you experience after switching.

    For more information about each JavaScript mode, see JavaScript modes and JavaScript engine feature support.

    This table highlights how JavaScript behavior has evolved from the lenient and error-prone pre-ES5 environment, to the stricter and more predictable ES5, and lastly the more feature-rich environment of ES12 (ECMAScript 2021).

    Table 1. Behavioral differences in JavaScript modes
    Feature Compatibility Mode ES5 Standards Mode ECMAScript 2021 (ES12)
    Arguments object The arguments object exists, but there's no strict mode, so modifications reflect on arguments. Prints:
    *** Script: [object Arguments]
    *** Script: [object Arguments]
    *** Script: [object Arguments]
    *** Script: 123
    In strict mode, the arguments object doesn’t reflect parameter modifications and throws an error. Prints:
    sn_es5: 123
    sn_es5: undefined
    sn_es5: [object Arguments]
    sn_es5: 123
    The same as ES5.
    Boolean overrides Primitive Booleans (true, false) can be overridden, causing unexpected behavior. Primitive Booleans are more protected, though still can be overridden when assigned to variables. The same as ES5, but strict mode helps prevent some assignments. The conditional expression should be written in this form:
    (cond_expr instanceof Boolean ? cond_expr.valueOf() : cond_expr).
    Exception for syntax errors Syntax errors throw exceptions at runtime. Error handling is inconsistent. Example:
    Javascript compiler exception: unterminated string literal (null.null.script; line 1) in:
    var b = '
    More consistent syntax error handling, especially in strict mode. Example:
    Evaluator: com.glide.script.RhinoEcmaError: unterminated string literal
       script : Line(1) column(9)
    ==>   1: var b = '
    The same as ES5, but with more robust handling and clearer error messages in updated engines. Example:
    SyntaxError: Unterminated string constant at line 1
    
    ==>   1: var b = '
    Increment and decrement Allowed on variables but could behave unexpectedly with complex expressions. Prints:
    *** Script: c: 1
    *** Script: gr.related_incidents: 1
    *** Script: 2
    *** Script: 3
    Improved clarity, but still allowed on variables (var, let, const). Prints:
    sn_es5: c: 0
    sn_es5: gr.related_incidents: 1
    sn_es5: 1
    sn_es5: 2
    The same as ES5, with stricter rules in some contexts (for example, const).
    Line continuations Allowed with a backslash (\) but discouraged due to readability issues. In this example, all three functions are called.
    var expr = doFoo();  // do foo
               doBar();  // do bar 
               finish();   // all done
     eval(expr);
    
    Same as Compatibility mode; no change in handling line continuations. In the previous example, ES5 only calls the first function and treats everything after the first comment including the newline as comment until the expression end. The same as ES5, but template literals provide a more readable alternative.
    Missing semicolons Automatic semicolon insertion (ASI) often led to unexpected behavior. Throws a syntax error when a semicolon is missing. The same as ES5. Updated practices encourage explicit semicolons.
    Non-existent functions Calling a non-existent function throws a ReferenceError. Throws a TypeError if a non-function is called. Throws an EcmaError when a non-existent function is called or a property is referenced.
    Non-existent properties Accessing a non-existent property returns undefined; no error thrown. Same as pre-ES5. The same as Compatibility mode and ES5 Standards mode.
    Numeric literals Basic decimal and hexadecimal literals. Introduced stricter parsing rules and better handling of numeric literals. Added binary (0b), octal (0o), and BigInt literals (123n).
    Reserved keyword as property Using reserved keywords isn't possible. Reserved keywords can be used as property names without error, for example, obj.for. Prints the object when returned. The same as ES5.
    Treat let and yield as keywords let and yield aren’t keywords and can be used as identifiers only. let is introduced as a keyword. yield is reserved in strict mode. Both are keywords. Using them as identifiers throws syntax errors.