Categories
JavaScript

Good Parts of JavaScript — Flow Control

JavaScript is one of the most popular programming languages in the world. It can do a lot and have some features that are ahead of many other languages.

In this article, we’ll look at some good parts of JavaScript, including flow control.

Falsy Values

Falsy values in JavaScript will prevent an if or else if block from running.

Falsy values are the following:

  • false
  • null
  • undefined
  • empty string ‘’
  • 0
  • NaN

Everything else is truthy.

Switch Statements

switch statements perform multiway branching.

It compares an expression with the specified cases.

A case can be a statement or a block. A case statement or block can contain one or more expressions.

The case expressions don’t have to be constants.

While Statement

A while statement performs a simple loop. The loop will stop running if the condition that’s after while is falsy.

Otherwise, the loop body will run.

For Statement

A for statement is more complex than a while loop.

It may contain 3 optional clauses, which is the initialization code, the condition, while the loop runs, and the increment statement.

First, the initialization code is run.

Then the condition is evaluated at each iteration. If the condition is truthy, then the loop will run.

Otherwise, the loop will break.

Then the increment statement runs. The statement updates the index variable.

The for loop looks like:

for (let i = 0; i < MAX; i++) {  
  //...  
}

The loop runs from i is 0 from i is one less than MAX .

For-In Loop

The for-in loop loops through the keys of an object, including any inherited properties.

The order that the keys are looped depends on how the browser implements the for-in loop.

This means that we can’t depend on the order that the keys are being looped through.

To check if the property is inherited or not, we can use the hasOwnProperty method that comes with objects.

We can do that by writing the following code:

for (const key in obj) {  
  if (obj.hasOwnProperty(key)) {  
    //..  
  }  
}

In the code above, we have the key that we looped through in obj , including inherited properties.

Therefore, we’ve to call obj.hasOwnProperty(key) if we only want to deal with keys that are in obj itself.

For-Of Loop

The for-of loop loops through the items that are in any iterable object.

This includes things like arrays, NodeLists, sets, maps, generators, and anything else we create.

For instance, we can write:

for (const a in arr) {  
  //..  
}

This means looping through items easier than with a while or for loop since we don’t have to specify any conditions.

It just loops through all the entries that are in the iterable object.

Try Statement

The try statement runs a block of code and catches an exception that was thrown in the block.

The catch clauses go after the try clause and receive the exception object.

It looks like:

try {  
  //...  
} catch (ex) {  
  //...  
}

Throw Statement

The throw statement is used to throw exceptions, which can be caught with the try...catch block.

For instance, we can write:

throw new Error('error');

We can throw anything with the throw statement, but the error object has information like stack traces and line number of where the error occurred that aren’t available anywhere else.

Return Statement

The return statement lets us end a function wherever we want inside the function block.

JavaScript doesn’t allow a line between the return and expression that it’s returning.

Break Statement

break statements are for ending loops or terminating the switch statement.

We can also add a label to end a labeled statement.

break and the label has to be the same line.

Expressions Statement

An expression statement can either assign variables or one or more variables or members.

It can also run a method or delete property from an object.

The = operator is used for assignment, which we shouldn’t confuse with the === operator.

The += operator can add or concatenate.

Conclusion

break statements are used for ending loops and switch cases.

return is used for ending functions anywhere in our code.

The throw statement is used to throw any object as an error which can then be caught by the catch block.

Categories
JavaScript

Good Parts of JavaScript — Strings and Flow Control

JavaScript is one of the most popular programming languages in the world. It can do a lot and have some features that are ahead of many other languages.

In this article, we’ll look at some good parts of JavaScript, including strings and flow control.

Strings

Strings can be wrapped in single or double quotes or backticks.

It can contain 0 or more characters. The “ (backslash) is an escape character.

JavaScript doesn’t have a character type. We just put one character in a string to represent one character.

Single or double quotes are good for delimiting short strings that don’t have any dynamic parts inside.

Backticks are used for delimiting template strings, which can contain expressions and can be multiple lines long.

Therefore, whenever we can, we should use template strings.

It’s much more convenient than using regular strings.

We can also use the single or double quotes within template strings as normal characters rather than use it to delimit strings.

For instance, we can define strings in the following ways. We can define a string with single quotes:

const foo = 'foo';

To define strings with double quotes, we can write:

const foo = "foo";

or we can define template strings by writing:

const world = 'world';
const greeting = `hello ${world}`;

Template strings can contain expressions, which can optionally contain expressions.

Expressions are surrounded by the ${} characters.

