JavaScript is a language that offers many different styles of writing code. There will always be more than one way to solve a problem. We will discuss some clever ways to solve some problems. And also give you some JavaScript tips and tricks and explanations along the way.
ES6 Basics
ECMA Script 2015 or ES6 refers to the new version of JavaScript. It has brought many new major updates. ES6 is what modern JavaScript is all about. We have explained some of the ES6 features below that you should know before learning some javascript tips tricks.
1. let and const
Instead of using var, it is recommended to use let to get the benefits of lexical scoping.
let outerLet = 'outer-let' var outerVar = 'outer-var' { // code block inside braces let innerLet = 'inner-let' var innerVar = 'inner-var' } console.log(outerLet) // outer-let console.log(outerVar) // outer-var console.log(innerVar) // inner-var console.log(innerLet) // ReferenceError: innerLet is not defined
Variables defined inside ‘if’ statements and ‘loops’ with ‘let’ are not accessible outside. While variables defined with ‘var’ are accessible throughout the same function. ‘const’ is the same as let except you cannot change the value later once assigned.
2. Spread Operator (…)
You can use the three dots (…) to pull out the values of an array or object. This can be used to clone arrays, objects, and add new values and properties.
const array = [1, 2, 3] // ...array will pull out the values const newArray = [...array, 4] console.log(newArray) // [1, 2, 3, 4] const object = { name: 'Shanon' } // ...object will pull out all the properties const newObject = { ...object, age: 39 } console.log(newObject) // { name: 'Shanon', age: 39 }
3. Arrow Functions
These are just condensed ways of writing functions in JavaScript. Here, you use an arrow (=>) without the function keyword. Parameters are written inside the parenthesis before the arrow. The statement after the arrow is the return value.
const logHello = () => { console.log('hello world') } const double = num => num * 2 const multiply = (a, b) => { const result = a * b return result } const doubled = double(2) const multiplied = multiply(5, 3) logHello() // hello world console.log(doubled) // 4 console.log(multiplied) // 15
When the function parameter is only one, then using parenthesis is optional. If more statements are required in the function body, then braces are required as shown in the multiply function above.
With this knowledge, let us dive into the tricks and tips to solve the common problems in JavaScript.
JavaScript Tips and Tricks
We have picked the top ones and explained them. You will get to learn a lot from these 10 javascript tricks.
1. Removing Duplicate elements from an array
Array elements can contain duplicate elements. Removing them using a custom logic inside a loop is not necessary. You can use ES6 to remove them using the new Set() constructor.
const duplicateNumbers = [1, 3, 3, 4, 2, 1] const set = new Set(duplicateNumbers) // spread the set to an array const uniqueNumbers = [...set] console.log(duplicateNumbers) // [ 1, 3, 3, 4, 2, 1 ] console.log(set) // Set { 1, 3, 4, 2 } console.log(uniqueNumbers) // [ 1, 3, 4, 2 ]
On creating a ‘set’ data structure, using the ‘new Set()’ constructor, the duplicate elements are automatically removed. Spreading this ‘set’ inside [] gives us an array without duplicates.
2. ‘prop’ in ‘obj’
If you want to check if an object has an accessible property before using it, then you should use the (‘prop’ in ‘obj’) syntax.
const user = { name: 'Robin', email: 'robin@test.com', } // won't run if ('age' in user) console.log(user.age) // it is true if ('name' in user) console.log(user.name) // Robin
You can loop through an object using a ‘for in’ loop.
const user = { name: 'Robin', email: 'robin@test.com', } for (userDetail in user) { console.log(userDetail, user[userDetail]) } // name Robin // email robin@test.com
3. Understanding Primitive and Reference Types
JavaScript types can be divided into two categories: Primitive and Reference. A primitive value is a simple literal value like 5, ‘me’, true, ‘hello world’, 55. So, strings, numbers, and Boolean values are primitive.
Their values are exactly stored the same in the variables. This is not the case with more complex types like arrays and objects. They are a combination of Primitive and reference values. So an array can have a collection of strings, numbers, Booleans, and even other arrays and objects.
They can have large values of nested data or a row of many values. Thus, storing the values of arrays or objects inside a variable is not practical as it can be large. So, the address of those arrays/objects are stored in the variables. This address is also called the reference.
So, when a variable containing the reference to an array is copied, then the reference is copied and not the value. This is the same for objects and this is the reason, arrays and objects are also called reference types. This is an important javascript tip to remember.
const arr1 = [1, 2, 3, 4, 5] const arr2 = arr1 // create actual copy (clone) const arr3 = [...arr1] // mutate change arr2 arr2.pop() console.log(arr2) // [ 1, 2, 3, 4 ] // arr1 also changes // as arr2 and arr1 references the same array in memory console.log(arr1) // [ 1, 2, 3, 4 ] // array 3 is a totally different array with a different reference. console.log(arr3) // [ 1, 2, 3, 4, 5 ]
4. Mutating and Non-muting methods
A mutating method changes and updates the original object or array. On the other hand, non-mutating methods do not change or alter the original array.
Not being aware of the method, whether it is mutating or not, can cause confusion and bugs. In the example below, slice() is a non-mutating method, but ‘reverse()’ is a mutating method.
Trick: You can stop modifying the original array and still use a mutating method. For that, you need to clone the array to a new variable. Then you can perform the mutating operations on the cloned variable. This will preserve the original array.
const arr = [1, 2, 3, 4, 5] // NON MUTATING - Does not change the original array. console.log(arr.slice(1, 4)) // [2, 3, 4] // array was not modified console.log(arr) // [1, 2, 3, 4, 5] // MUTATING - Changes the original array. console.log(arr.reverse()) // [5, 4, 3, 2, 1] // array was modified by the method console.log(arr) // [5, 4, 3, 2, 1]
5. Finding an element of an array.
To find an array element, you can use the .find() higher-order function. You can access the index of the element using .findIndex(). There is a difference between indexOf() and findIndex(). ‘findIndex()’ allows complex comparisons that can consist of comparing object values.
const books = [ { name: "Alice's Adventures in Wonderland", year: 1865 }, { name: 'Da Vinci Code', year: 2003 }, ] const bookFrom2003 = books.find(book => book.year === 2003) const bookIndex = books.findIndex(book => book.year === 2003) console.log(bookFrom2003) // { name: 'Da Vinci Code', year: 2003 }
6. Deleting an array element
Use splice() to delete an array element if you know its index.
array.splice(indexToDelete, 1)
If you need to delete an element based on some condition then you should use the filter() method instead.
const items = [ { name: 'cat', type: 'animal' }, { name: 'dog', type: 'animal' }, { name: 'carrot', type: 'vegetable' }, { name: 'apple', type: 'fruit' }, ] // filter does not mutate the array const filteredItems = items.filter(item => item.type !== 'animal') console.log(filteredItems) /* [ { name: 'carrot', type: 'vegetable' }, { name: 'apple', type: 'fruit' } ] */
The filter() method takes a callback function that receives a parameter. It is called for every element of the array. If the callback returns true, then the array element is included in the new array.
Bonus Trick: You can use this quick trick to filter out all the elements that are false.
const values = [0, 2, 5, '', 'test', false] const truthyValues = values.filter(Boolean) console.log(truthyValues) // [ 2, 5, 'test' ]
7. Short-Circuiting of values in JavaScript
A truth value is something that evaluates to true, and a falsy value is something that evaluates to false. Values like 0, ‘’, false, undefined, null are falsy. The rest are truthy. This is an important technique to know if you want to write more flexible code in JavaScript.
- Short circuit in OR operation makes sure that if any value is found true in the chain of OR conditions (val1 || val2 || val3 || …), then the next values are not evaluated and simply that value is returned which was evaluated to true.
- The short circuit in AND is similar. In the chain of AND conditions, if any value is found false then the next conditions are not necessary to be checked. And also, JavaScript returns that value which is evaluated to false in AND operation.
In a nutshell, The OR operation returns the value whichever evaluates to true first. But the AND operator returns the value where the condition failed. This example below should clarify the concept.
const val1 = false const val2 = 'hello' const val3 = 0 const val4 = 25 // val2 is found to be true so it stops checking and returns // the value const orValue = val1 || val2 || val3 || val4 // 0 (val3) is a falsy value so it stops evaluating val4 and // returns val3 const andValue = val2 && val3 && val4 console.log(orValue, andValue) // hello 0
8. Deep Cloning an array or object
You can only shallow clone(copy) a normal array or object. The deep clone method copies even the nested arrays and objects. However, “JSON.parse()” and “JSON.stringify()” do not copy the properties of the prototype objects.
const users = [ { name: 'Robin', links: ['linkedin', 'facebook'] }, { name: 'Susie', meta: { comments: 2, likes: 3 } }, ] // create a deep clone of the users array const clonedUser = JSON.parse(JSON.stringify(users)) // udpate the clonedArray clonedUser[0].links.push('youtube') // clonedUser was modified and this did not change users array. // this worked as expected. console.log(users) /* [ { name: 'Robin', links: [ 'linkedin', 'facebook' ] }, { name: 'Susie', meta: { comments: 2, likes: 3 } } ] */
9. Shuffle an array in one line of code
The sort method takes a callback function as an argument. “Math.random()” returns values between 0 to less than 1. Subtracting by half gives a 50% chance of –ve or +ve value.
const array = [1, 2, 3, 4, 5] array.sort(() => Math.random() - 0.5) console.log(array) // [ 1, 5, 2, 4, 3 ]
10. Dynamic property names
Objects can access properties dynamically using the square bracket notation. This is very useful in loops and functions that repeatedly run the same code to return different values.
const object = { name: 'dan', age: 30, } const prop = 'name' console.log(object[prop]) // dan
There are many more tricks that you will discover in your journey of coding with JavaScript. You will also find your intuitive ways of solving it by yourself as you code.