Methods - JavaScript Core Concepts
Tags: codenewbie, javascript, webdev, beginners
Published: 2022-10-26 16:17:08

The **Section 2:** _**Functions & Methods**_ of my **JavaScript Core Concepts** Series is divided into 6 Parts:

Part 1 Functions
Part 2 Classes
**Part 3 Methods**
Part 4 Callback Methods
Part 5 Scope
Part 6 Hoisting

## JavaScript Custom Methods
### Part 1 What are Methods in JavaScript?
= Functions connected to an Object (becoming part of the Object)
→ Behaviors of the Object

= The fact that methods are usually inside an Object
→ Is what makes it different to a function

### Part 2 How do you create Methods?
= Assign a created Function to an Object

Here are 3 ways to do it: 

#### 1st Way: Using a constructor
##### Code Example 
```
function Event(date) {
	this.date = date	
	this.displayEvent = function(){
		return ‘The event is on ‘ + this.date
	}
}
```

#### 2nd Way: Without a Constructor
##### Code Example
```
var flat8 = {date: ‘September 27th, 2022’}
flat8.displayEvent = function(){
	return ‘This event is on ‘ + this.date
}
```

#### 3rd Way: Using one big Object
##### Code Example
```
var flat8 = {
	date: ‘September 28th, 2022’
	displayEvent: function(){
		return ‘This event is on ‘ + this.date
}
}
```

...

## JavaScript Built-in Methods

Below, I'll be going over a couple useful String Methods, Math Methods, Array Methods, and Object Methods.

These should provide a brief overview of functionality offered...

### Part 1 String Methods
#### Where can you find Built-in Methods?
**MDN Web Docs**
= Core document for the web, Javascript, CSS
= Maintained by Mozilla for a while 
→ Look for: "String" → "Instance Methods" → "Code Examples"

#### View String Methods in VSCode 
= Type “myName.”

#### String Methods vs Properties 
**Example**: `myName.length = Popular`
= `.length` is a **Property**
→ Returns number of characters w/in string

**Example**: `myName.toUpperCase()`
= `.toUpperCase` is a **Method**

#### Concatenating Strings
= Adding them together 

**Example**: `const myName = firstName + secondName;`
= Adds them tightly together 

If you want _space_ between strings 
= Add them _within a string_

#### `.toUpperCase()`
= Logs all characters of string in uppercase 
Does not change original variable value

##### First Character Uppercase & All Else Lowercase
= Options to complete:

a. `language.replace(“j”, “J”)`

b. `language.charAt().toUpperCase() + language.slice(i)`
= `charAt`: Finding the character at that position
= `slice`: Takes a beginning index & an optional ending index 
→ Including & excluding the number is different for the two
`${langugae.charAt().toUpperCase()}${language.slice()}`

##### Character Codes
= Where the character is on this table: www.AsciiTable.com

### Part 2 Math Methods
#### Display in VSCode Color
= Orange 

#### Math.floor
1. Takes a Floating Point Number

2. Eliminates Decimals

3. Rounds down to nearest Whole Number less than it

#### Math.ceil
1. Takes Floating Point Number 

2. Eliminates Decimals

3. Rounds to nearest Whole Number more than it

#### Math.round 
= Rounds to nearest Whole Number
→ Depending on Decimal Amount

#### Math.random
= Generates a Random Number between 0 & 1
→ Numbers generated are not truly random 
→ Have scenes to create pseudo-random numbers

#### View Math Methods 
= To apply Math methods to Math objects
→ You can type “Math.” into VSCode
→ And you can find what you need in the list 

#### Practical Uses
1. Docs & Autocomplete
2. Memorizing Objects & Methods

...

### Part 3 Array Methods 
#### How do you access Array Methods?
= Arrays are tied to `Array.prototype`
→ Array methods work on Arrays & any Array-like Objects

Here are a few useful Array Methods…

#### `Array.prototype.indexOf()`
##### Syntax 
```
array.indexOf(searchElement, *from index of*)
```

##### Purpose 
= Searches Array for an Element including a specific value

##### Application 
_Option_: Provide a starting Index to Function
_No Provided Start Index_: Search will begin from Index 0 