This is great since dynamic string replaces concatenation, which is a pain to use if we have to create dynamic strings.

We can create multiline strings without hassle as follows:

const hello = `
hello
world
`

Now 'hello' and 'world' will be in separate lines.

We can also use template tags to return a value by passing in a template string.

Template tags are just functions with special signatures.

The first parameter of a template tag is an array of strings, and the remaining parameters are the expressions.

If we write:

const tag = (strings, ...exps)=>{
 console.log(strings, exps);
}

const name = 'world';
tag`hello ${name}`;

We get that strings is [“hello “, “”, raw: Array(2)] and exps is an array of expressions, which is [“world”] .

All strings have a length property. It returns the length of the string.

JavaScript strings are immutable. Once it’s made, it can never be changed.

But we can create new strings by concatenation or putting them in template strings.

2 strings that have the same length and exactly the same characters in the same order are considered the same.

So:

'foo' + 'bar' === 'foobar';

returns true .

JavaScript strings also have many methods that we can use to manipulate them.

Photo by Samuel Ferrara on Unsplash

Statements

JavaScript programs are composed of one or more statements.

If we use script tags only, then everything is thrown into the global namespace.

However, with the introduction of JavaScript modules, modules can be bundled together to compile them into a big bundle.

let or var can be used to declare variables. And they’re private if they’re declared in a function.

let is also private within the block.

const defines a constant, which is also block scoped.

Constants are mutable, but we can’t assign them to a new value.

The switch , while , for and do statements are allowed to have an optional label statement that can be used with the break statement.

Statements are usually run from top to bottom.

The sequence can be changed with conditional statements, if and switch .

Loop statements, while , for , and do can also change the order of execution of statements.

Disruptive statements like break , return , and throw can also change the execution flow.

Function invocation can also change the flow of the program.

A block is wrapped in curly braces. Blocks create a new scope for any data declared with let or const .

Therefore, it’s preferred that we use let or const to declare our variables and constants.

An if statement changes the flow of a program based on the value of the expression within the parentheses.

If it returns true , then the code in the if block is run.

Otherwise, else if ‘s conditions will be check and the code in those blocks will run if possible.

If an else block is present, that will run if other blocks before it isn’t run.

Conclusion

Template strings are great. We can have expressions and they can be more than one line long.

Statements are building blocks of programs. We can run the flow can change based on various flow control statements.

Categories
JavaScript

The Good Parts of JavaScript

JavaScript is one of the most popular programming languages in the world. It can do a lot and have some features that are ahead of many other languages.

In this article, we’ll look at some good parts of JavaScript.

Misconceptions About JavaScript

We can’t assume that JavaScript is like any other language. To take advantage of the good parts, we’ve to learn it as a new language.

It’s possible to create things with JavaScript without knowing too much about it.

But without knowing the good parts, we won’t be writing code as cleaning as we could.

Dynamic Types

We can use dynamic types to our advantage. With or without strong typing, we got to test our code thoroughly.

Otherwise, we’re going to run into issues regardless of whether the language has strong typing or not.

Type errors are only one class of errors and we can eliminate that with tests that we have to type anyways.

The dynamically typed natures of JavaScript with the ability to create one-off objects with object literals are a great feature that we can’t ignore.

We can create objects without creating classes.

Also, it inspired the JavaScript Object Notation (JSON) for transmitting data,

It’s very similar to JavaScript object literals and we can convert them easily.

Simple Testing Ground

Both Node.js and browsers have a REPL where we can test out our code.

There’re also many online JavaScript editors for running Node.js and browser code.

Many of those editors even have templates for creating projects with various frameworks out of the box.

We can also include libraries on the fly.

With REPLs and online editors, we can create tests and prototype code without much effort.

In all the editors and REPLs, we can see the results right away.

Whitespace

In JavaScript, whitespace are usually insignificant. This lets us have some flexibility in formatting our code.

However, there are some whitespace that are required to separate some tokens like keywords and variables.

For instance, if we have:

const foo = this;

Then the space after the const is required, but the rest are not.

Comments

Comments are good to add to let us clarify our code.

We can write comments with blocks surrounded with /* */ or start with // ..

2 forward slashes are also used by regex literals, so we probably don’t want to use them.

Instead, we can create comment blocks with /* */ .

Names

Names in JavaScript are letters that are optionally followed by one or more characters, digits, or underscores.

They also can’t be reserved words that are used by the JavaScript language itself.

We can’t use reserved words as function names, class names, or variable names.

Numbers

There’s a single number type in JavaScript.

