VERSIONS
ECMAScript 2015 == ES2015 == ES6.
ES5 is 2009
ServiceNow uses ECMA 262 == ES5.1 (from June 2011)
Versions are named ES1-ES6 and then ECMA2016-
Pseudo ES names: ES7 ~ ECMA2016; ES8 ~ ECMA2017. I guess x in ESx ~ year+1
ES6 adds:
ES6 Class
ES6 Modules = import, export
=> Arrow Functions
const, let
Array iterator functions
Destructuring [x,y]= or {x,y}=
Ternary a?b:c
... var args REST Operator. Gets an actual Array.
ECMA2018/ES9 adds:
Spread/rest Operator ... === elements-of
??? When were private # class members added??? Still doesn't work in IE.
??? Similar availability, ?. is conditional/optional chaining operator.
x?.y?.z gives undefined if x anything other than an object with an 'x' member
OR x.y is anything other than an object with a z member.
Also works for Array element references where the Array may not exist. The syntaxt is just
a little non-intuitive: x.optArray?.[3]
x must be defined
Destructuring is both [a,b] = [blah, blah] and const {v1, v2} = anObj;
?? is simlar "Nullish coalescing operator.
If x is null or undefined then specified string; otherwise x.
??= "nullish coaslescing assignment" or "logical nullish assignment"
Spread/rest operator examples
GOTCHA: Sometimes must have () surrounding the {}s!
In param lists this is called "Rest parameters".
const concatAr = [...a1, ...a2]; # effectively same as: newArr = arr1.concat(arr2);
const [a, b, ...remainders] = [some,ar,ray];
const concatMap = {...m1, ...m2};
Functions can be used like static classes.
Just define a function in style FName = Function() {...};
and after that add attributes to it like: FName.x =...;
Can use the fName.x attributes inside the function body.
To skip function param placeholder params, don't use dummy variable name 'undefined' because
that would override system's undefined value.
Instead use a dummy variable name, and add eslint directive to cover it, like
"no-unused-vars": ["error", {"args": "all", "argsIgnorePattern": "^_?dummy" }],
Versions: https://en.wikipedia.org/wiki/ECMAScript#Versions
Comparing to zero.
x === 0 and x === 0.0 both work and are equivalent.
Just make sure that your values are both numbers!
Consider Lodash library for basic JS utilities.
BUT ES6 may eliminate need. See
https://www.sitepoint.com/lodash-features-replace-es6/
_toParis(dict) looks good for displaying
OR https://www.npmjs.com/package/prettyprint
Single and double scripts are interchangeable.
But JSON has requirements for double-quotes.
JSON
Keys must be double-quoted strings. Nothing else allowed for a key!
NOT WITH ES6!! May be Objects!
Newlines and Carriage returns are encoded as \n and \r, even for Groovy pretty-printed JSON.
No comments of any type allowed from JavaScript, even Node.js.
(Node.js's ESLint enhances to support comments).
Values therefore never span lines.
var reconstitutedObj = JSON.parse(JSON.stringify(oldObject));
Inline reconstitution of an encoded JSON string:
server side Java:
import org.apache.commons.lang.StringEscapeUtils;
StringEscapeUtils.escapeJavaScript(gson.toJson(o));
server side Groovy:
import groovy.json.JsonOutput
import groovy.json.StringEscapeUtils
println StringEscapeUtils.escapeJavaScript(JsonOutput.toJson(o))
web side: $.parseJSON("LITERAL_JSON_STRING"); // requires jQuery
Positioning by Javascript generally makes CSS settings, so see the css.txt file.
html.txt has much relevant information too.
Setting styles with vanilla JS: document.getElementById(id).style.sName = sVal;
IE
IE GOTCHA!!!! FF ignores trailing commas at the end of lists.
IE inserts a final undefined value after the comma. In many cases, that
undefined causes the interpreter to throw with a very non-intuitive message.
LESSON: Make sure not to leave any dangling commas at end of lists.
IE7 ALWAYS adds a tbody to tables, even to
and it will even
wrap th cells except that the tbody will not enclose a thead that you
have added. I.e., there is no distinction between th and td, but it
will honor specified thead's.
FREAKING CRAZY! IE7 automatically assigns Elements to global variables
(with var names of the ID names) as soon as Elements with ids are added to
the page, or as soon as an id is assigned (or re-assigned) to an Element
already on the page UNLESS SUCH A GLOBAL VARIABLE HAS ALREADY BEEN DECLARED
implicitly or explicitly. If you attempt to reassign, you get this Error:
"Object doesn't support this property or method."
Makes no difference if the item is instantiated with HTML or with
PrototypeJS Element or W3C HTMLElement; nor whether added to page with
W3C body.appendChild() or PrototypeJS insert().
To work around that Craziness, defeat this bad behavior by coding, at a
code location before any element may be instantiated. I.e. in the page
before any scriplets. Either
I. Explicit declarations anywhere in the first scriplet:
var tagId1, tagId2,...;
OR
II. Implicit declarations by assignment at top of first scriplet:
tagId1 = tagId2... = undefined;
http://www.javascripttoolbox.com
(incl. pop-up calendars and Data formatters and validators). NO MILLIS!!!!
sprintf: http://www.webtoolkit.info/javascript-sprintf.html
(webtoolkit.sprintf.js)
typeof(n) === "number" evaluates true for NaN,
so usually whenever checking 'typeof(x) ?== "number"〕, should also check:
isNaN(n).
NaN===Nan evaluates to false, so must use isNaN(x)
Type conversion:
In some cases you have to counter-intuitively use parseX(...). E.g.
myInt = parseInt(4.533);
To test parseInt output, use isNaN(x).
To convert anything at all to string use String(thing). Safe to convert from
strings and null too. N.b. "String(x)", NOT "new String(x);".
int->char: String.fromCharCode(65); // is a String
Test for int: Number.isInteger() AND parseInt(x) === x
Convert into number: Number(x)
To round to an integer: Math.round(2.1) or Math.round(Number("2.1"))
Rounding (not truncation!) to non-integer number: Number(2.12.toFixed(1))
decimal precision:
printf-like numerical formatting: (12.345).toFixed(2) or v.toFixed(2)
and others as described by answer "Number Formatting in JavaScript" at
GOTCHA!! toFixed often does convert to text. Why!? So: Number(x.toFixed(3));
Docs say that toFixed converts to a string, but quirk is that literal numeric
constants (with no parens) -> numbers; 1.23.toFixed(3) -> number SOMETIMES!
https://stackoverflow.com/questions/610406/javascript-equivalent-to-printf-string-format#4673436
Convert to a boolean by an expression: Boolean(10 > 9)
Similar to: var b = 10 > 0
Int (number) to hex string: n.toString(16)
Funny thing about strings is, you can use str[i] instead of str.charAt(i), but
"str[i] = 'x';" has no effect (must use splice or deconstruct to modify chars).Safer and recommended to not use str[i]. Always use str.charAt(i).
Impossible to check if a variable has been declared or assigned to but has
been assigned 'undefined'.
Checking for non-undefined assignedness of variable 'v' (not for v.x if v not obj):
(typeof v !== "undefined')
Testing for types:
"typeof var" returns just "object" for all Objects AND NULL!
(values "undefined", "object" (for null or any Object instance),
"boolean", "number", "string", "function", "xml")
THIS IS THE ONE CASE WHERE YOU CAN REFERENCE A VARIABLE BEFORE IT IS
DECLARED (implicitly or explicitly), but you can't do "typeof nonobj.attr".
CRAZINESS: typeof null === "object", but if try to do nullVar.x then
will throw with message: Cannot convert null to an object
"var instanceof ClassName" works great.
Be aware of very low precedence, so e.g.: if (!(var instanceof CName))
But there are some more convenience functions for OOTB classes, like
Array.isArray()
Test for real number integer: Number.isInteger
It is safe to run "var instanceof ClassName" even if var isn't an Object
or is null or even undefined. (As always it must be declared at least
implicitly before being referenced in any way).
Test for Array: x instanceof Array
(Only "{} instanceof" produces syntax error and only in browser JS debuggerr).
Test for plain dictionary:
typeof obj === "object" && obj !== null && obj.constructor === Object
OR with jQuery: $.isPlainObject(obj)
I think best to call these "plain objects".
Great article about this:
https://masteringjs.io/tutorials/fundamentals/pojo
I prefer: typeof(o) === "object" && o !== null &&
Object.getPrototypeOf(o) === Object.getPrototypeOf({});
JavaScript scriptlet = Value of a single callback attr. or content of a
single
Objects don't work for keys. At least HTML elements do not.
Intead, keep a list and a map keyed by el.id.
As stated above, object keys are always string constants.
SCOPE IN HTML pages
Vars declared inside of functions, including jQuery $(function(){...}), definitely are not
accessible above (from the Window context).
Though in JavaScript variable declarations are moved to top of block so they can be used before declared, different