Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Date

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at the Date object.

Date

The Date constructor lets us create date objects.

We can create a new Date instance by passing in nothing, a date string, values for day, month, time, etc., or a timestamp.

For instance, to create the date with the current date, we can write:

new Date();

Also, we can pass in a date string:

new Date('2020 1 1');

and we get:

Wed Jan 01 2020 00:00:00 GMT-0800 (Pacific Standard Time)

or:

new Date('1 1 2020');

and we get:

Wed Jan 01 2020 00:00:00 GMT-0800 (Pacific Standard Time)

Or:

new Date('1 jan 2020');

and we get:

Wed Jan 01 2020 00:00:00 GMT-0800 (Pacific Standard Time)

The Date constructor can figure out the date from different strings.

We can also pass in numeric values to the the Date constructor to represent the:

  • year
  • month, with 0 representing January to 11 for December
  • day — 1 to 31
  • hour — 0 to 23
  • minutes — 0 to 59
  • seconds — 0 to 59
  • milliseconds — 0 to 999

For example, we can write:

new Date(2020, 0, 1, 17, 05, 03, 120);

And we get:

Wed Jan 01 2020 17:05:03 GMT-0800 (Pacific Standard Time)

If we pass in a number that’s out of range, it’ll be adjusted to be in range.

For instance, if we have:

new Date(2020, 11, 32, 17, 05, 03, 120);

Then we get:

Fri Jan 01 2021 17:05:03 GMT-0800 (Pacific Standard Time)

We can also pass in a timestamp.

For instance, we can write:

new Date(1557027200000);

And we get:

Sat May 04 2019 20:33:20 GMT-0700 (Pacific Daylight Time)

If we called Date without new , then we get a string representing the current date.

It doesn’t matter whether we pass in the parameters.

So if we have:

Date();

We get:

"Mon Aug 03 2020 15:02:32 GMT-0700 (Pacific Daylight Time)"

Date Methods

We can adjust the date with some instance methods.

For instance, we can use getMonth(), setMonth(), getHours(), setHours(), etc. to set the parts of a date.

To return a string, we call toString :

const d = new Date(2020, 1, 1);  
d.toString();

Then we get:

"Sat Feb 01 2020 00:00:00 GMT-0800 (Pacific Standard Time)"

To set the month, we call setMonth :

d.setMonth(2)

This returns the new timestamp:

1583049600000

To get a human-readable date, we can call toString :

d.toString();

and get:

"Sun Mar 01 2020 00:00:00 GMT-0800 (Pacific Standard Time)"

We can get the timestamp of a date with Date.UTC :

Date.UTC(2029, 0, 1);

And we can pass that into the Date constructor:

new Date(Date.UTC(2029, 0, 1))

The now method also returns the current timestamp, so we write:

Date.now();

and we get:

1596492422408

We can do the same with valueOf or the + operator:

new Date().valueOf();  
+new Date();

and they both return the current timestamp.

Conclusion

Dates can be manipulated with the Date constructor with JavaScript.

We can convert between timestamps, date objects, and string.

Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Constructors and Shorthands

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at constructors and object shorthands.

The constructor Property

The constructor property is part of an instance object.

It contains the reference to the constructor function.

So if we have:

function Person(name, occupation) {
  this.name = name;
  this.occupation = occupation;
  this.whoAreYou = function() {
    return `${this.name} ${this.occupation}`
  };
}

const jane = new Person('jane', 'writer');

Then:

jane.constructor

is the Person constructor function.

The instanceof Operator

The instanceof operator lets us check whether the object is created with the given constructor.

For instance, we can write:

jane instanceof Person

then we get true .

And if we write:

jane instanceof Object

and that’s also true .

Functions that Return Objects

A function that returns an object is called a factory function.

For instance, we can create a factory function by writing:

function factory(name) {
  return {
    name
  };
}

Then we can call it by writing:

const james = factory('james');

Then we get james.names is 'james' .

Constructors can also be written to return an object instead of return an instance of this .

For instance, we can write:

function C() {
  this.a = 1;
  return {
    b: 2
  };
}

Then if we invoke the construction:

const c = new C()

and then we get:

{b: 2}

Passing Objects

We can pass objects into a function.

For instance, we can write:

const reset = function(o) {
  o.count = 0;
};

Then we can use it by writing:

const obj = {
  count: 100
}
reset(obj);
console.log(obj);

And we get:

{count: 0}

from the console log.

Comparing Objects

We can’t compare objects with === since it only returns true if they have the same reference.