##### Returns 
= Lowest Index greater than or equal to start of Array
→ Where Element is equal to given value 
→ AKA the Index of the 1st Element equal to the given value

###### What happens if no match is found?
= Function returns: `-1`

##### Examples:
```
var events = [‘Party’, ‘Dinner’, ‘Show’, ‘Movie’, ‘Dance’];

console.log(events.indexOf(‘Dinner’)); // Logs: 1
console.log(events.indexOf(‘Show’, 1)); // Starts searching at element at index 1, and Logs: 2
```

##### Array of events, and there might be multiple of a given event
→ `indexOf()` can be used to find all Instances of ‘Party’ in the array of events
→ Executing the code displays that ‘Party’ is found at Index 0 and 4 of the Array 

###### Example 
```
var events = [‘Party’, ‘Dinner’, ‘Show’, ‘Movie’, ‘Dance’, ‘Party’];
var event = ‘Party’;
var eventLocation = events.indexOf(event);
while (eventLocation != -1) { // While there exists an event called ‘Party’ within the events array
	locatedat.push(eventLocation);
	eventLocation = events.indexOf(event, eventLocation + 1); // Starts searching for other instances of ‘Party’ AFTER the index of where the first instance of ‘Party’ was found
}
console.log(locatedat); // Logs: 0, 4 
```

##### Using a Custom Function to ensure that each Event is within the array of events, and if they do not exist, we add them to the array:

###### Example
```
function existingEvents(events, event) {
	if (events.indexOf(event) ===  -1) { // If the event does not exist within the array of events 
		events.push(event);
		console.log(‘The new events are ’ + events);
} else if (events.indexOf(event) > -1) {
	console.log(event + ‘ is already part of the events.’)
}
}

var events = [‘Party’, ‘Dinner’, ‘Show’];

existingEvents(events, ‘Party’); // Party is already part of the events.
existingEvents(events, ‘Movie’); // The new events are Party,Dinner,Show,Movie 
existingEvents(events, Dance); // The new events are Party,Dinner,Show,Movie,Dance
existingEvents(events, ‘Parade’); // The new events are Party,Dinner,Show,Movie,Dance,Parade
existingEvents(events, ‘Dinner’); // Dinner is already part of the events.
``` 

#### `Array.prototype.slice()`
##### Syntax 
`array.slice([beginning index], [ending index])`

##### Purpose 
1. Accepts a start and end Argument 

2. Only looks into the Array from start (inclusive) to end (non-inclusive) Index

3. Eliminates a specific amount of Elements 

_No End Value Provided_
= Returns rest of Array
→ Beginning from provided start point

##### Mutates Original?
= No

##### Returns 
= Returns a new Array including all Elements of original Array
→ From Element specified by starting point provided 
→ And up to but not including Element specified by ending point provided

##### Example
```
var events = [‘Party’, ‘Dinner’, ‘Show’, ‘Movie’, ‘Dance’, ‘Party’];
var choppedEvents = events.slice(2,3);

console.log(choppedEvents); // Show
```
= Slice Method needs to be assigned to a Variable upon invocation in order for the Result to be recorded
→ The elements being sliced will be picked out and recorded 
→ In order to return only one element, the element’s index, along with the index after it, needs to be provided

#### `Array.prototype.toString()`
##### Syntax
`array.toString()`

##### Purpose
1. Converts all Elements in Array to Strings 

2. Outputs 1 big String
= As a comma separated list of items 

#### `Array.prototype.filter()`
##### Syntax
`array.filter(*callback function*, *arguments*)`

##### Purpose
= Filters down a collection of Elements 
→ Based on a given test

_In order to call filter()_
= Need to pass a Callback 
→ Callback is executed against every Element in Array 

_If Callback results in `true` value_
= That particular Element is added to a NEW Array 
→ Leaving original Array unchanged 

##### Mutate Original?
= No

##### Returns
= New Array
→ Containing only Elements of original Array that returned `true` when provided Callback ran 

#### `Array.prototype.join()`
##### Syntax
`string = array.join([separator = ‘,’])`

##### Purpose 
1. Converts each Element of Array to a String 

2. Then concatenates those Strings together 

##### Application 
_If separator string provided_
= Gets inserted between all Elements in final String

##### Returns 
1. String that results from converting each Element of original Array to a String 

2. Then joins them together 
= With separator String between Elements 

#### `Array.prototype.splice()`
##### Syntax
`array.splice(*starting index*, *number of elements to delete*, *element to insert in place of deleted*)`

##### Purpose 
1. Delete 0 or more Elements 

2. Beginning from provided start location 

3. Replaces those Elements with 0 or more new values provided 

4. Existing items in Array are shifted
= As needed to make room for any added or deleted Elements

##### Mutates Original?
= Yes, it modifies the original Array directly

##### Returns 
= Returns an Array containing any Elements that may have been deleted from Array 

#### `Array.prototype.forEach()`
##### Syntax
`array.forEach(*callback function*, *arguments*)`

##### Purpose 
= Executes a provided Function
→ On each Element of Array 

##### Returns 
= No return value 
→ Does not return the original Array 

##### Application 
= Related to `.map()`, `filter()`, `every()`, and `some()`
→ Because they share some related details 

1. All expect a Callback Function as 1st argument 

2. All check length of array before looping 

_Optional 2nd Argument_
= Way to specify the `this` value for Callback Function 

_If Callback Provided_
= Adds Elements to Array during execution 
→ Elements are not included for looping by `forEach()`

_If Callback changes original Array values_
= Before they are looped over
→ Those changed values will be passed during Callback execution

##### Mutates Original?
= Yes 

#### `Array.prototype.concat()`
##### Syntax 
`var newArray = oldArray.concat(value1, value2, value3)`

##### Purpose
1. Creates new Array which is result of adding supplied Arguments to original Array 

2. Original Array left intact 

3. New Array is original plus any added Elements

##### Mutates Original?
= No 

##### Application 
1. Any Arguments in `concat()` Function are Arrays

2. Elements of the supplied Array are added
= Rather than entire Array itself 
→ So you are adding all those Elements
→ Rather than adding an Array as one Element within an Array 

##### Returns 
= A new Array 
→ Which is created by adding each of the supplied Arguments to original Array 

#### `Array.prototype.shift()`
##### Syntax
`array.shift()`

##### Purpose 
1. Removes & Returns 1st Element of original Array 
2. All remaining Elements in Array get shifted 1 slot to the left 
= To fill hole created by removing 1st Element

##### Mutates Original?
= Yes 

##### Application 
_If apply function to empty Array_ 
= Does nothing 
→ Simply returns `undefined`
= Does not create a new Array
→ Modifies original array directly

##### Returns 
= Returns 1st Element from original Array 

#### `Array.prototype.unshift()`
##### Syntax 
`array.unshift(*element1*, *element2*)`

##### Purpose 
1. Direct opposite of `shift()`

2. Inserts any Arguments passed into beginning of Array 

3. All existing Elements need to shift to right to accommodate new Elements 

4. Each Argument passed to `unshift()` gets added
= In order starting from Index 0

5. Modifies original Array directly 

##### Mutates Original?
= Yes 

##### Returns
= New length of the Array

#### `Array.prototype.map()`
##### Syntax
`array.map(*callback function*, *arguments*)`

##### Purpose
1. Loops over every Element in Array 

2. Executes a Callback Function on each item

3. After `map()` has completed looping through Array

4. Takes results from each Callback applied to each Element

5. Then returns all those results as an Array

6. Left with: New Array w/ updated Values & Old Array w/ original Values 

7. The 2 Arrays are equal in length 

_When Callback Invoked_
= Done so with 3 arguments:
1. Value of element 
2. Index of element 
3. Array object being traversed

_Optional 2nd Parameter Provided_
= Used at the `this` value for each execution of the Callback 

##### Application 
`map()` vs `forEach()`
= Seem like same 
→ But different

`forEach()` 
= Iterates over Array 
= & Applies some operation with side effects to each array member
**ie** Saving each one to the database or Some other side effect 

`map()`
= Iterates over Array 
= & Updates each member of Array 
→ Returns: Another array of same size → With transformed members 
**ie** Converting array of strings to all lowercase

##### Returns 
= Returns a new Array 
→ With Elements computed by provided Callback Function 

##### Use Cases
= A lot in professional software

#### `Array.prototype.sort()`
##### Syntax 
`array.sort([compareFunction])`

##### Purpose 
1. Applies the sort directly on original Array 

2. No copy is made

3. Optionally provide a Callback Function 
= To create custom behavior for tne sort

###### Mutuates Original?
= Yes

##### Returns 
= Reference to original Array 

##### Application 
_No Callback Function Provided_
= Function will 1st convert all elements to strings 
→ Then sort based on something called Unicode code point value 
→ Alphabetical
→ But with some special rules 
**ie** Capital letters coming before lowercase 

##### Example 
###### Without Callback
```
var names = [‘Angeline Wang’, ‘Paul Smith’, ‘Judy Palmer’, ‘Tracey Chan’];
names.sort(); // Sorts the elements into alphabetical order

var nums = [1, 10, 2, 21, 33, 04, 12, 09, 300];
nums.sort(); // Sorts numbers by unicode code point value, so not directly by chronological order: For example, 10 comes before 2 in Unicode code point order

var usernames = [‘223angeline’, ‘angelinewang’, ‘4paulsmith’] ;
usernames.soft();
// In Unicode, numbers come before uppercase letters, which come before lowercase letters 

console.log(names);
// [“Angeline Wang", "Judy Palmer", "Paul Smith", "Tracey Chan"]

console.log(nums);
// [1, 10, 12, 2, 21, 300, 33, 4, 9]

console.log(usernames);
// [‘223angeline’, ‘4paulsmith’, ‘angelinewang’]
```
_If Callback not provided to sort method_
= Ordering may not be what you expect: B/c unicode code point order 
→ Rules for ordering in Unicode are a bit unique 
→ **ie** Numbers come before uppercase letters, uppercase letters come before lowercase letters
→ Array of numbers is converted to Strings, before sorting: So this is why 33 comes before 4 & 9 in above example

###### With Callback
= And now sorts in the order for numbers you’d expect 
```
var nums = [1, 10, 2, 21, 33, 04, 12, 09, 300];
nums.sort(numsasexpected);

function numsasexpected(one, two) {
	return one - two;
}

console.log(nums);
// [1, 2, 4, 9, 10, 12, 21, 33, 300]
```

#### `Array.prototype.pop()`
##### Syntax
`array.pop()`

##### Purpose 
1. Opposite of `push()`

2. Removes last Element from an Array 

3. Decrements length of Array
 
4. Returns value removed from Array 

##### Application 
= If you apply `pop()` to an empty array 
→ Will return `undefined`

##### Returns 
= Last Element of Array it is called on 

#### `Array.prototype.reduce()`
##### Syntax
`array.reduce(*callback function*, *initial value*)`

##### Purpose
1. Accepts a function as 1st parameter

2. Acts like a binary operator 

3. Callback Function takes 2 values

4. Operates on them
 
5. Returns a value 

6. Number of times Callback Function runs 
= Always 1 less than total length of original Array

##### Application 
**Example**: If original Array has length of 10
= Callback will run 9 times 
→ Final result: 1 combined Value 

##### Returns
1. Reduced value of Array 

2. This is the return value of the last time the Callback Function is executed 

##### Example 
= Execute `.reduce()` over values inside a simple array of objects 
```
var users = [
	{	
		name: ‘Stacey’,
		university: ‘King’s College London’,
		course: ‘Law’,
		degreeLevel: ‘BA’,
		age: 21,
		partiesHosted: 2
	},
	{	
		name: ‘Tom’,
		university: ‘King’s College London’,
		course: ‘Business’,
		degreeLevel: ‘BA’,
		age: 21,
partiesHosted: 4
	},
	{	
		name: ‘Drake’,
		university: ‘King’s College London’,
		course: ‘Business’,
		degreeLevel: ‘BA’,
		age: 22,
		partiesHosted: 2
	},
	{	
		name: ‘Emily’,
		university: ‘King’s College London’,
		course: ‘Social Sciences’,
		degreeLevel: ‘MA’,
		age: 19,
		partiesHosted: 2
	}
];

var totalParties = users.reduce(function (prev, current) {
	return prev + current.partiesHosted;
}, 0);

console.log(‘Users have a cumulative of: ’ + totalParties + ‘parties hosted!’);
// Users have a cumulative of: 10 parties hosted! 

var degreeLevelTotals = users.reduce(function (groupedByDegreeLevel, user) {
	var degreeLevel = user.degreeLevel;
	if (!groupedByDegreeLevel[degreeLevel]) {
		groupedByDegreeLevel[degreeLevel] = 0;
	}
	groupedByDegreeLevel[degreeLevel] += user.partiesHosted;
	return groupedByDegreeLevel;
}, {});

console.log(‘Our users have ’ + degreeLevelTotals[‘MA’] + ‘ parties hosted by masters students and ‘ + degreeLevelTotals[‘BA’] + ‘ parties hosted by bachelors students!’);

// Our users have 2 parties hosted by masters students and 8 parties hosted by bachelors students!

var usersByDegreeLevel = users.reduce(function (groupedByDegreeLevel, user) {
	if (!groupedByDegreeLevel[user.degreeLevel]) {
		groupedByDegreeLevel[user.degreeLevel] = 0;
	}
	groupedByUsers[user.degreeLevel]++;
	return groupedByUsers;
}, {}); 

console.log(‘We have ’ + usersByDegreeLevel[‘MA’] + ‘ user(s) completing a masters degree, and ’ + usersByDegreeLevel[‘BA’] + ‘ users completing a bachelor's degree!’);

// We have 1 user(s) completing a masters degree, and 3 users completing a bachelor’s degree!
```

#### `Array.prototype.some()`
##### Syntax 
`array.some(*callback function*, *arguments*)`

##### Purpose
1. Runs provided Callback on each Element in the Array 

2. If Callback returns `true` even once
= Function stops straight away 
→ And returns `true`
 
3. If ALL Callback Iterations return `false` 
= Function returns `false`

##### Application 
1. Takes a Callback as 1st Argument

2. Takes an Optional 2nd Argument

3. If 2nd Argument Provided
= Specifies `this` value for invocations of supplied Callback

##### Returns
= Returns either `true` or `false`
→ At least 1 item in array must return `true` 
→ For Function to return `true`

##### Example
```
function containsParty(element, index, array) {
	return element === ‘Party’;
} 

var eventsThisWeek =  [‘Party’, ‘Show’, ‘Dinner’, ‘Show’, ‘Movie’, ‘Dance’, ‘Party’];
var eventsNextWeek =  [‘Show’, ‘Dinner’, ‘Show’, ‘Movie’, ‘Dance’];

console.log(eventsThisWeek.some(containsParty)); // true 
console.log(eventsNextWeek.some(containsParty)); // false
```

#### Array.prototype.lastIndexOf()
##### Syntax 
`array.lastIndexOf(*searchElement*, [*fromIndex = arr.length-1*])`

##### Purpose 
1. Tests for Strict Equality 

2. Searches through an array backwards for the value provided in the first argument

3. After the function locates the value

4. Returns the index position of where it exists in the array 

_Optional 2nd Argument not provided_
= Search will begin from that point
→ And goes backwards

_2nd Argument is Provided_
= Search starts at end of Array 
→ If no match is found 
→ `-1` is returned

##### Returns
1. Highest index position (first found, counting from end)
= That is less than or equal to the start of the array

2. Element needs to match strictly equal to value provided

3. If no match, then returns `-1`

##### Example
###### Find One 
```
var events = [‘Party’, ‘Show’, ‘Dinner’, ‘Show’, ‘Movie’, ‘Dance’, ‘Party’];

console.log(events.lastIndexOf(‘Show’)) // Finds the last instance of ‘Show’ and logs: 3
console.log(events.lastIndexOf(‘Party’)) // Starts looking from end of array and logs: 6
console.log(events.lastIndexOf(‘Dance’, 3)); // Starts looking at index position 3, and looks backwards, and logs: -1 because there are no instances of ‘Dance’ at or before the index position 3 
console.log(events.lastIndexOf(‘Show’, -4)); // Starts looking at index position 3, and finds the element there so logs: 3
```

