The idea that a compiler is figuring out all the scopes ahead of time befor being executed
lex → the first stage of parsing
The scope of dynamic scope is determined based upon a conditions at runtime (where this function has been called).
while lexical scope is determined at auther time.
const n = "Sarah"
function f(){
console.log(n)
}
function ff(){
const n = " Hello"
f()
}
ff()
// Sarah => lexical
// Hello => dynamic
You should default to keep evreything private and only exposing the minimal necessary
let x
try {
x = funMayReturnError(1)
}
catch (error) {
x = 5
}
// using anaymaous function
let x = (function bringX() {
try {
return funMayReturnError(1)
}
catch (error) {
return 5
}
})
function f (){
console.log("hello")
}
f()
// we can do
// also it may do not have name
(function ff (){ // not a functon declertion
console.log("hello")
})()
Block(curly braces) are not scopecauntil they have let or const inside them
- Hoisting is the process of moving variable and function declarations to the top of their scope.
- Variable declarations are hoisted but not their assignments. They are accessible but have an initial value of
undefined
. - Function declarations are also hoisted, allowing them to be called before they are defined.
- Hoisting does not apply to function expressions, arrow functions, or variables declared with
let
orconst
.
var t = "1"
o()
function o(){
console.log(t)
var t = "2"
}
o() //undefined
Wa can’t say that let dosn’t have hoisting, insted it’s kind of uninitioalized state
var t = "1"
{
console.log(t)
let t = "2"
}
// error
// but should print 1, beacuse it's in the outer scope,
Closure is when a function “remembers” its lexical scope even when the function is executed outside that lexical scope.
for (var i=1; i<=3; i++){
setTimeout(()=>{
console.log(i)
},1000*i)
}
/*
there is only one i variable that is shared across all the iterations of the
loop. When the setTimeout functions are executed after the delays, they all
use the same value of i, which is 4
*/
for (let i=1; i<=3; i++){
setTimeout(()=>{
console.log(i)
},1000*i)
}
/*
each iteration of the loop creates a new and separate i variable. As a result,
when the setTimeout functions are executed after the delays, each callback
captures its own unique value of i. It
*/
Modules encapsulate data and behavior (methods) together. The state (data) of a module is held by its methods via closure.
Namespace, NOT a module
- Objects are built by "constructor calls" (via new)
- A "constructor call" makes an object “❌based on❌” its own prototype A "constructor call" makes an object “✅linked to✅” its own prototype
when we add ask to prototype, it’s added to the prototype object when we creat deepJS we didn’t copy the prototype of workshop insted it has a link to it, if we try to access sth isn;t exist in the deepJS it search in workShop if not exist it search in > the JS main prototype (inside of it there is toString())
In c++ & Java
in JS
OLOO: 🔥 Objects Linked to Other Objects
- Only standard JS syntax
- Compiler and Runtime (both optional)
- Completely configurable (ie, ESLint)
- Main focus: inferring or annotating values; Optional: "static typing"
- With the grain of JS, not against it
Functional programming is a good habit. It keeps your code easy to manage, and saves you from sneaky bugs.
My solution:
function countToFive() {
let firstFive = "12345";
let len = firstFive.length;
// Only change code below this line
for (let i = 0; i < len; i++) {
// Only change code above this line
console.log(firstFive[i]);
}
}
countToFive();
My solution:
function zeroArray(m, n) {
// Creates a 2-D array with m rows and n columns of zeroes
let newArray = [];
let row = [];
for (let i = 0; i < m; i++) {
// Adds the m-th row into newArray
for (let j = 0; j < n; j++) {
// Pushes n zeroes into the current row to create the columns
row.push(0);
}
// Pushes the current row, which now has n zeroes in it, to the array
newArray.push(row);
row =[]
}
return newArray;
}
let matrix = zeroArray(3, 2);
console.log(matrix);
My solution:
function myFunc() {
for (let i = 0; i <= 4; i += 2) {
console.log("Still going!");
}
}
My solution:
// Function that returns a string representing a cup of green tea
const prepareTea = () => 'greenTea';
/*
Given a function (representing the tea type) and number of cups needed, the
following function returns an array of strings (each representing a cup of
a specific type of tea).
*/
const getTea = (numOfCups) => {
const teaCups = [];
for(let cups = 1; cups <= numOfCups; cups += 1) {
const teaCup = prepareTea();
teaCups.push(teaCup);
}
return teaCups;
};
// Only change code below this line
const tea4TeamFCC = getTea(40);
// Only change code above this line
My solution:
// Function that returns a string representing a cup of green tea
const prepareGreenTea = () => 'greenTea';
// Function that returns a string representing a cup of black tea
const prepareBlackTea = () => 'blackTea';
/*
Given a function (representing the tea type) and number of cups needed, the
following function returns an array of strings (each representing a cup of
a specific type of tea).
*/
const getTea = (prepareTea, numOfCups) => {
const teaCups = [];
for(let cups = 1; cups <= numOfCups; cups += 1) {
const teaCup = prepareTea();
teaCups.push(teaCup);
}
return teaCups;
};
// Only change code below this line
const tea4GreenTeamFCC = getTea(prepareGreenTea, 27);
const tea4BlackTeamFCC = getTea(prepareBlackTea, 13);
// Only change code above this line
console.log(
tea4GreenTeamFCC,
tea4BlackTeamFCC
);
My 1st solution:
const capitals = function (word) {
return word.split('').map((l,i)=>{ return /^[A-Z]$/.test(l)? i : null}).filter(l=> l!=null)
};
My 2nd solution:
const capitals = word => { return word.match(/[A-Z]/g).map( x => { return word.indexOf(x) }) }
My solution:
function isValidIP(str) {
return str.split('.').filter(v => {return +v <= 255 && +v >= 0 && v.length == String(+v).length;}).length == 4;
}