Floating point numbers and interest are all one type.

This is more convenient than having separate types for different kinds of numbers.

Having one type of number eliminates the type of errors that are caused by different types of numbers.

If a number has an exponential part, then the value of the literal is computed by multiplying the part before the e by 10 raised to the power after the e .

For instance, the number 1000 and 1e3 are the same number.

Negative numbers are formed by the - prefix operator.

NaN is a number value that’s the result of an operation that can’t produce a number.

NaN isn’t equal to any value, including itself.

For instance, if we divide a number by 0, then we get NaN returned.

We can check if something produces NaN by using the Number.isNaN method, which checks the value as-is, or the isNaN function, which does the conversion to number before checking the returned value.

Numbers have various methods that we can use to manipulate them. Also, we can do Math with the Math object.

Conclusion

JavaScript has a few useful features.

We can use dynamic typing to our advantage. The ability to create and use object literals is a convenience feature that many programming languages don’t provide.

It also has comments we can use to clarify code.

There’s only one number type in JavaScript, which eliminates lots of issues with multiple types of numbers.

Categories
JavaScript

Good Parts of JavaScript — Recursion and Scope

JavaScript is one of the most popular programming languages in the world. It can do a lot and have some features that are ahead of many other languages.

In this article, we’ll look at ways to make a function call itself and scopes of functions.

Recursion

A recursive function is a function that calls itself.

We can use it do divide a problem into a set of subproblems, each with a trivial solution.

For instance, we can create a recursive function as follows:

const count = (i) => {
  if (i === 10) {
    return;
  }
  console.log(i);
  count(i + 1);
}

count(0);

In the code above, we have a simple recursive function that stops with i reaches 10.

For each value of i , we log the value of i to the console.

We should make sure that we have a base case to stop the function.

If a function returns the result of running itself recursively, JavaScript doesn’t optimize that by replacing it with a loop.

For instance, if we have:

const factorial = (i, a = 1) => {
  if (i < 2) {
    return a;
  }
  return factorial(i - 1, a * i)
}

const result = factorial(10);

Then JavaScript will turn that into a loop, so the call stack would be full if we call it too many times.

Scope

Scope in a programming language controls the visibility of variables and parameters.

In JavaScript, we have a function and block-scoped variables.

let and const are block-scoped and var is function-scoped.

Therefore, to reduce confusion, we should use let and const to declare data.

For instance, if we have:

if (condition) {
  let x = 1;
  const y = 2;
  //...
}

x and y are block-scoped, so they’re only available within the if blocks.

We should just forget about var and use let or const exclusively.

Variables should be declared as late as possible so that their lifetimes are short.

This reduces the need to follow the use of variables through many lines of code when we’re reading code.

Closure

Inner functions get access to parameters and variables of functions that are defined in.

We can use this to make values private and use them in inner functions.

For instance, we can write:

const obj = (() => {
  let value = 0;
  return {
    increment(val) {
      value += val;
    },
    getValue() {
      return value;
    }
  };
})();

value is private, so that we can update value by incrementing it with val .

So we update value safely without exposing them to the outside.

We used an IIFE above, we can return an object that uses private variables.

Also, we can turn that into a factory function by removing the parentheses.

For instance, we can write:

const createName = (name) => {
  return {
    getName() {
      return name;
    }
  };
};

const name = createName('foo').getName();

We return an object that returns the value of the name parameter.

It’s not a constructor so that we can’t use it with the new operator.

Inner functions have access to the variable itself rather than the value when it’s made.

For instance, if we have:

const addHandlers = (nodes) => {
  for (var i = 0; i < nodes.length; i += 1) {
    nodes[i].onclick = () => {
      alert(i);
    }
  }
}

addHandlers(document.querySelectorAll('button'))

If we run the code above, the alert box always shows 3 no matter which button we click.

This is because the loop body is found to the variable i rather than the variable i at the time the function is made.

To fix this, we can use let instead of var :

const addHandlers = (nodes) => {
  for (let i = 0; i < nodes.length; i += 1) {
    nodes[i].onclick = () => {
      alert(i);
    }
  }
}

addHandlers(document.querySelectorAll('button'))

let is block-scoped so that the onclick handler will get the current value of i rather than the value of i when the loop is done.

Conclusion

Recursive functions are functions that call themselves directly or indirectly.

It’s useful for dividing problems into trivial subproblems.

Scopes of variables depends on how we declare them. If we declare them with let or const , then they’re block-scoped.

If we declare them with var , then they’re function-scoped.

Closures allows us to access private variables.

