Last active
February 14, 2020 22:36
-
-
Save dominikkaegi/4a48d21828bc793fb5242396924a2e67 to your computer and use it in GitHub Desktop.
An overview of destructing objects and arrays
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ----------------------------------------------------- | |
| // --------------- DESTRUCTERING --------------- | |
| // ----------------------------------------------------- | |
| // ------- NON-NESTED ARRAYS --------------- | |
| // Simple Destructering | |
| function foo() { | |
| return [1, 2, 3] | |
| } | |
| var [ | |
| a, | |
| b, | |
| c, | |
| ..rest | |
| ] = foo() || [] | |
| // a = 1, b = 2, c = 4, rest = [] | |
| // Destructering with Default Types | |
| var [ | |
| a, | |
| b = 42, | |
| c, | |
| ...rest | |
| ] = [1, , 3, 4, 5, , 7] | |
| // a = 1, b = 42, c = 3, rest = [4, 5, undefined, 7] | |
| // The Destructering has nothing to do with declaration. If we have 'a, b, c and rest' already declared somewhere | |
| // in our code we could neglect the var in front of the Destructering patter | |
| var a, b, c, rest; | |
| [ | |
| a, | |
| b, | |
| c, | |
| ...rest | |
| ] = [1, 2, 3, 4, 5] | |
| // a = 1, b = 2, c = 3, rest = [4, 5] | |
| // The only constraint there is for destructering, that they need to be a valid left hand side | |
| // of an asignedment. We could forexample directly add them as a property to an object. | |
| var obj = {} | |
| [ | |
| obj.a, | |
| obj.b, | |
| obj.c, | |
| ...obj.rest | |
| ] = [1, 2, 3, 4, 5] | |
| // obj is now filled up with following properties | |
| // { | |
| // a: 1, | |
| // b: 2, | |
| // c: 3, | |
| // rest: [ | |
| // 4, | |
| // 5 | |
| // ] | |
| // } | |
| // Swaping Values | |
| var x = 10, y =20 | |
| [x, y] = [y, x] | |
| // x = 20, y = 10 | |
| // "Throwing away the first value of an array and adding one at the end" | |
| var a = [1, 2, 3] | |
| var x | |
| [x, x, ...a] = [ 0, ...a, 4] | |
| // a = [2, 3, 4] | |
| // But you don't even need an x for this, as array destructering allow you an empty slots | |
| var a = [1, 2, 3] | |
| [, , ...a] = [ 0, ...a, 4] | |
| // ---------- NESTED ARRAYS ------- | |
| var a, b, c, rest | |
| [ | |
| a, | |
| b, | |
| c, | |
| ...rest | |
| ] = [1, 2, 3, [4,5,6]] | |
| // a = 1, b = 2, c = 3, rest = [ [4, 5, 6] ] | |
| var a, b, c, rest | |
| [ | |
| a, | |
| b, | |
| c, | |
| [ | |
| d, | |
| ..rest | |
| ] | |
| ] = [1, 2, 3, [4,5,6]] | |
| // a = 1, b = 2, c = 3, d = 4, rest = [5, 6] | |
| // ----- RESULT OF A DESTRUCTERING PATTER ---------- | |
| // The return value of a destructering pattern is always the object / array which has been destructered | |
| // This can be confusing, as one could think that the return value is an array of the destructered values, because | |
| // [a, b] seems to be an array, but it is not an array, it is a pattern on how to break down an array. | |
| function foo() { | |
| return [1, 2, 3, [4,5,6] ] | |
| } | |
| var a, b | |
| var x = [a, b] = foo() | |
| // x = [1, 2, 3, [4,5,6] ] | |
| // The destructering assignement is not creating a new sub array of two items. It is breaking down the array | |
| // according to a pattern | |
| // Because a destructering assignement is returning the object / array itself, you can also | |
| // chain multiple destructering assignment | |
| function foo() { | |
| return [1, 2, 3, [4,5,6] ] | |
| } | |
| var a, b, c, d, rest | |
| [ , , , [ c, d] ] = [ a, b, ..rest] = foo() | |
| // a = 1, b = 2, rest = [3, [4, 5, 6]] | |
| // c = 4, d = 5 | |
| // ----------------------------------------------------- | |
| // --------------- OBJECT DESTRUCTERING --------------- | |
| // ----------------------------------------------------- | |
| // First Level Destructering | |
| function foo() { | |
| return { a: 1, b: 2, c: 3, d: 4} | |
| } | |
| var { | |
| a = 10, // default value 10 | |
| b: X = 20, // rename source b to X with default value 10 | |
| c: c, // assign property c to c | |
| d, // shorthand if name stays the same | |
| e // will declare variable e with value undefined | |
| } = foo() || {} | |
| // Nested Destructering | |
| function foo() { | |
| return { | |
| a: 1, | |
| b: 2, | |
| c: 3, | |
| d: { | |
| e: 4 | |
| } | |
| } | |
| } | |
| var { | |
| a, | |
| d: X, | |
| d: { | |
| e | |
| } = {} | |
| } = foo() || {} | |
| console.log(e) | |
| // Nested Destructering on "undefined properties" | |
| // Nested Destructering with nested objects with defaults to prevent | |
| // hard fails. Recommendation from Getify is to always add a default | |
| // when having nested destructering of properties. | |
| function foo() { | |
| return { | |
| a: 1, | |
| b: 2, | |
| c: 3, | |
| d: { | |
| e: 4 | |
| } | |
| } | |
| } | |
| var { | |
| a, | |
| d: X, | |
| d: { | |
| e: { | |
| f: { | |
| g: { | |
| h = 20 | |
| } = {} | |
| } = {} | |
| } | |
| } = {} | |
| } = foo() || {} | |
| console.log(e) // undefined | |
| console.log(f) // undefined | |
| console.log(g) // undefined | |
| console.log(h) // 20 | |
| // Object Destructering when variables are already defined | |
| // is possible but you need to wrap the whole deconstructiong | |
| // into () braces, because {} are not valid syntax to start with | |
| // as the engine believes it is a scope as opposed to the | |
| // deconstruction properties we want. | |
| function foo() { | |
| return { a: 1, b: 2, c: 3} | |
| } | |
| var a, b, c | |
| ({ | |
| a, | |
| b, | |
| c | |
| } = foo() || {}) | |
| // ----------------------------------------------------- | |
| // ------------- PARAMETER DESTRUCTERING ------------- | |
| // ----------------------------------------------------- | |
| function foo( [a,b,c] = []) { | |
| console.log(a, b, c) | |
| } | |
| foo( [1,2,3] ) | |
| // Object Deconstruction allows to mimic named arguments | |
| function foo( {a, b, c}) { | |
| console.log(a, b, c) | |
| } | |
| foo({ | |
| a: 1, | |
| b: 2, | |
| c: 3 | |
| }) | |
| // This allows for easier apis for function with multipe parameter | |
| function foo( {a, b = 20, c} = {}) { | |
| console.log(a, b, c) | |
| } | |
| foo({ | |
| c: 3, | |
| a: 1 | |
| }) | |
| // ----------------------------------------------------- | |
| // -------- USING DESTRUCTERING TO MIX OBJECTS -------- | |
| // ----------------------------------------------------- | |
| // To Mix two objects like defaults and config we needed some utility library | |
| // in the past. Now we can do it with deconstruction | |
| var defaults = { | |
| method: "POST", | |
| callback: function () {}, | |
| headers: { | |
| "content-type": "text/plain" | |
| } | |
| } | |
| var config = { | |
| url: 'http://some.url', | |
| callback: foo, | |
| headers: { | |
| "x-requested-with": "foo" | |
| } | |
| } | |
| // Mix the two objects | |
| { // creating a scope to noe pollute the other space with variables | |
| // deconstructering all the variables we need to create the object | |
| let { | |
| method = defaults.method, | |
| url, | |
| callback = defaults.callback, | |
| headers: { | |
| "content-type": contentType = defaults.headers["content-type"], | |
| "x-requested-with": xRequestedWith | |
| } | |
| } = config | |
| // "reconstructing" the objects with all the extracted variables | |
| config = { | |
| method, | |
| url, | |
| callback, | |
| headers: { | |
| "content-type": contentType, | |
| "x-requested-with": xRequestedWith | |
| } | |
| } | |
| // This has the benefit that we are entirely in controll of how the object get's mixed | |
| // and don't need to rely on some external algorithm. | |
| } | |
| { | |
| // If we would take the above example one step further we would not need a defaults object | |
| // anymore and just add the defaults to the deconstruction: | |
| let { | |
| method = "POST", | |
| url, | |
| callback = function() {}, | |
| headers: { | |
| "content-type": contentType = defaults.headers["content-type"], | |
| "x-requested-with": xRequestedWith | |
| } | |
| } = | |
| config = { | |
| method, | |
| url, | |
| callback, | |
| headers: { | |
| "content-type": contentType, | |
| "x-requested-with": xRequestedWith | |
| } | |
| } | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment