The purpose of this article is to help you more skilled use of JavaScript language to develop work.

An if statement with multiple conditions

Place multiple values in an array and call the includes method of the array.

/ / bad 👴
if (x === "abc" || x === "def" || x === "ghi" || x === "jkl") {
  //logic
}

/ / better 👶
if (["abc"."def"."ghi"."jkl"].includes(x)) {
  //logic
}
Copy the code

Use conditional expressions to simplifyif true... else

/ / bad 👴
let test: boolean;
if (x > 100) {
  test = true;
} else {
  test = false;
}

/ / better 👶
let test = x > 10 ? true : false;
// Or so
let test = x > 10;

console.log(test);
Copy the code

Check for false values (undefined, null, 0, false, NaN, empty string)

When we create a new variable, we sometimes want to check that the referenced variable is not null or undefined or an empty string. JavaScript does have a very good and quick way to implement this inspection – the logical or operator (| |)

| | will be on the left operand is false value returns the right operand

Only if the left side is:

  • Empty string:' 'or` `
  • NaN
  • 0
  • null
  • undefined
  • false

The Boolean or operator (| |) will return to the right of the value

/ / bad 👴
if(test1 ! = =null|| test1 ! = =undefined|| test1 ! = ="") {
  let test2 = test1;
}

/ / better 👶
let test2 = test1 || "";
Copy the code
/ / bad 👴
if (test1 === true) or if(test1 ! = ="") or if(test1 ! = =null)

/ / better 👶
if (test1){
  // do some
}else{
  // do other
}
Copy the code

Note: If test1 has a value, the logic after if is performed. This operator is mainly used for null,undefinded, and empty string checking.

Use the null value merge operator –??

Only if the left-hand side is

  • null
  • undefined

Null-value merge operator (??) Returns the value on the right

const baz = 0 ?? 42;
console.log(baz);
// expected output: 0
Copy the code

Note: with the logical or operator (| |), | | will be on the left operand is false value returns the right operand

Only if the left side is:

  • Empty string:' 'or` `
  • NaN
  • 0
  • null
  • undefined

The Boolean or operator (| |) will return to the right of the value

var a = "" || 1;
/ / output 1
console.log(a);
Copy the code

nullCheck and default assignments

let test1 = null;
let test2 = test1 ?? "";

console.log("null check", test2); // Outputs an empty string ""
Copy the code

undefinedCheck and default assignments

const test = undefined ?? "default";

console.log(test);
// expected output: "default"
Copy the code

Return after comparison

/ / bad 👴
let test;
function checkReturn() {
  if(! (test ===undefined)) {
    return test;
  } else {
    return callMe("test"); }}/ / better 👶
function checkReturn() {
  return test ?? callMe("test");
}
Copy the code

Use the optional chain operator –? .

? . Also called chain judgment operator. It allows developers to read property values that are deeply nested in the object chain without validating every reference. When the reference is empty, the expression stops evaluating and returns undefined

const travelPlans = {
  destination: "DC".monday: {
    location: "National Mall".budget: 200,}};/ / bad 👴
const res =
  travelPlans &&
  travelPlans.tuesday &&
  travelPlans.tuesday.location &&
  travelPlans.tuesday.location.href;

/ / better 👶
/ / output is undefined
constres1 = travelPlans? .tuesday? .location? .href;Copy the code

The && operator for multiple criteria

If the function is called only when the variable is true, use the && operator.

/ / bad 👴
if (test1) {
  callMethod();
}

/ / better 👶
test1 && callMethod();
Copy the code

This is useful when you want to conditionally render a component in React, as opposed to the (&&) short circuit. Such as:

<div> {this.state.isLoading && <Loading />} </div>
Copy the code

The switch to simplify

We can store conditions in key-value objects and invoke them based on conditions.

/ / bad 👴
switch (data) {
  case 1:
    test1();
    break;
  case 2:
    test2();
    break;
  case 3:
    test();
    break;
  // And so on...
}

/ / better 👶
var data = {
  1: test1,
  2: test2,
  3: test,
};

// If type exists in data, the corresponding function is executed
data[type] && data[type] ();Copy the code

Default Parameter Value

/ / bad 👴
function add(test1, test2) {
  if (test1 === undefined) test1 = 1;
  if (test2 === undefined) test2 = 2;
  return test1 + test2;
}

/ / better 👶
add = (test1 = 1, test2 = 2) = > test1 + test2;
add(); //output: 3
Copy the code

Conditional lookup simplification

If we want to call different methods based on different types, we can use multiple else if statements or switches, but is there a better simplification technique? In fact, the previous switch is simplified in the same way!

/ / bad 👴
if (type= = ="test1") {
  test1();
} else if (type= = ="test2") {
  test2();
} else if (type= = ="test3") {
  test3();
} else if (type= = ="test4") {
  test4();
} else {
  throw new Error("Invalid value " + type);
}

