Week 4 (Beginning Jan 31st) Learning Week Cycle 5 - emcsquared2/2022-Learning GitHub Wiki
Arrays
Arrays are like a variable containing more than one item of data. A contiguous part of memory is allocated to storing the data.
1-dimensional arrars are like a column and 2-d arrays are like tables. A 3d array can be visualised as a cube.
A 4-d array could be visualised as a column of cubes.....etc to higher dimensional arrays.
Creating instances
If we change the properties of a class, all instances will have the same properties as the updated class.
Constructors can be empty of properties and still run methods.
If there is no constructor written, a default constructor will run instead in the class.
For loops
Revision
initialize; test; increment_
for(){
}
//for keyword
//parameters
//function
Add the isUpperCase method to String to see whether the string is ALL CAPS
"C".isUpperCase() == true
"hello I AM DONALD".isUpperCase() == false
This was a sneaky little challenge that meant I had to do some research.
I discovered that the data types in Javascript are actually objects and therefore you can add methods and properties to them
I found that if you use the console in the Chrome dev tools and enter....
var word = "hello";
console.log(Object.getPrototypeOf(word));
//You get the following....
String {'', constructor: ƒ, anchor: ƒ, big: ƒ, blink: ƒ, …
anchor: ƒ anchor()
at: ƒ at()
big: ƒ big()
blink: ƒ blink()
bold: ƒ bold()
charAt: ƒ charAt()
charCodeAt: ƒ charCodeAt()
codePointAt: ƒ codePointAt()
concat: ƒ concat()
constructor: ƒ String()
endsWith: ƒ endsWith()
fixed: ƒ fixed()
fontcolor: ƒ fontcolor()
fontsize: ƒ fontsize()
includes: ƒ includes()
indexOf: ƒ indexOf()
italics: ƒ italics()
lastIndexOf: ƒ lastIndexOf()
length: 0
//etc etc
//Note that length is not an f function, it is a property of the String object.
// Doesn't work in VS Code but Dev tool lists all the properties and methods af the String object.
This challenge is effectively asking to add a method to the String object.
When that method is called on a string variable, it should return true if it is all in CAPS
//Firstly define the function using the String.prototype object.
//The function name we are being asked to add is 'isUpperCase'
String.prototype.isUpperCase = function(){
}
//Then we want to use the string Object 'this' and return a true if it is equal to the string in CAPS
String.prototype.isUpperCase = function() {
return this == this.toUpperCase();
};
console.log("BYE".isUpperCase())
//OUTPUT true
Determine if a word or phrase is an isogram.
An isogram (also known as a "nonpattern word") is a word or phrase without a repeating letter, however spaces and hyphens are allowed to appear multiple times.
const isIsogram = str => {
const string = str.toLowerCase();
let isIsogram = true;
for (let i=0; i<string.length; i++){
for (let j=i+1; j<string.length; j++){
if (string[i]===string[j] && string[i] !=='-' && string[i] !==' '){
isIsogram = false;
break;
};
};
};
return isIsogram
};
This took me a little while longer than I would have liked, mainly because I had stuck the return statement within the second for loop by accident.
Carefully thinking throught the nested for loop is not the most intuitive concept in the world the world but it's definitely becoming easier the more I do.
No help required on this one.
Looking at the community solutions there are lots of answers including Isogram.prototype in the answer.
I'm going to prof Steve for help...
Introduction to Prototypes in JS
JS is a prototype based language
In JS when you create an object, you automatically get a prototype object
const obj1 = {
prop1 : ()=> console.log("hello prop1")
};
const obj2 = {
prop2 : ()=> console.log("hello prop2")
};
obj1.prop1()
//OUTPUT hello prop1
//If we want obj1 to use something else as it's prototype i.e obj2
//Then we use the setPrototype method
Object.setPrototypeOf(obj1, obj2)
//now we can call the obj2 function on the obj1 because it is using the obj2 prototype
obj1.prop2()
//OUTPUT hello prop2
//It doesn't lose it's own properties
obj1.prop1()
//OUTPUT hello prop1
//we can call a for loop on obj 1 to list all its properties
for (let prop in obj1){
console.log(prop);
};
//OUTPUT prop1, prop2
//To access the prototype of obj1 we use the Object.getPrototypeOf method
console.log(Object.getPrototypeOf(obj1))
//OUTPUT { prop2: [Function: prop2] }
//We can call the prop2 function on the prototype of obj1 (which is obj2 because we set it that way)
Object.getPrototypeOf(obj1).prop2()
//OUTPUT is "hello prop2"
//To access the own properties of obj1 and not it's prototype
console.log(Object.getOwnPropertyNames(obj1))
//OUTPUT [ 'prop1' ]
//Or we can get the own property names of the prototyp of obj1 i.e the ownproperty names of obj2 ie "prop2"
console.log(Object.getOwnPropertyNames(Object.getPrototypeOf(obj1)))
//OUTPUT [ 'prop2' ]
//Or if we go up the chain and get the own properties of the prototype of obj2
console.log(Object.getOwnPropertyNames(Object.getPrototypeOf(obj2)))
//OUTPUT
/*[
'constructor',
'__defineGetter__',
'__defineSetter__',
'hasOwnProperty',
'__lookupGetter__',
'__lookupSetter__',
'isPrototypeOf',
'propertyIsEnumerable',
'toString',
'valueOf',
'__proto__',
'toLocaleString'
]
*/
//At the top of the chain is null...
console.log((Object.getPrototypeOf(Object.getPrototypeOf(obj2))))
//OUTPUT null
Functions at Runtime
First Class Functions
Functions in JS are first-class because they....
- Can be stored as a variable
- Can be passed as an argument into another function
- Can return it from a function
So a first class function means it has equal status in that programming language as the other data structures
My own revision on different ways to declare functions...
//FUNCTION EXPRESSION (ANONYMOUS function saved to the variable myFunction)
const myFunction = function(name){
console.log(`Hello ${name}`)
}
myFunction("David")
//FUNCTION EXPRESSION (NAMED function saved to the variable myFunction2)
//I don't fully understand the use for the naming yet, something to do with debugging and scope
const myFunction2 = function nameFunction(name){
console.log(`Hello ${name}`)
}
myFunction2("Betty")
//FUNCTION EXPRESSION using ES6 arrow notation
const myFunction3 = name => console.log(`Hello ${name}`)
myFunction3("Brian")
//Function Declaration
function myFunction4(name){
console.log(`Hello ${name}`)
}
myFunction4("Charlie")
Functions are first order objects...
function myFunction4(name){
console.log(`Hello ${name}`)
}
console.log(myFunction4.length)
//OUTPUT 1 as it has 1 parameter
console.log(myFunction4.name)
//OUTPUT myFunction4
console.log(Object.getOwnPropertyNames(myFunction4))
//OUTPUT [ 'length', 'name', 'arguments', 'caller', 'prototype' ]
//The property names of the object prototype. Interesting
console.log(Object.getOwnPropertyNames(Object.getPrototypeOf(myFunction4)))
//OUTPUT [
'length', 'name',
'arguments', 'caller',
'constructor', 'apply',
'bind', 'call',
'toString'
]
Functions are first-class functions so we can return a function from another function.
This is called a higher-order function.
The tutorial gave an example using the terms calling and invoking. I want to understand the difference...
Invoking a JavaScript Function
- The code inside a function is not executed when the function is defined.
- The code inside a function is executed when the function is invoked.
- It is common to use the term "call a function" instead of "invoke a function".
- It is also common to say "call upon a function", "start a function", or "execute a function".
- A JavaScript function can be invoked without being called.
function myFunction(a, b) {
return a * b;
}
myFunction(10, 2); // Will return 20
The function above does not belong to any object but "belongs" to the default global object i.e. the html page.
In a browser, the page object is the browser window. The function above automatically becomes a window function.
This is a common way to invoke a JS function but not very good practice.
Global variables, methods or functions can easily create name conflicts and bugs in the global object.
myFunction and window.myFunction() is the same function
function myFunction(a, b) {
return a * b;
}
window.myFunction(10, 2); // Will also return 20
//Works in e.g. Google dev tool in the browser but does not work in VSCode
Not quite sure on the difference still but will move on and see if I get it later on!
//A function expression that is anonymous
//The function is saved to the variable returnsAFunction
//Inside the function another anonymous function is defined
//So the return value of returnsAFunction is the second anonymous function
const returnsAFunction = function() {
return function () {
console.log("Hello from inside a function")
}
}
//Console.log the variable
console.log(returnsAFunction)
//OUTPUT [Function: returnsAFunction]
console.log(returnsAFunction())
//OUTPUT [Function (anonymous)]
//Calling the returnsAFunction - First brackets () - Invoke the anonymous function second ()
returnsAFunction()()
//OUTPUT 'Hello from inside a function'
//Invoke the anonymous function in the returnsAFunction function and save it to another variable
const newFunction = returnsAFunction()
console.log(newFunction)
//OUTPUT [Function (anonymous)]
newFunction()
//OUTPUT 'Hello from inside a function'
// Me playing around!
const returnsAFunction2 = function() {
return function () {
return function(){
console.log("Hello from a function inside a function inside a function");
};
};
};
returnsAFunction2()()()
//OUTPUT 'Hello from a function inside a function inside a function'
/*
Declare a function named `higherOrderFunction` that takes no arguments,
and returns an anonymous function.
The returned function itself takes no arguments as well, and simply
returns the number 8.
*/
const higherOrderFunction = function(){
return function() {
return 8;
}
};
Consider integer numbers from 0 to n - 1 written down along the circle in such a way that the distance between any two neighboring numbers is equal (note that 0 and n - 1 are neighboring, too).
Given n and firstNumber, find the number which is written in the radially opposite position to firstNumber.
Example
For n = 10 and firstNumber = 2, the output should be solution(n, firstNumber) = 7.
function solution(n, firstNumber) {
return firstNumber >= n/2 ? firstNumber - n/2 : firstNumber + n/2;
}