For instance, if we have:

const james = {
  breed: 'cat'
};
const mary = {
  breed: 'cat'
};

Then:

james === mary

returns false even if they have exactly the same properties.

The only way that it can return true is if we assign one to object to the other.

For instance, we write:

const james = {
  breed: 'cat'
};
const mary = james;

Then:

james === mary

returns true .

ES6 Object Literals

ES6 gives us a much shorter syntax for defining object literals.

For instance, if we have:

let foo = 1
let bar = 2
let obj = {
  foo: foo,
  bar: bar
}

Then we can shorten that to:

let foo = 1
let bar = 2
let obj = {
  foo,
  bar
}

We can also shorten methods.

For instance, instead of writing:

const obj = {
  prop: 1,
  modifier: function() {
    console.log(this.prop);
  }
}

We write:

const obj = {
  prop: 1,
  modifier() {
    console.log(this.prop);
  }
}

We can also use computed property keys.

For instance, we can write:

let vehicle = "car";
let car = {
  [`${vehicle}_model`]: "toyota"
}

We can do the same for methods.

Conclusion

Object literals can be written in various ways JavaScript.

We can check the constructor with the constructor property and instanceof .

Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Closures

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at functions.

Functions that Return Functions

Fnctions can return functions.

For instance, we can write:

function a() {
  console.log('foo');
  return function() {
    console.log('bar');
  };
}

We return a function and then we can call the function we return.

For instance, we can write:

a()();

Then first call a , so 'foo' is logged.

Then we call the returned function with the second parentheses, so we get 'bar' logged.

Functions that Rewrites Itself

We should be aware that functions can rewrite themselves.

For instance, we can write:

function a() {
  console.log('foo');
  a = function() {
    console.log('bar');
  };
}

Then we get 'foo' logged.

The first console log runs, then the function is reassigned.

We shouldn’t do that and linters will alert us if we do this.

Closures

Closures are functions that have other functions inside it.

The inner functions can access the outer function’s scope.

For instance, if we have:

function outer() {
  let outerLocal = 2;

  function inner() {
    let innerLocal = 3;
    return outerLocal + innerLocal;
  }
  return inner();
}

We have the inner function with the innerLocal variable.

This is only available within the inner function.

It can also access the outer function’s outerLocal variable.

This is useful because we want to have private variables in our code.

We have outerLocal and innerLocal that are only available inner .

outer can’t access the variables of inner .

So we have different levels of privacy with these functions.

Closures in a Loop

If we have a loop that looks like:

function foo() {
  var arr = [],
    i;
  for (i = 0; i < 3; i++) {
    arr[i] = () => i
  }
  return arr;
}

Then if we call it:

const arr = foo();
for (const a of arr){
 console.log(a());
}

then we get 3 from all the console logs.

This is because i is 3 when we assigned the added our function to arr .

var isn’t block-scoped, so we would get the last value of i instead of what’s in the loop.

To get the value of i from the loop heading to the function we assign, we write:

function foo() {
  var arr = [],
    i;
  for (i = 0; i < 3; i++) {
    ((j) => {
      arr[i] = () => j
    })(i)
  }
  return arr;
}

Then we get 0, 1, and 2 as we expect.

We can also replace var with let to make i block-scoped and avoid this issue.

Getter and Setter

Getter functions return values and setters sets values.

We can put the getter and setter functions into a closure so that we can keep them private.

For instance, we can write:

let getValue, setValue;
(() => {
  let secretVal = 0;
  getValue = () => {
    return secretVal;
  };

  setValue = (v) => {
    if (typeof v === "number") {
      secretVal = v;
    }
  };
}());

And we run a function to assign the getValue and setValue functions with functions.

getValue returns the value of secretVal and setValue sets it.

This way, we keep secretVal secret.

Conclusion

Closures are great for various applications.

It’s mostly to keep variables private, and we can also use them to bind variables values the way we expect.

Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Boolean, Number, and String

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at primitive wrappers.

Boolean

The Boolean can be used as a factory function or a constructor.

For instance, we can write:

const b = new Boolean();

and we get a boolean wrapper object returned.

We can convert it back to a primitive value with valueOf :

b.valueOf();

A better use of the Boolean function is to use it as a factory function.

For example, we can write:

Boolean("foo");

then we get true .

It’ll return true for anything truthy and false otherwise.

Boolean without new returns a primitive value.

Number

Number can also be used as a constructor or a factory function.

For instance, if we have:

const n = Number('12');

then we return the number 12.

And if we have:

const n = new Number('12');

then we return an object with value 12.

So we should use it without new to eliminate confusion.

Number also has some static properties.

Number.MAX_VALUE is 1.7976931348623157e+308 .

There’s also the Number.POSITIVE_INFINITY which is Infinity .

And Number.NEGATIVE_INFINITY which is -Infinity .

The toFixed method formats a number to a decimal number with the given number of fractional digits.

For instance, we can write:

(123.456).toFixed(1);

We have “123.5” .

The toExponential method returns the number string in exponential notation.

For instance, if we have (12345).toExponential() , then we get:

"1.2345e+4"

The toString method lets us convert numbers to number strings of various bases.

For instance, we can write:

(255).toString(2)

Then we convert the number to the binary string:

"11111111"

And we can write:

(255).toString(16)

and get:

"ff"

To convert it to a decimal, we write:

(255).toString(10)

And we get:

"255"

String

The String function is used to create a string.

We can use it as a constructor or factory function.

We don’t want to create an object with it to reduce confusion, so we should use it as a factory function.

For instance, we can write:

const obj = new String('foo');

then we create a string wrapper object.

To convert it to a primitive value, we call valueOf :

const s = obj.valueOf();

It’s better just to create a string as a string literal:

const s = 'foo';

We can also use the function to convert non-strings to strings:

const s = String(123);

We can get the number of characters in a string with the length property.

So if we have:

const s = 'foo';

Then s.length is 3.

If we pass in an object to String , then the toString method will be called.

So:

String({
  a: 1
});

returns:

"[object Object]"

And:

String([1, 2, 3]);

returns:

"1,2,3"

Conclusion

Boolean, Number, and String functions let us create primitive values.

We should use them as factory functions to convert between different primitive types.

Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Arrays and Functions

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at arrays and functions.

ES6 Array Methods

ES6 added more useful array methods.

They provided that were previously provided by 3rd party libraries like Underscore and Lodash.

Array.from

The Array.from method lets us convert iterable objects and non-iterable array-like objects into an array.

For instance, we can use it to convert a NodeList returned from document.querySelectorAll into an array.

We can write:

const divs = document.querySelectorAll('div');
console.log(Array.from(divs));

Then we get an array.

We can also convert objects that have numeric index and a length property into an array.

For example, we can write:

const obj = {
  0: 'a',
  1: 'b',
  length: 2
};
console.log(Array.from(obj));

And we get:

["a", "b"]

Creating Arrays Using Array.of

We can use the Array.of method to create a new array.

For instance, we can with:

let arr = Array.of(1, "2", {
  obj: "3"
})

Then we get:

[
  1,
  "2",
  {
    "obj": "3"
  }
]

It takes one or more arguments and returns an array with the arguments.

ES6 Array.prototype Methods

The array instance all have more methods added to them.

They include the following methods:”

  • Array.prototype.entries()
  • Array.prototype.values()
  • Array.prorotype.keys()

entries returns the key-value pair array.

values returns an array of values.

keys returns an array of keys.

So we can write:

let arr = ['a', 'b', 'c']
for (const index of arr.keys()) {
  console.log(index)
}

for (const value of arr.values()) {
  console.log(value)
}

for (const [index, value] of arr.entries()) {
  console.log(index, value)
}

We log the index with the keys method.

And we log the values withe values method.

And index and value with the entries method.

It also added the find and findIndex methods to let us find the first entry of the array that matches a given condition.

find returns the matched entry.

And findIndex returns the index of the matched entry.

For instance, we can write:

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(numbers.find(n => n > 3));
console.log(numbers.findIndex(n => n > 3));

Then we get 4 and 3 respectively from the console log.

Function

The Function constructor can be used to create a function

For instance, we can write:

const foo = new Function(
  'a, b, c, d',
  'return arguments;'
);

The first argument is the parameters and the 2nd is the function body.

It’s not a good idea to use it since we create functions with strings, which means there will be security and performance issues.

Functions objects have the constrictor and length properties.

The constructor property has the constructor that created the function, which should be the Function constructor.

And the length property has the number of parameters the function expects.

So if we have:

function foo(a, b, c) {
  return true;
}
console.log(foo.length);
console.log(foo.constructor);

We get 3 and ƒ Function() { [native code] } respectively.

Conclusion

We can create arrays with the Array.from and Array.from methods.

Also, we can traverse arrays with various methods.

The Function constructor shouldn’t be used to create functions.