###### Find All
```
var locatedat = [];
var events = [‘Party’, ‘Show’, ‘Dinner’, ‘Show’, ‘Movie’, ‘Dance’, ‘Party’];
var event = ‘Show’;
var eventLocation = enemies.lastIndexOf(event);
while (enemyLocation != -1) {
	locatedat.push(enemyLocation);
	eventLocation = events.lastIndexOf(event, eventLocation -1);
}
console.log(locatedat); // 3, 1
```

#### `Array.prototype.reduceRight()`
##### Syntax
`array.reduceRight(*callback function*, *initial Value*)`

##### Purpose 
1. Works same as `reduce()`
= But w/ 1 difference: `reduceRight()` counts array elements from _right_ to left 
→ Counts from _highest_ index to the lowest index number
→ Rather than left to right, lowest to highest index number 

##### Example
```
var sum = [0, 1, 1, 2, 3, 5, 8].reduceRight(function (a, b) {
	return a + b;
});

console.log(sum); // 20

var flat = [[0, 10], [20, 30, [1, 2, 3, 4]], [40, 50]].reduceRight(function (a, b) {
	return a.concat(b);
}, []);

console.log(flat); // [40, 50, 20, 30, [1, 2, 3, 4], 0, 10]
```

#### Array.prototype.every()
##### Syntax
`array.every(*callback function*, *arguments*)`

##### Purpose 
1. Test if a condition is true for ALL Elements in Array 

2. Expected to provide a Callback Function 

3. Callback Function runs on each Element in Array 
= From lowest to highest index 

4. If _all_ Iterations return `true` when Callback runs 
= `every()` function itself will return `true` 

5. If _even one_ iteration of Callback returns `false` 
= `every()` stops right away & returns `false`

##### Example 
```
function greaterThan10(element, index, array) {
	return element > 10;
}

arr1 = [11, 12, 13, 14];
arr2 = [20, 21, 12, 9];

console.log(arr1.every(greaterThan10)); // true
console.log(arr2.every(greaterThan10)); // false
```

#### `Array.prototype.reverse()`
##### Syntax
`array.reverse()`

##### Purpose
1. Reverses order of Elements in Array 

2. Mutates original Array

3. No new Array created or returned 

##### Mutates original?
= Yes

##### Application
1. Many references to particular Array in the Program

2. And you reverse the array
= All references now also see an array which has been reversed
→ Leaving dependent operations affected

##### Example 
```
var events = [‘Party’, ‘Dinner’, ‘Show’, ‘Movie’, ‘Dance’, ‘Party’];
events.reverse();

console.log(events);
// [‘Party’, ‘Dinner’, ‘Show’, ‘Movie’, ‘Dance’, ‘Party’]
```
= Note how this method invocation does not need to be attached to a variable since it directly works on the original 

...

### Part 4 Object Methods
#### How do you access values in an Object?
= Since values in an Object are not indexed
→ They are accessed through their Keys 

#### `.forEach()`
= Array Iterator Method that CANNOT be used to iterate over the keys on an _Object_
→ Instead, a `for in` Loop should be used instead…

#### `for in` Loop
= This is similar to a `forEach` Loop
→ Purpose: Iterate over an Object

##### Parameters
###### 1. Key 
= All Keys in that Object 

###### 2. Object 
= Name of the Object 

##### Syntax
```
for (let key in car) {
	console.log(car[key])
}
```

##### Purpose 
= Iterates over each key/value pair

_During Each Iteration_
The Key = Whatever is incrementing
**ie** `car.type = (let type in car)`, `car.color = (let color in car)`

##### Log Value of a Key of an Object
###### Syntax
`console.log(car[key])`

#### `Object.keys`
= Returns all the keys within the Object = An Array 

#### `Object.values` 
= Returns all the values within the Object = An Array

#### `Object.entries`
= Returns all the key/value pairs = An Array of Arrays 

### Resources for Further Exploration:
[Most Useful JavaScript Array Functions](https://vegibit.com/most-useful-javascript-array-functions/)