diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..6b2982b
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 JS snippets
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index b912f24..dcd01f3 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,59 @@
# JavaScript-snippets
-
-
-# JSsnippets on Facebook
-
-find us on [Facebook](https://www.facebook.com/snippetsJS)
-
-
-# How to generate a random number in a given range
-
+> Click :star: if you like the project. Pull Request are highly appreciated. Follow us on [Facebook](https://www.facebook.com/snippetsJS)
+
+### Table of Contents
+| No. | Questions |
+|---- | ---------
+|1 | [Generate a random number in a given range](#How-to-generate-a-random-number-in-a-given-range) |
+|2 | [Find the difference between two arrays](#How-to-find-the-difference-between-two-arrays)|
+|3 | [Convert truthy/falsy to boolean(true/false)](#Convert-truthy-falsy-to-boolean)|
+|4 | [Repeat a string](#Repeat-a-string)|
+|5 | [Check how long an operation takes](#Check-how-long-an-operation-takes)|
+|6 | [Two ways to remove an item in a specific in an array](#Two-ways-to-remove-an-item-in-a-specific-in-an-array)|
+|7 | [Did you know you can flat an array?](#Did-you-know-you-can-flat-an-array)|
+|8 | [Get unique values in an array](#Get-unique-values-in-an-array)|
+|9 | [Copy Text to Clipboard](#Copy-Text-to-Clipboard)|
+|10 | [Nested Destructuring](#Nested-Destructuring)|
+|11 | [URLSearchParams](#URLSearchParams)|
+|12 | [Count elements in an array](#Count-elements-in-an-array)|
+|13 | [Aliases with JavaScript Destructuring](#Aliases-with-JavaScript-Destructuring)|
+|14 | [The Object.is() method determines whether two values are the same value](#the-objectis-method-determines-whether-two-values-are-the-same-value)|
+|15 | [Freeze an object](#Freeze-an-object)|
+|16 | [Printing Object keys and values](#Printing-Object-keys-and-values)|
+|17 | [Capture the right click event](#Capture-the-right-click-event)|
+|18 | [In HTML5, you can tell the browser when to run your JavaScript code](#in-html5-you-can-tell-the-browser-when-to-run-your-javascript-code)|
+|19 | [Nullish coalescing operator](#Nullish-coalescing-operator)|
+|20 | [Optional chaining](#Optional-chaining)|
+|21 | [globalThis](#globalThis)|
+|22 | [The second argument of JSON.stringify lets you cherry-pick π keys to serialize.](#the-second-argument-of-jsonstringify-lets-you-cherry-pick--keys-to-serialize)|
+|23 | [Fire an event listener only once.](#Fire-an-event-listener-only-once)|
+|24 | [Vanilla JS toggle](#Vanilla-JS-toggle)|
+|25 | [Check if a string is a valid JSON](#Check-if-a-string-is-a-valid-JSON)|
+|26 | [getBoundingClientRect](#getBoundingClientRect)|
+|27 | [Check if a node is in the viewport](#Check-if-a-node-is-in-the-viewport)|
+|28 | [Notify when element size is changed](#Notify-when-element-size-is-changed)|
+|29 | [Detect if Browser Tab is in the view](#Detect-if-Browser-Tab-is-in-the-view)|
+|30 | [Private class methods and fields](#Private-class-methods-and-fields)|
+|31 | [Preventing paste into an input field](#Preventing-paste-into-an-input-field)|
+|32 | [The void operator](#The-void-operator)|
+|33 | [replaceAll](#replaceAll)|
+|34 | [Required Function Params](#Required-Function-Params)|
+|35 | [Get input value as a number](#Get-input-value-as-a-number)|
+|36 | [reduceRight](#reduceRight)|
+|37 | [Abort Fetch](#Abort-Fetch)|
+|38 | [How to change the value of an object which is inside an array](#How-to-change-the-value-of-an-object-which-is-inside-an-array)|
+|39 | [Numeric separators allow us to improve our code readability](#Numeric-separators-allow-us-to-improve-our-code-readability)|
+|40 | [pay attention when using every](#pay-attention-when-using-every)|
+|41 | [How to convert an array of key-value tuples into an object](#How-to-convert-an-array-of-key-value-tuples-into-an-object)|
+|42 | [Native text to speech JS](#Native-text-to-speech-JS)|
+|43 | [toFixed](#toFixed)|
+|44 | [generate randomUUID](#generate-random-uuid)|
+|45 | [structuredClone](#structuredClone)|
+|46 | [get device orientation](#get-device-orientation)|
+|47 | [CONST vs LET vs VAR](#const-let-var)|
+
+**[β¬ Back to Top](#table-of-contents)**
+### How to generate a random number in a given range
```javascript
// Returns a random number(float) between min (inclusive) and max (exclusive)
@@ -26,8 +72,8 @@ const getRandomNumberInclusive =(min, max)=> {
getRandomNumberInclusive(2, 10);
```
-# How to find the difference between two arrays.
-
+**[β¬ Back to Top](#table-of-contents)**
+### How to find the difference between two arrays
```javascript
const firstArr = [5, 2, 1];
@@ -66,7 +112,9 @@ difference(firstArr, secondArr); //[3,4]
console.log('difference',difference(firstArr, secondArr))
```
-# How to convert truthy/falsy to boolean(true/false)
+**[β¬ Back to Top](#table-of-contents)**
+### Convert truthy falsy to boolean
+
```javascript
const myVar = null;
const mySecondVar = 1;
@@ -78,8 +126,8 @@ console.log( !!myVar ) // false
console.log( Boolean(mySecondVar) ) // true
console.log( !!mySecondVar ) // true
```
-
-# How to repeat a string
+**[β¬ Back to Top](#table-of-contents)**
+### Repeat a string
```javascript
let aliens = '';
@@ -97,7 +145,8 @@ Array(6).join('π½')
//π½π½π½π½π½π½
```
-# Check how long an operation takes
+**[β¬ Back to Top](#table-of-contents)**
+### Check how long an operation takes
```javascript
//The performance.now() method returns a DOMHighResTimeStamp, measured in milliseconds.
//performance.now() is relative to page load and more precise in orders of magnitude.
@@ -110,7 +159,8 @@ const endTime = performance.now();
console.log("this doSomething took " + (endTime - startTime) + " milliseconds.");
```
-# Two ways to remove an item in a specific in an array
+**[β¬ Back to Top](#table-of-contents)**
+### Two ways to remove an item in a specific in an array
```javascript
//Mutating way
@@ -120,11 +170,12 @@ console.log(muatatedArray) //['a','b','d','e']
//Non-mutating way
const nonMuatatedArray = ['a','b','c','d','e'];
-const newArray = nonMuatatedArray.filter((item'index) => !( index === 2 ));
+const newArray = nonMuatatedArray.filter((item, index) => !( index === 2 ));
console.log(newArray) //['a','b','d','e']
```
-# Did you know you can flat an array?
+**[β¬ Back to Top](#table-of-contents)**
+### Did you know you can flat an array
```javascript
const myArray = [2, 3, [4, 5],[7,7, [8, 9, [1, 1]]]];
@@ -140,7 +191,8 @@ myArray.flat(infinity) // [2, 3, 4, 5 ,7,7, 8, 9, 1, 1];
```
-# Get unique values in an array
+**[β¬ Back to Top](#table-of-contents)**
+### Get unique values in an array
```javascript
const numbers = [1,1,3,2,5,3,4,7,7,7,8];
@@ -162,7 +214,9 @@ const unieqNumbers4 = _.uniq(numbers)
console.log(unieqNumbers4) //[1,3,2,5,4,7,8]
```
-# Copy Text to Clipboard
+
+**[β¬ Back to Top](#table-of-contents)**
+### Copy Text to Clipboard
```javascript
@@ -180,7 +234,8 @@ function copyToClipboard(){
```
-# Nested Destructuring
+**[β¬ Back to Top](#table-of-contents)**
+### Nested Destructuring
```javascript
@@ -197,7 +252,8 @@ const { education : { degree } } = user;
console.log(degree) //Masters
```
-# URLSearchParams
+**[β¬ Back to Top](#table-of-contents)**
+### URLSearchParams
```javascript
@@ -212,22 +268,8 @@ console.log(urlParams.toString()); // "?post=1234&action=edit"
console.log(urlParams.append('active', '1')); // "?post=1234&action=edit&active=1"
```
-
-# Shuffle an array
-
-
-```javascript
-const list = [1,2,3,4,5,6,7,8,9];
-const shuffle = list.sort(func);
-
-function func(a,b){
- return 0.5 - Math.random();
-}
-
-console.log(shuffle);
-```
-
-# Count elements in an array
+**[β¬ Back to Top](#table-of-contents)**
+### Count elements in an array
```javascript
@@ -252,8 +294,8 @@ const countMyFruits = myFruits.reduce((countFruits,fruit) => {
// { Apple:3, Banana:1, Mango:2, Orange:1 }
```
-
-# Aliases with JavaScript Destructuring
+**[β¬ Back to Top](#table-of-contents)**
+### Aliases with JavaScript Destructuring
```javascript
@@ -273,8 +315,8 @@ console.log(pageName) // JSsnippets
```
-
-# The Object.is() method determines whether two values are the same value
+**[β¬ Back to Top](#table-of-contents)**
+### The Object.is() method determines whether two values are the same value
```javascript
@@ -292,8 +334,8 @@ Object.is(foo, bar); // false
```
-
-# How can we freeze an object
+**[β¬ Back to Top](#table-of-contents)**
+### Freeze an object
```javascript
@@ -322,8 +364,8 @@ Object.isFrozen(obj) //true
```
-
-# Printing Object keys and values
+**[β¬ Back to Top](#table-of-contents)**
+### Printing Object keys and values
```javascript
@@ -345,7 +387,9 @@ for(let [key,value] of Object.entries(obj)){
// order is not guaranteed
```
-# Capture the right click event
+
+**[β¬ Back to Top](#table-of-contents)**
+### Capture the right click event
```javascript
window.oncontextmenu = () => {
@@ -359,3 +403,605 @@ window.addEventListener('contextmenu', ()=>{
return false // cancel default menu
},false)
```
+
+**[β¬ Back to Top](#table-of-contents)**
+### In HTML5, you can tell the browser when to run your JavaScript code
+```javascript
+
+//Without async or defer, browser will run your script immediately, before rendering the elements that's below your script tag.
+
+
+//With async (asynchronous), browser will continue to load the HTML page and render it while the browser load and execute the script at the same time.
+//Async is more useful when you really don't care when the script loads and nothing else that is user dependent depends upon that script loading.(for scripts likes Google analytics)
+
+
+//With defer, browser will run your script when the page finished parsing. (not necessary finishing downloading all image files.
+
+```
+
+**[β¬ Back to Top](#table-of-contents)**
+### Nullish coalescing operator
+```javascript
+
+// an equality check against nullary values (e.g. null or undefined). Whenever the expression to the left of the ?? operator evaluates to either //undefined or null, the value defined to the right will be returned.
+
+const foo = undefined ?? 'default string';
+console.log(foo);
+// expected output: "default string"
+
+
+const age = 0 ?? 30;
+console.log(age);
+// expected output: "0"
+```
+
+**[β¬ Back to Top](#table-of-contents)**
+### Optional chaining
+```javascript
+
+const car = {}
+const carColor = car.name.color
+console.log(carColor);
+// error- "Uncaught TypeError: Cannot read property 'carColor' of undefined
+
+//In JavaScript, you can first check if an object exists, and then try to get one of its properties, like this:
+const carColor = car && car.name && car.name.color;
+console.log(carColor);
+//undefined- no error
+
+
+//Now this new optional chaining operator will let us be even more fancy:
+
+const newCarColor = car?.name?.color;
+console.log(newCarColor)
+//undefined- no error
+
+//You can use this syntax today using @babel/plugin-proposal-optional-chaining
+```
+
+**[β¬ Back to Top](#table-of-contents)**
+### globalThis
+```javascript
+Accessing the global property in JavaScript has always posed some difficulty. This is because
+different platforms have different ways to access it.
+
+Client-side JavaScript uses window or self
+
+Node.js uses global
+
+Web workers use self
+
+The globalThis property provides a standard way of accessing the global 'this' value across environments. you can access the global object in a consistent manner without having to know which environment the code is being run in.
+
+console.log(globalThis) //get the global this depends on your environment
+
+```
+
+
+**[β¬ Back to Top](#table-of-contents)**
+# The second argument of JSON.stringify lets you cherry-pick π keys to serialize.
+```javascript
+const user = {
+ id: 459,
+ name: 'JS snippets',
+ age:29,
+ education:{
+ degree: 'Masters'
+ }
+}
+
+JSON.stringify(user,[name,age], 2)
+
+/*
+returns
+
+{
+ "name": "JS snippets",
+ "age": 29
+}
+
+
+*/
+
+```
+
+**[β¬ Back to Top](#table-of-contents)**
+### Fire an event listener only once
+```javascript
+const el = document.getElementById("btn");
+
+function myClickHandler(){
+ console.log('this click will only fire once')
+}
+
+
+el.addEventListener('click', myClickHandler, {
+ once: true,
+});
+
+```
+**[β¬ Back to Top](#table-of-contents)**
+### Vanilla JS toggle
+```javascript
+const span = document.querySelector("span");
+let classes = span.classList;
+
+span.addEventListener("click", function() {
+ let result = classes.toggle("active");
+
+ if (result) {
+ console.log("active class was added");
+ } else {
+ console.log("active class was removed");
+ }
+});
+
+```
+
+**[β¬ Back to Top](#table-of-contents)**
+### Check if a string is a valid JSON
+
+```javascript
+function isJson(str) {
+ try {
+ JSON.parse(str);
+ } catch (e) {
+ //the json is not ok
+ return false;
+ }
+ //the json is ok
+ return true;
+}
+```
+**[β¬ Back to Top](#table-of-contents)**
+### getBoundingClientRect
+
+```javascript
+//getBoundingClientRect provides you with important pieces of data about an
+//HTML elementβs size and positioning.
+
+const bodyBounderies = document.body.getBoundingClientRect();
+// => {
+// top: Number,
+// left: Number,
+// right: Number,
+// bottom: Number,
+// x: Number,
+// y: Number,
+// width: Number,
+// height: Number,
+// }
+```
+
+**[β¬ Back to Top](#table-of-contents)**
+### Check if a node is in the viewport
+bonus: add/remove animation depending if an image is in the viewport
+https://codepen.io/JSsnippets/pen/PoqrjEY
+```javascript
+const image = document.querySelector('.animate-me');
+
+observer = new IntersectionObserver((entries) => {
+ const [ myImg ] = entries;
+ if (myImg.intersectionRatio > 0) {
+ myImg.target.classList.add('fancy');
+ } else {
+ myImg.target.classList.remove('fancy');
+ }
+});
+
+
+observer.observe(image);
+
+```
+
+**[β¬ Back to Top](#table-of-contents)**
+### Notify when element size is changed
+see our codepen: https://codepen.io/JSsnippets/pen/dyYoYVX
+```javascript
+const foo = document.getElementById("foo");
+
+const observer = new ResizeObserver((entries) => {
+ for (let entry of entries) {
+ const cr = entry.contentRect;
+ console.log = `Size: ${cr.width}px X ${cr.height}px`;
+ }
+});
+observer.observe(foo);
+
+```
+**[β¬ Back to Top](#table-of-contents)**
+### Detect if Browser Tab is in the view
+play/pause video accordingly
+see our codepen: https://codepen.io/JSsnippets/pen/gOapPzq
+```javascript
+
+
+const video = document.getElementById("my-video");
+
+const onVisibilitychange =()=>{
+ return document.hidden
+ ? video.pause()
+ : video.play();
+}
+
+document.addEventListener("visibilitychange", onVisibilitychange)
+
+```
+
+
+**[β¬ Back to Top](#table-of-contents)**
+### Private class methods and fields
+```javascript
+
+class Students {
+ #name;
+
+ constructor(){
+ this.#name = "JS snippets";
+ }
+
+ #privateMethod() {
+ return 'Come and learn Js with us';
+ }
+
+ getPrivateMessage() {
+ return this.#privateMethod();
+ }
+}
+
+const instance = new Something();
+console.log(instance.name); //=> undefined
+console.log(instance.privateMethod); //=> undefined
+console.log(instance.getPrivateMessage()); //=> Come and learn Js with us
+
+```
+
+
+**[β¬ Back to Top](#table-of-contents)**
+### Preventing paste into an input field
+see our codepen: https://codepen.io/JSsnippets/pen/qBbyMoJ
+
+```javascript
+
+const pasteBox = document.getElementById("paste-no-event");
+pasteBox.onpaste = (e) => {
+ e.preventDefault();
+ return false;
+};
+
+```
+
+
+**[β¬ Back to Top](#table-of-contents)**
+### The void operator
+The void operator evaluates the given expression and then returns undefined.
+```javascript
+
+
+void 0; //returns undefined
+void (0); //returns undefined
+void {}; //returns undefined
+void "JSsnippets; //returns undefined
+void (0); //returns undefined
+void (2 == '2'); //returns undefined
+void anyfunction(); //returns undefined
+
+```
+
+
+**[β¬ Back to Top](#table-of-contents)**
+### replaceAll
+the method string.replaceAll(search, replaceWith) replaces all appearances of search string with replaceWith.
+```javascript
+
+
+const str = 'this is a JSsnippets example';
+
+const updatedStr = str.replace('example', 'snippet'); // 'this is a JSsnippets snippet'
+
+
+The tricky part is that replace method replaces only the very first match of the substring we have passed:
+
+
+const str = 'this is a JSsnippets example and examples are great';
+
+const updatedStr = str.replace('example', 'snippet'); //'this is a JSsnippets snippet and examples are great'
+
+In order to go through this, we need to use a global regexp instead:
+
+
+const str = 'this is a JSsnippets example and examples are great';
+
+const updatedStr = str.replace(/example/g, 'snippet'); //'this is a JSsnippets snippet and snippets are greatr'
+
+but now we have new friend in town, replaceAll
+
+const str = 'this is a JSsnippets example and examples are great';
+
+const updatedStr = str.replaceAll('example', 'snippet'); //'this is a JSsnippets snippet and snippets are greatr'
+
+```
+
+
+**[β¬ Back to Top](#table-of-contents)**
+### Required Function Params
+Expanding on the default parameter technique, we can mark a parameter as mandatory
+
+```javascript
+const isRequired = () => {
+ throw new Error( 'This is a mandatory parameter.' );
+}
+
+
+const getPage = ( pageName = 'Jssnippets', url = isRequired() ) => {
+ return `${pageName} ${url}`;
+}
+
+console.log(getPage());
+
+//In the above code, url will be undefined and that will try to set the default value for it which is the isRequired() function. It will throw an error as,
+
+//Uncaught error: This is a mandatory parameter.
+//at isRequired
+
+```
+
+
+
+
+**[β¬ Back to Top](#table-of-contents)**
+### Get input value as a number
+
+```javascript
+
+
+
+function checkMyType(event){
+
+ console.log(typeof event.target.value) // string
+ console.log(typeof event.target.valueAsNumber ) // number
+
+}
+
+
+```
+**[β¬ Back to Top](#table-of-contents)**
+### reduceRight
+
+```javascript
+
+const arr = ["a", "b", "c", "d", "e"]
+
+const reduceArray = arr.reduce((acc, current) => {
+ return acc + current
+}, "")
+//return abcde
+
+const reduceRightArray = arr.reduceRight((acc, current) => {
+ return acc + current
+}, "")
+//return edcba
+
+```
+
+
+**[β¬ Back to Top](#table-of-contents)**
+### Abort Fetch
+
+```javascript
+
+
+//HTML
+
+
+
+//JS
+let controller;
+
+document.querySelector('#download').addEventListener('click', () => {
+ controller = new AbortController();
+ const signal = controller.signal;
+ fetch('https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-576p.mp4', {signal})
+ .then(() => console.log('done'));
+});
+
+document.querySelector('#abort').addEventListener('click', function() {
+ controller.abort();
+});
+
+```
+
+
+**[β¬ Back to Top](#table-of-contents)**
+### How to change the value of an object which is inside an array
+
+```javascript
+
+const state = [
+ {
+ userId: 1,
+ name: "JSSnippets",
+ isOwner: false,
+ },
+ {
+ userId: 2,
+ name: "React",
+ isOwner: false,
+ },
+ {
+ userId: 3,
+ name: "Vue",
+ isOwner: false,
+ },
+ {
+ userId: 4,
+ name: "Angular",
+ isOwner: false,
+ },
+];
+
+const newState = state.map((obj) =>
+ obj.name === "JSSnippets" ? { ...obj, isOwner: true } : obj
+);
+
+```
+
+**[β¬ Back to Top](#table-of-contents)**
+### Numeric separators allow us to improve our code readability
+
+```javascript
+
+100_000_000 === 100000000 // true
+
+300_000 === 300000 //true
+
+```
+
+
+
+
+
+**[β¬ Back to Top](#table-of-contents)**
+### pay attention when using every
+
+Calling this method on an empty array will return true for any condition!
+
+
+```javascript
+
+const arr = []
+const result = arr.every(x=> x==5)
+console.log(result) //true
+
+```
+
+
+
+
+
+**[β¬ Back to Top](#table-of-contents)**
+### How to convert an array of key-value tuples into an object
+
+
+```javascript
+
+const JSarr = [
+ ['name', 'JSsnippets'],
+ ['address', 'worldwide'],
+ ['year', '2018'],
+ ['followers', '15000']
+
+];
+
+const obj = Object.fromEntries(JSarr);
+//{
+// "name": "JSsnippets",
+// "address": "worldwide",
+// "year": "2018",
+// "followers": "15000"
+//}
+```
+
+**[β¬ Back to Top](#table-of-contents)**
+### Native text to speech JS
+
+
+```javascript
+
+const startSpeaking=()=>{
+
+ let msg = document.getElementById("text-to-speech").value;
+ let speech = new SpeechSynthesisUtterance();
+
+ speech.lang = "en-US";
+ speech.text = msg;
+ speech.volume = 1;
+ speech.rate = 1;
+ speech.pitch = 1;
+
+ window.speechSynthesis.speak(speech);
+}
+
+
+```
+
+**[β¬ Back to Top](#table-of-contents)**
+### toFixed
+
+Warning: Floating point numbers cannot represent all decimals precisely in binary. This can lead to unexpected results, such as 0.1 + 0.2 === 0.3 returning false .
+
+```javascript
+
+123.678.toFixed() // Returns '124'
+123.678.toFixed(1) // Returns '123.7': Note rounding
+
+2.35.toFixed(1) // Returns '2.4'. Note it rounds up
+2.65.toFixed(1) // Returns '2.6'. Note it rounds down -why??? see the warning above
+
+```
+
+
+**[β¬ Back to Top](#table-of-contents)**
+### generate random uuid
+
+The randomUUID() method of the Crypto interface is used to generate a v4 UUID using a cryptographically secure random number generator.
+
+```javascript
+
+crypto.randomUUID() // print in console '460ff1e6-2106-4848-833d-5c5b3bfdc943'
+
+crypto.randomUUID() // print in console '9a91c014-d1b1-453a-8091-ef8b9b48b14a'
+
+
+```
+
+
+**[β¬ Back to Top](#table-of-contents)**
+### structuredClone
+
+If you want to deep clone a value in Node.js, you no longer need to use a library or the JSON.parse(JSON.stringify(value)) hack. You can use the new global function structuredClone()
+
+```javascript
+
+const user = {
+ name: "JS Snippets",
+ address: { street: "Original Road", city: "Placeshire" },
+};
+
+const clonedUser = structuredClone(user);
+
+clonedUser.address.street = "New Road";
+
+console.log("user.address.street:", user.address.street);
+// > Original Road
+
+console.log("clonedUser.address.street:", clonedUser.address.street);
+// > New Road
+
+
+```
+
+**[β¬ Back to Top](#table-of-contents)**
+### get device orientation
+
+Browsers expose a global variable named screen, which weβll use to access the information we need.
+
+```javascript
+
+function getOrientation() {
+ const isPortrait = screen.orientation.type.startswith('portrait')
+ return isPortrait ? 'portrait' : 'landscape'
+}
+
+```
+
+**[β¬ Back to Top](#table-of-contents)**
+### CONST vs LET vs VAR
+
+| | const | Let | Var |
+|------------------------|-------|-----|-----|
+| Can be Reaasigned? | :x: | :white_check_mark: |:white_check_mark: |
+| Cab be Redeclared? | :x: | :x: | :white_check_mark: |
+| Block Scope | :white_check_mark: |:white_check_mark: | :x: |
+| Function Scope | :white_check_mark: | :white_check_mark: | :white_check_mark: |
+| Stored in Global Scope | :x: | :x: | :white_check_mark: |
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: