Place Holder Products Code
Bash MySQL
Notes Return of the Fed Login
Admin Control Panel Email Control Panel Product Control Panel Debug Info Beacon Create Snippet Tag Control Panel

JavaScript

By Ref, By Val


WARNING - Everything except Objects and Arrays are copied by value.

Example of array copy by reference - a potential gotcha:

let things = ["thing1", "thing2"];
let different_things = things;
different_things.push("thing3");

> things
// [ 'thing1', 'thing2', 'thing3' ]

Create a shallow copy of an Object:

let obj = Object(key : "val");
let copy = Object.assign({}, obj);

Create a shallow copy of an Array:

let ar = ["thing1", "thing2"];
let copy = ar.slice();

Objects and Arrays can also be copied by JSONifying them.  This produces a deep copy, however there are some caveats.

Functions, for instance, can't be copied this way.  Basically anything that can't be represented without finagling in JSON won't work.

let thing = Object();
let copy = JSON.parse(JSON.stringify(thing));

A custom deep copy function might look something like this.  Here we use recursion to delve into Objects and Arrays in order to copy their contents by value:

Note that the same caveats as JSONifying an Object apply here, however we can handle them specifically, as we've done here with Dates.

function deepCopy(obj) {
    let result = Object();
    if (Array.isArray(obj)) {
        result = Array();
    }
    for (let key in obj) {
        const prop = obj[key];
        if (prop !== null && prop !== undefined && typeof prop === 'object') {
            // Handle special types of Objects here:
            if (prop.constructor === Date) {
                result[key] = new Date(prop.getTime());
            } else {
                result[key] = deepCopy(prop);
            }
        } else {
            result[key] = prop;
        }
    }
    return result;
}

Ajax


Ajax, which stands for Asynchronous JavaScript and XML, is an ubiquitous feature of web applications.  It allows asynchronous requests to be fired from JavaScript.

Nicely patterned AJAX call using jQuery:

let that = this;
$.ajax({
  url : the.server.api,
  data : {
      "key"     : val,
      "key2"    : val2,
    },
  type : "GET",         // ie. GET, POST
  dataType : "json",    // If result is NOT of type, throw error
})
.done(function(jqxhr, status, exception) {
  // On Success
  // data: xhr object
  // textStatus : "error"
  // xhr: "Internal Server Error"
  console.log(jqxhr)
})
.fail(function(jqxhr, status, exception) {
  // On Failure
  console.error("API request failed with " + jqxhr.status); // ie. 200, 404, 500
})
.always(function(jqxhr, status, exception) {
  // Do Always
})

Array Operations


Array Ops at a Glance:

unshift                     pop
----->                      ----->
      [0, 1, 2, ..., n-1, n]
<-----                      <-----
shift                       push

Both pop() and shift() return a single element, AND modify the array:

let l = [0,1,2,3,4];
l.pop()
// 4
l
// [0,1,2,3]

let l = [0,1,2,3,4];
l.shift()
// 0
l
// [1,2,3,4]

Both push() and unshift() return the Array's new length, AND modify the Array:

let l = [0,1,2,3,4];
l.push(5);
// 6
l
// [ 0, 1, 2, 3, 4, 5 ]
l.unshift(6);
// 7
l
// [ 6, 0, 1, 2, 3, 4, 5 ]

Arrays can be concatenated with .concat():

[].concat([1,2,3,4,5],[6,7,8])
// [ 1, 2, 3, 4, 5, 6, 7, 8 ]

Find the intersection of two Arrays of primitives:

[1, 2, 3].filter(value => [3, 4, 5].includes(value))
// [3]

Map


Map creates a new array by mapping each element in the original array to an element in the new array via the passed function.  We'll use the following list for examples:

let list = [
	{name : "name 1", val: 1},
	{name : "name 2", val: 2},
	{name : "name 3", val: 3},
	{name : "name 4", val: 4},
];

Example of map returning a single property from each member function:

list.map(o => o.val);
// [ 1, 2, 3, 4];

Example evaluating Array elements:

list.map(o => o.val > 1);
// [ false, true, true, true]

Example evaluating Array elements with long-form function argument:

list.map(function(o) {
  return o.val > 1
});
// [ false, true, true, true]

Reduce


Reduce reduces an array to a single value.  We'll use the following list for examples:

let list = [
	{name : "name 1", val: 1},
	{name : "name 2", val: 2},
	{name : "name 3", val: 3},
	{name : "name 4", val: 4},
];

Example reducing an array of integers to their sum:

[1,2,3,4,5].reduce((a,b) => a + b);
// 15

Example reducing an array of strings to their "sum":

["house","by","the","sea"].reduce((a,b) => a + " " + b);
// 'house by the sea'

If we try to do the same thing with elements of different types, the result may be unexpected:

list.reduce((a,b) => a + b.val);
// '[object Object]234'

To do the same thing to objects, we need to also pass a second argument to reduce, the initialValue:

list.reduce((a,b) => a + b.val, 0);
// 10

Filter


Simple filter on an array of objects.  This will create a new array with only objects whose val prop is larger than 6.

let list = [
	{name : "name 1", val: 1},
	{name : "name 2", val: 2},
	{name : "name 3", val: 3},
	{name : "name 4", val: 4},
	{name : "name 5", val: 5, obj : {obj_val : 1}},
	{name : "name 5", val: 5, obj : {obj_val : 2}},
];

list.filter(o => o.val < 3);
// [{name : "name 1", val: 1},{name : "name 2", val: 2}]

Loops


Loop shorthand takes two distinct forms, in and of.  The following examples make use of this Array:

let list = [
    {name : "Elephant", size : 15, props : {color: "grey"}},
    {name : "Lion", size : 12, props : {color: "gold"}},
    {name : "Stork", size : 6, props : {color: "white"}},
    {name : "Ardvark", size : 4, props : {color: "brown"}},
];

Use in to iterate over Array keys:

for (o in list) { console.log(o) };
// 0, 1, 2, 3

Use of to iterate over Array elements:

for (o of list) { console.log(o.name) };
// Elephant, Lion, Stork, Ardvark

We can also use a slightly longer format, that makes it much clearer what the variable represents:

for (let key in list) { 
    const item = list[key];
    console.log(item.name);
};
// Elephant, Lion, Stork, Ardvark

Miscellaneous


Time Execution:

var t0 = performance.now();
// Do Something
var t1 = performance.now();
console.log("loadData() selection took " + (t1 - t0) + " milliseconds.")

Find the maximum value from an Array list of Objects with property val and return value:

Math.max.apply(Math, list.map(function(o) { return o.val; }))

Produce all combinations of array members:

getCombn(arr, pre) { 
    pre = pre || ''; 
    if (!arr.length) { 
        return pre; 
    }
    let that = this;
    var ans = arr.reduce(function(ans, value) { 
        return ans.concat(that.getCombn(arr.slice(1), pre + value)); 
    }, []); 
    return ans; 
}