Using only functional-style array methods to get the unique values in an array:
const sampleArray = [1, 2, 1, 3, 4]; // note "1" is repeated
const uniqueArray = sampleArray.filter( (value, idx, arr) => arr.indexOf(value) === idx );
console.log(uniqueArray);
// expected output is [1, 2, 3, 4]
This JS snippet takes advantage of two things:
JSON.stringify() accepts a second parameter called "the replacer parameter". This parameter can be:
An array: the values in the function represent which keys of the object should be stringifyed into JSON. Anything not in the array is left out of the JSON string.
A function: the function accepts 2 parameters - key and value. The return value of this function is what will be inserted into the JSON object for the given key. Returning undefined omits the key from the JSON object. This allows you to provide custom logic when stringifying objects to JSON
Javascript functions can return other functions, and the inner function has access to the scope of the outer function, making it useful to store variables persistently between function calls, for example:
var checkCookie = function() {
var lastCookie = document.cookie; // 'static' memory between function calls
return function() {
var currentCookie = document.cookie;
if (currentCookie != lastCookie) {
// something useful like parse cookie, run a callback fn, etc.
lastCookie = currentCookie; // store latest cookie
}
};
}();
window.setInterval(checkCookie, 100); // run every 100 ms
// example object:
let demo = {one: 1, two: 2}
// pick subset of keys
let {one} = demo
// rename variables
let {one: anotherOne} = demo
// "one" renamed to "anotherOne"
// provide default values
let {three = 3, one} = demo
// since "three" doesn't exist in demo, it's given the default value of "3"
// gather the rest
let {one, ...rest} = demo
//"rest" will contain anything from "demo" which is not "one"
We can only await for an actual result from a promise within an async function, while the async function itself will always return a promise. For example:
const demo = async () => {
const response = await Axios.get("http://example.com")
//"response" will contain the actual JS object
}
const p = demo()
// "p" will contain a pending promise, NOT the actual data
JS classes allow you to define custom setters & getters, for example:
class XYZ extends ... {
constructor {
this.name = 'demo';
}
get name() {
// here perform any functionality that is called when a user gets the "name" var
}
set name( value ) {
// here perform any functionality that is called when a user set the "name" var
}
}
// for example:
example1 = new XYZ()
example1.name = "ex1" // passes through the "set name(value) function defined above
console.log(example1.name) // passes through the get name() function defined above
Notice how getters and setters affect properties, i.e. example1.name, not example1.name()
JS Proxy objects act as middleware for objects. For example:
const handler = {
get : function( obj, prop, value ) { ... }
}
const proxiedObj = new Proxy( initialObj, handler )
Note the "handler" in the second argument to "Proxy". The results from this handler can be returned to the initial object (first argument to "Proxy").
Use cases:
set filtering to validate input to variables
Because the JSON grammar is much simpler than JavaScript’s grammar, JSON can be parsed more efficiently than JavaScript.
Instead of inlining the data as a JavaScript object literal, like so:
const data = { foo: 42, bar: 1337 }; // 🐌
…it can be represented in JSON-stringified form, and then JSON-parsed at runtime:
const data = JSON.parse('{"foo":42,"bar":1337}'); // 🚀
As long as the JSON string is only evaluated once, the JSON.parse
approach is much faster compared to the JavaScript object literal, especially for cold loads.
function addition(x, y) {
return x + y;
}
const plus5 = addition.bind(null, 5)
plus5(10) // output -> 15
Note the use of .bind above, which returns another function ("plus5") which has the "x" input by default set to null, and "y" set to 5 by default. This way xalling plus5 with just the "x" variable set (as per last line) won't result in null, because "y" is set by default
Function Properties are a good alternative to globally scoped variables. For example:
const greet = () => {
...
console.log(1 + greet.var1) // outputs 124
...
}
greet.var1 = 123; // actual function property
All instances of the "greet" function have access to the same value of greet.var1
function variables = "static variables"
elem = document.getElementById('some_id');
// find first parent (move up)
elem.closest('.some_class');
//find first child (move down)
elem.querySelector('.some_class')