/ / better 👶
var types = {
  test1,
  test2,
  test3,
  test4,
};
types[type] && types[type] ();Copy the code

Object property assignment

let test1 = "a";
let test2 = "b";

/ / bad 👴
let obj = { test1: test1, test2: test2 };

/ / better 👶
let obj = { test1, test2 };
Copy the code

Deconstruction assignment

/ / bad 👴
const test1 = this.data.test1;
const test2 = this.data.test2;
const test2 = this.data.test3;

/ / better 👶
const { test1, test2, test3 } = this.data;
Copy the code

Template string

If you’re tired of using + to concatenate multiple variables into a single string, this simplification trick will be a headache free.

/ / bad 👴
const welcome = "Hi " + test1 + "" + test2 + ".";
/ / better 👶
const welcome = `Hi ${test1} ${test2}`;
Copy the code

Interline string

/ / bad 👴
const data =
  "abc abc abc abc abc abc\n\t" + "test test,test test test test\n\t";
/ / better 👶
const data = `abc abc abc abc abc abc test test,test test test test`;
Copy the code

Bitwise manipulation of indexOf is simplified

When looking for a value in an array, we can use the indexOf() method. But there’s a better way. Let’s look at this example.

/ / bad 👴
if (arr.indexOf(item) > -1) {
  // item found
}
if (arr.indexOf(item) === -1) {
  // item not found
}
/ / better 👶
if (~arr.indexOf(item)) {
  // item found
}
if(! ~arr.indexOf(item)) {// item not found
}
Copy the code

The bitwise (~) operator returns true (except -1), and the reverse operation only requires! ~. Alternatively, you can use the includes() function.

if (arr.includes(item)) {
  // true if the item found
}
Copy the code

A string is converted to a number

There are built-in methods, such as parseInt and parseFloat, that can be used to convert strings to numbers. We can also do this by simply providing a unary operator (+) in front of the string.

/ / bad 👴
let total = parseInt("453");
let average = parseFloat("42.6");

/ / better 👶
let total = +"453";
let average = +"42.6";
Copy the code

Execute promises sequentially

What if you have a bunch of asynchronous or normal functions that all return promises and require you to execute them one by one?

async function getData() {
  const promises = [fetch("url1"), fetch("url2"), fetch("url3"), fetch("url4")];
  for (const item of promises) {
    // Print promise
    console.log(item);
  }

  / / better 👶
  for await (const item of promises) {
    // Prints out the result of the request
    console.log(item); }}Copy the code

Wait for all promises to complete

The promise.allSettled () method takes a set of Promise instances as parameters and wraps them into a new Promise instance. The wrapper instance will not complete until all of these parameter instances return the result, whether this is fulfilled or Rejected

Sometimes we don’t care about the result of an asynchronous request, just whether all the requests end. In this case, the promise.allSettled () method is useful

const promises = [fetch("index.html"), fetch("https://does-not-exist/")];

const results = await Promise.allSettled(promises);

// Filter out successful requests
const successfulPromises = results.filter((p) = > p.status === "fulfilled");

// Filter out failed requests and print the reason
const errors = results
  .filter((p) = > p.status === "rejected")
  .map((p) = > p.reason);
Copy the code

Swap the positions of array elements

/ / bad 👴
const swapWay = (arr, i, j) = > {
  const newArr = [...arr];

  let temp = newArr[i];

  newArr[i] = list[j];
  newArr[j] = temp;

  return newArr;
};
Copy the code

Starting with ES6, swapping values from different locations in the array is much easier

/ / better 👶
const swapWay = (arr, i, j) = > {
  const newArr = [...arr];

 const [newArr[j],newArr[i]] = [newArr[i],newArr[j]];

  return newArr;
};
Copy the code

Use variables as object keys

You can use it when you have a string variable and want to use it as a key in an object to set a value

let property = "a";

const obj = {
  b: "b"}; property ="name";

obj[property] = "This is A";

// {b: "b", name: "A"}
console.log(obj);
Copy the code

Random number generator with range

Sometimes you need to generate random numbers, but you want them to be within a certain range, so you can use this tool.

function randomNumber(max = 1, min = 0) {
  if (min >= max) {
    return max;
  }

  return Math.floor(Math.random() * (max - min) + min);
}
Copy the code

Generate random colors

function getRandomColor() {
  const colorAngle = Math.floor(Math.random() * 360);
  return `hsla(${colorAngle}`, 100%, 50%, 1);
}
Copy the code

Gets the last item in the list

In other languages this function is made into a method or function that can be called on an array, but in JavaScript, you have to do your own work.

let array = [0.1.2.3.4.5.6.7];
console.log(array.slice(-1)) > > > [7];

console.log(array.slice(-2)) > > > [6.7];

console.log(array.slice(-3)) > > > [5.6.7];
Copy the code
function lastItem(list) {
  if (Array.isArray(list)) {
    return list.slice(-1) [0];
  }

  if (list instanceof Set) {
    return Array.from(list).slice(-1) [0];
  }

  if (list instanceof Map) {
    return Array.from(list.values()).slice(-1) [0]; }}Copy the code