Categories
Material UI

Material UI — Slider

Material UI is a Material Design library made for React.

It’s a set of React components that have Material Design styles.

In this article, we’ll look at how to add sliders with Material UI.

Discrete Sliders

We can add sliders to snaps to discrete values.

To do that, we set the marks prop to true .

For instance, we can write:

import React from "react";
import Slider from "@material-ui/core/Slider";

export default function App() {
  return (
    <form>
      <Slider marks />
    </form>
  );
}

to make an uncontrolled slider that snaps to the nearest 10.

Small Steps

We can change the steps with the steps prop.

For example, we can write:

import React from "react";
import Slider from "@material-ui/core/Slider";

export default function App() {
  return (
    <form>
      <Slider step={0.00001} marks />
    </form>
  );
}

to change the increment between each discrete value.

Custom Marks

We can add our own custom marks with the marks prop.

For example, we can write:

import React from "react";
import Slider from "@material-ui/core/Slider";

const marks = [
  {
    value: 0,
    label: "0m"
  },
  {
    value: 25,
    label: "25m"
  },
  {
    value: 50,
    label: "50m"
  },
  {
    value: 75,
    label: "75m"
  },
  {
    value: 100,
    label: "100m"
  }
];

export default function App() {
  return (
    <form>
      <Slider step={10} marks={marks} valueLabelDisplay="auto" />
    </form>
  );
}

We add the marks array with the value and label properties in each entry to show the labels with the text in the label property.

Restricted Values

We can restrict values to the ones that are in the marks array by setting step to null .

For example, we can write:

import React from "react";
import Slider from "@material-ui/core/Slider";

const marks = [
  {
    value: 0,
    label: "0m"
  },
  {
    value: 25,
    label: "25m"
  },
  {
    value: 50,
    label: "50m"
  },
  {
    value: 75,
    label: "75m"
  },
  {
    value: 100,
    label: "100m"
  }
];

export default function App() {
  return (
    <form>
      <Slider step={null} marks={marks} valueLabelDisplay="auto" />
    </form>
  );
}

Now we can only select the values that are marked in the marks array because of the null value we passed into the step prop.

Make Label Always Visible

We can make the labels always visible by setting the valueLabelDisplay prop to on .

For example, we can write:

import React from "react";
import Slider from "@material-ui/core/Slider";

const marks = [
  {
    value: 0,
    label: "0m"
  },
  {
    value: 25,
    label: "25m"
  },
  {
    value: 50,
    label: "50m"
  },
  {
    value: 75,
    label: "75m"
  },
  {
    value: 100,
    label: "100m"
  }
];

export default function App() {
  return (
    <form>
      <Slider step={10} valueLabelDisplay="on" marks={marks} />
    </form>
  );
}

Now we see the value above the slider dot.

Range Slider

We can allow users to select a value range with the Slider .

To do that, we can set an array as the value as the initial value.

For example, we can write:

import React from "react";
import Slider from "@material-ui/core/Slider";

export default function App() {
  const [value, setValue] = React.useState([20, 30]);

  const handleChange = (event, newValue) => {
    setValue(newValue);
  };
  return (
    <form>
      <Slider valueLabelDisplay="auto" value={value} onChange={handleChange} />
    </form>
  );
}

to make a range slider.

We set an array as the initial value of the value state to make the slider a range slider.

Vertical Sliders

We can make a slider vertical with the orientation prop set to vertical .

For instance, we can write:

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Slider from "@material-ui/core/Slider";

const useStyles = makeStyles({
  root: {
    height: 300
  }
});

export default function App() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <Slider
        orientation="vertical"
        valueLabelDisplay="auto"
        defaultValue={30}
      />
    </div>
  );
}

to create a vertical slider.

We’ve to set the height of the wrapper so that the slider is displayed.

Track

We can set track to false to remove the track that’s displayed when we select a value.

To do that, we write:

import React from "react";
import Slider from "@material-ui/core/Slider";

export default function App() {
  return (
    <div>
      <Slider track={false} defaultValue={30} />
    </div>
  );
}

to remove th track.

We can also set it to inverted to change the track to be opposite of the default.

Non-Linear Scale

The scale is linear by default, but we can change it to a nonlinear scale with the scale prop set to a function.

We can write:

import React from "react";
import Slider from "@material-ui/core/Slider";

export default function App() {
  return (
    <div>
      <Slider scale={x => x ** 5} defaultValue={30} />
    </div>
  );
}

to change the scale.

Conclusion

We can add sliders to let users select a number or a range of numbers from a slider.