Lazy loading of images

In a lazy loading implementation, there are two key values: the height of the current visible region and the height of the element from the top of the visible region.

The height of the current viewable area can be obtained using the window.innerHeight property in modern browsers and those up to IE9. In low version of IE standard mode, you can use the document. The documentElement. ClientHeight, here we are compatible with two kind of situations:

const viewHeight = window.innerHeight || document.documentElement.clientHeight;
Copy the code

For the height of the element from the top of the viewport, we use the getBoundingClientRect() method to get the size of the returned element and its position relative to the viewport. MDN gives a very clear explanation for this:

The return value of this method is a DOMRect object, which is the collection of rectangles returned by the element’s getClientRects() method, that is, the collection of CSS borders associated with the element.

The DOMRect object contains a set of read-only attributes — left, top, Right, and bottom — that describe the border, in pixels. All attributes except width and height are relative to the top-left position of the viewport.

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Lazy-Load</title>
    <style>
      .img {
        width: 200px;
        height: 200px;
        background-color: gray;
      }
      .pic{// NecessaryimgStyle}</style>
  </head>
  <body>
    <div class="container">
      <div class="img">// Note that we didn't introduce a real SRC for it<img class="pic" alt="Loading" data-src="./images/1.png" />
      </div>
      <div class="img">
        <img class="pic" alt="Loading" data-src="./images/2.png" />
      </div>
      <div class="img">
        <img class="pic" alt="Loading" data-src="./images/3.png" />
      </div>
      <div class="img">
        <img class="pic" alt="Loading" data-src="./images/4.png" />
      </div>
      <div class="img">
        <img class="pic" alt="Loading" data-src="./images/5.png" />
      </div>
      <div class="img">
        <img class="pic" alt="Loading" data-src="./images/6.png" />
      </div>
      <div class="img">
        <img class="pic" alt="Loading" data-src="./images/7.png" />
      </div>
      <div class="img">
        <img class="pic" alt="Loading" data-src="./images/8.png" />
      </div>
      <div class="img">
        <img class="pic" alt="Loading" data-src="./images/9.png" />
      </div>
      <div class="img">
        <img class="pic" alt="Loading" data-src="./images/10.png" />
      </div>
    </div>
  </body>
</html>
Copy the code
<script>
    // Get all image labels
    const imgs = document.getElementsByTagName('img')
    // Get the height of the viewable area
    const viewHeight = window.innerHeight || document.documentElement.clientHeight
    // num is used to count which image is currently displayed, so as not to check the first image every time
    let num = 0
    function lazyload(){
        for(let i=num; i<imgs.length; i++) {
            // Subtract the height from the top of the element to the top of the viewable area
            let distance = viewHeight - imgs[i].getBoundingClientRect().top
            If the height of the viewable area is greater than or equal to the height from the top of the element to the top of the viewable area, the element is exposed
            if(distance >= 0) {// Write real SRC to the element to show the image
                imgs[i].src = imgs[i].getAttribute('data-src')
                // The first I image has been loaded, next time from the first I +1 check whether it is exposed
                num = i + 1}}}// Listen for Scroll events
    window.addEventListener('scroll', lazyload, false);
</script>

Copy the code

Image preloading

class PreLoadImage {
  constructor(imgNode) {
    // Get the real DOM node
    this.imgNode = imgNode;
  }

  // Manipulate the SRC attribute of the img node
  setSrc(imgUrl) {
    this.imgNode.src = imgUrl; }}class ProxyImage {
  // Placeholder map URL
  static LOADING_URL = "xxxxxx";

  constructor(targetImage) {
    // Target Image, i.e. PreLoadImage instance
    this.targetImage = targetImage;
  }

  // This method mainly operates the virtual Image to complete the loading
  setSrc(targetUrl) {
    // The actual IMG node is initialized to display a placeholder map
    this.targetImage.setSrc(ProxyImage.LOADING_URL);
    // Create a virtual Image instance to help us load the Image
    const virtualImage = new Image();
    // When the target image is loaded, set the SRC property of the real IMG node in the DOM to the URL of the target image
    virtualImage.onload = () = > {
      this.targetImage.setSrc(targetUrl);
    };
    // Set the SRC attribute, and the virtual Image instance starts loading imagesvirtualImage.src = targetUrl; }}Copy the code

ProxyImage helps us schedule the work related to pre-loading. We can use the proxy ProxyImage to achieve indirect access to the real IMG node and get the effect we want.

Reference documentation

  1. Front-end performance optimization principles and practices
  2. Core principles and application practice of JavaScript design pattern
  3. 25 JS Tips you should Know

conclusion

These are some common JavaScript tricks, but if there are any other abbreviations that haven’t been mentioned, you are welcome to add them.