I "code" about bots & algos. Write about: Web3 Dev, DeFI, on/off-chain footprints, AI, NFTs & any novel edge I find...
I "code" about bots & algos. Write about: Web3 Dev, DeFI, on/off-chain footprints, AI, NFTs & any novel edge I find...

Subscribe to QuantArcane

Subscribe to QuantArcane
Share Dialog
Share Dialog
<100 subscribers
<100 subscribers


Hello coders. I’m a long time .NET developer who recently started playing with Solidity at Alchemy’s Web3 Dev Bootcamp. About halfway into the bootcamp I had an epiphany about what my final project should be.
Since React is the de facto front-end library/framework in the blockchain industry I decided to use it for my app. Also throughout my (mostly backed) career I did work on a couple of Angular-Typescript projects but never got a chance to work with React.
So, in order to not feel like a fraud for jumping straight into React without properly going through JavaScript first, I took yet another step back and did a quick 30-hour tutorial: The Modern JavaScript Bootcamp by Andrew Mean. By the way, I want to give a big shout-out to Andrew for the great content!
Since I did something similar about 7 years ago before working with TypeScript and Angular, this time I decided I will create a small set of cheat sheet articles that can be reviewed in 20-30 minutes at most.
This way I will have a reference point to come back to in the future and hopefully save some time for other object-oriented programmers out there.
I plan to split this in three articles: The first one is going to be about general JS syntactic concepts, The second one about OOP in JS, and the third about Asynchronous JS.
In the future I might expand the set with more in-depth articles on subjects like Webpack or delve into Web Assembly, but at this point I feel I’m getting too derailed from my goal of obtaining the Alchemy NFT Certification.
Enough context let’s get started.
const { keccak256 } = require("ethereum-cryptography/keccak");
const { utf8ToBytes } = require("ethereum-cryptography/utils");
const message = "JS uses lexical scoping";
const hashMessage = function(msg){
if(msg.length < 30)
{
const message = " shadowing: defining a variable with the same name but in a different scope";
msg += message;
}
const bytes = utf8ToBytes(msg);
const hash = keccak256(bytes);
return hash;
}
console.log(hashMessage(message));
// Global Scope (message, hashMessage)
// Local Scope (msg, bytes, hash)
// Local Scope (message)
The nested scope from the if block (where the second “message” variable is defined) has access to all the above scopes. So it can access the local scope variables: msg, bytes, hash, as well as the global scope vars “message “ and “hashMessage”.
If JS can't find the variable in its scope it will keep going up until global. If it reaches global and the variable is NOT defined, it will auto define it! Because why not... :|
To fix this mayhem causing "feature" Js has something called "strict mode". (Add "use strict" on top of your script files) More on this here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
It's ok to define a second variable with the same name, e.g. the "message" variable inside the if block, if it’s not in the same scope as the first “message” variable (from global scope), and it will shadow if.
Undefined comes from uninitialized, declared variables.
Or from assigning a void function result to a variable
Or by not passing a parameter into a function
I can check against it:
if (x === undefined)
And I can manually assign undefined to clear a value, but for that "null" should be used!
"let" is block scoped
"const" is like in C# (on a ref type you can't change the address but you can change the object's content)
"var" has several issues:
is function scoped (a var declared in an "if" block is accessible outside the "if" block provided is in the same function.
you can redeclare the same variable multiple times :|
var declaration (not assignment) gets hoisted above. So if using a var variable before declaration you get undefined instead of the natural reference error. Plus all sorts of weird stuff can happen due to the vars hoisting.
I’ll be addressing value types vs reference types in my next guide about OOP in JS.
const str = ´Lorem Ipsum ${varLoremHere} Ipsum´;
Great, now I have to make room for the backtick key on my Dygma keyboard and mess my perfect setup. Arghhh!
So apparently if you do:
if("some string") // true
Js is going to default the string to the "true" boolean value. Resembling ChatGPT, if you don't know just make something up!
Js will resolve: (false, 0, empty string, null, undefined, NaN) to falsy. Everything else will be resolved to truthy (arrays, objects, a monkey with a chainsaw)!
console.log('5' + 5); // 55
console.log('5' - 5); // 0
console.log('5' === 5); // false (the third equal is for comparing the types)
console.log('5' == 5); // true (can't think of a scenario where == should be used...)
console.log(true + 12); // 13
const type = typeof 123 // check the type using typeof
console.log(type) // number
More on type coercion here: https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/types-grammar/ch4.md (Funny I stumbled upon Kyle Simpson here, I followed a pluralsight course by him like 7-8 years ago.)
const age = 35;
let message = age >= 18 ? "Can Vote!" : "Can't Vote!"; // same as C#! GG Js!
See below the syntax for creating functions in JS (regular functions, arrow functions and methods inside classes)
const function_name = function(){}
const square_MultiLineLambda = (num) => { return num * num; }
const square_SingleLineLambda = (num) => num * num
It’s worth mentioning that lambda expressions don't have access to the context when declared inside a class, they can't access "this"!
Inside classes, define functions like in C# (minus return type, minus access modifier)
function_name(){}
In JavaScript we can simulate the same effect as encapsulating a private variable with getters and setters in C#, by using closures:
const createBankAccount = () => {
let balance = 100000;
getBalance = () => balance;
depozit = (amount) => balance += amount;
withdraw = (amount) => {
if(amount <= 5000){
balance -= amount;
}
}
return {getBalance, depozit, withdraw};
}
const bankAccount = createBankAccount();
bankAccount.depozit(6000)
console.log(bankAccount.getBalance()); // prints 106000
bankAccount.withdraw(7000)
console.log(bankAccount.getBalance()); // prints 106000 (withdraw > 5000)
bankAccount.withdraw(4000)
console.log(bankAccount.getBalance()); // prints 102000
Here we define a regular function “createBankAccount“, that has our “private“ variable “balance“. The variable is private in the sense that due to the lexical scoping it cannot be used from outside the function.
Now we don’t want anyone to be able to change this variable to their liking. For this, inside our “createBankAccount“ function we define three nested functions: one for getting the balance, one for crediting the balance, and one for debiting the balance. We can even protect our balance by adding a debit limit of 5000.
All three methods have access to the balance variable due to scoping.
Then we return an object containing a reference to each of the three nested functions. (delegates in C#)
On the line below we run the “createBankAccount“ function from top to bottom.
const bankAccount = createBankAccount();
We now have in the “bankAccount“ variable an object with three references to those nested functions that have access to “let balance”.
This is how we protect the balance and allow access only through the three nested methods defined inside the closure.
const emptyArray = [] // Empty array
const expenses = [100.10, 45, -20] // Array of numbers
const data = [true, 11, 'Paul'] // Array of mixed types
console.log(expenses[0]) // get first
console.log(expenses[expenses.length - 1]) // get last
expenses.push(12) // add items
expenses.unshift(3) // add items before
console.log(expenses) // Will print [ 3, 100.1, 45, -20, 12 ]
// Splice adds, removes, edits items anywhere
const nums = [99, 199, 299]
nums.splice(1, 0, 399) // Add item - p1: position, p2: items to delete, p3: item to add
console.log(nums) // Will print [99, 399, 199, 299]
nums.pop() // remove from end
nums.shift() // remove from beginning
console.log(nums) // Will print [399, 199]
nums.splice(0, 1) // p1: index, p2: how many elements to delete
console.log(nums) // Will print [399]
const nums2 = [10, 20, 30, 40]
nums2[2] = 3000;
nums2.splice(1, 1, 2000); // p1: at index 1, p2: delete 1 item, p3: add item 2000
console.log(nums2); // [10, 2000, 3000, 40]
For loop is the same as C#/Java
forEach is similar with linq’s foreach
const todos = ['Order cat food', 'Clean kitchen', 'Buy food', 'Do work', 'Exercise']
todos.forEach(function (todo, index) { // forEach is similar to linq's, takes a delegate as a param
const num = index + 1
console.log(`${num}. ${todo}`)
})
const index = todos.indexOf('Clean kitchen'); // indexOf gets the index searching by the content
console.log(index) // Will print 1
// but indexOf uses ""==="" to search for the index, which doesn't work on ref types": {} === {} does not return true (diff addresses)
// for getting the index in an array of objects we use findIndex to search into the objects properties
const notes = [{title: 'title 1', body: 'body 1'}, {
title: 'title 2',
body: 'body 2'
}];
const objIndex = notes.findIndex(function (note, index) {
return note.title === 'title 2'
})
console.log(index) // Will print 1
// for getting the whole object, just use find instead of findIndex:
const obj = notes.find(function (note, index) {
return note.title === 'title 2'
})
console.log(obj) // Will print { title: 'title 2', body: 'body 2' }
const todoItems = [{text: 't1', completed: false}, {text: 't2', completed: true}, {text: 't3', completed: false}]
/*
* Filter returns a NEW array with the filtered elements
* Takes as param a callback function
* - which gets called for each element with the collection and the index
* - returns true for including an element
* - returns false for excluding an element
*/
const thingsToDo = todoItems.filter(function (todo) {
return !todo.completed
});
console.log(thingsToDo) // Wil print t1 & t3 objects
/**
* Sort takes a delegate with two items of the array "a" & "b"
* Implement the delegate's callback function so that it:
* - returns -1 if "a" should come first
* - returns 1 if "b" should come first
* - returns 0 is "a" & "b" are equal
* * does NOT return a NEW collection!
*/
todoItems.sort(function (a, b) {
if (!a.completed && b.completed) {
return -1
} else if (!b.completed && a.completed) {
return 1
} else {
return 0
}
})
console.log(todoItems) // Wil print t1, t3, t2 objects (sorted by completed prop)
Find all methods in mdn docs here.
The rest parameter is very similar to C#’s params argument. You can use it as a parameter in a method signature when you have a variable number of parameters you want to pass in. The operator will receive those parameters as an array.
Suppose we have a function that sums two numbers:
const sum = (a, b) => {
return a + b;
}
console.log(sum(1,2));
}
Now suppose we want to change the function to accept being called with a variable amount of numbers to be summed? The code would look like this:
const sum2 = (...params) => {
let sum = 0;
params.forEach(i => sum += i);
return sum;
}
console.log(sum2(1, 2, 3));
console.log(sum2(1, 2, 3, 4, 5));
In JS the rest parameter has three dots before “…rest“. Also same as C# if we have multiple parameters in the function, the rest param naturally comes last.
Now we can also use the rest parameter for something else that I find both awesome and useful, and that is to deep copy an array:
const arrayOne = ["One", "Two", "Three"];
const arrayTwo = [...arrayOne];
arrayTwo.push("Four");
console.log(arrayOne); // prints [ 'One', 'Two', 'Three' ]
console.log(arrayTwo); // prints [ 'One', 'Two', 'Three', 'Four' ]
The const arrayTwo = [...arrayOne]; takes each element from arrayOne and copies it into arrayTwo. The result is a deep copy of arrayOne.
Let’s say I have the same add method that receives numbers as a rest param, and let’s say this method is part of a third party library and I cannot change it’s signature. Also imagine I have an array of numbers that I want to pass in as parameters so they can be received by the rest parameter:
const numbers = [10, 20, 30, 40, 50, 60];
// Sum should be called like this:
// sum2(10, 20, 30, 40, 50, 60);
// but my numbers are in an array!
console.log(sum2(...numbers)); // spreads out all array items as parameters
The spread operator has the same syntax as the rest parameter but it’s used in a function call (to spread out the array items as parameters) as opposed being used in a function signature (to bundle function parameters into an array).
// same syntax as C#. I imagine throwing stuff often since js refuses to fail
const addLikeAPro = (a, b) => {
if (typeof a !== "number" || typeof b !== "number") {
throw new Error("One of the params is not a number");
}
return a + b;
}
try {
const sum = addLikeAPro(10, "cow");
console.log(sum);
}
catch (e) {
console.log(e);
}
Since the last time I checked out JavaScript, it seems that the language has fixed many of its faults with the introduction of const/let and strict mode.
In part II of this three-part series I’ll explore JavaScript’s Object-Oriented Programming and its prototypical inheritance.
https://mirror.xyz/quantarcane.eth/sw3wZxsZH-JXExMDCxcJFvd2sN9iS1X2YxNFnAZRPpI
https://mirror.xyz/quantarcane.eth/fyMW6ZXkJ1AA3FN42TU522_YR5gh_QyyvMZev84Tshg
You can find the full set of examples over at my github page.
Also if you liked the article, I'm constantly tweeting about this stuff and more. Feel free to follow me on Twitter and drop a comment to say hi!
Hello coders. I’m a long time .NET developer who recently started playing with Solidity at Alchemy’s Web3 Dev Bootcamp. About halfway into the bootcamp I had an epiphany about what my final project should be.
Since React is the de facto front-end library/framework in the blockchain industry I decided to use it for my app. Also throughout my (mostly backed) career I did work on a couple of Angular-Typescript projects but never got a chance to work with React.
So, in order to not feel like a fraud for jumping straight into React without properly going through JavaScript first, I took yet another step back and did a quick 30-hour tutorial: The Modern JavaScript Bootcamp by Andrew Mean. By the way, I want to give a big shout-out to Andrew for the great content!
Since I did something similar about 7 years ago before working with TypeScript and Angular, this time I decided I will create a small set of cheat sheet articles that can be reviewed in 20-30 minutes at most.
This way I will have a reference point to come back to in the future and hopefully save some time for other object-oriented programmers out there.
I plan to split this in three articles: The first one is going to be about general JS syntactic concepts, The second one about OOP in JS, and the third about Asynchronous JS.
In the future I might expand the set with more in-depth articles on subjects like Webpack or delve into Web Assembly, but at this point I feel I’m getting too derailed from my goal of obtaining the Alchemy NFT Certification.
Enough context let’s get started.
const { keccak256 } = require("ethereum-cryptography/keccak");
const { utf8ToBytes } = require("ethereum-cryptography/utils");
const message = "JS uses lexical scoping";
const hashMessage = function(msg){
if(msg.length < 30)
{
const message = " shadowing: defining a variable with the same name but in a different scope";
msg += message;
}
const bytes = utf8ToBytes(msg);
const hash = keccak256(bytes);
return hash;
}
console.log(hashMessage(message));
// Global Scope (message, hashMessage)
// Local Scope (msg, bytes, hash)
// Local Scope (message)
The nested scope from the if block (where the second “message” variable is defined) has access to all the above scopes. So it can access the local scope variables: msg, bytes, hash, as well as the global scope vars “message “ and “hashMessage”.
If JS can't find the variable in its scope it will keep going up until global. If it reaches global and the variable is NOT defined, it will auto define it! Because why not... :|
To fix this mayhem causing "feature" Js has something called "strict mode". (Add "use strict" on top of your script files) More on this here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
It's ok to define a second variable with the same name, e.g. the "message" variable inside the if block, if it’s not in the same scope as the first “message” variable (from global scope), and it will shadow if.
Undefined comes from uninitialized, declared variables.
Or from assigning a void function result to a variable
Or by not passing a parameter into a function
I can check against it:
if (x === undefined)
And I can manually assign undefined to clear a value, but for that "null" should be used!
"let" is block scoped
"const" is like in C# (on a ref type you can't change the address but you can change the object's content)
"var" has several issues:
is function scoped (a var declared in an "if" block is accessible outside the "if" block provided is in the same function.
you can redeclare the same variable multiple times :|
var declaration (not assignment) gets hoisted above. So if using a var variable before declaration you get undefined instead of the natural reference error. Plus all sorts of weird stuff can happen due to the vars hoisting.
I’ll be addressing value types vs reference types in my next guide about OOP in JS.
const str = ´Lorem Ipsum ${varLoremHere} Ipsum´;
Great, now I have to make room for the backtick key on my Dygma keyboard and mess my perfect setup. Arghhh!
So apparently if you do:
if("some string") // true
Js is going to default the string to the "true" boolean value. Resembling ChatGPT, if you don't know just make something up!
Js will resolve: (false, 0, empty string, null, undefined, NaN) to falsy. Everything else will be resolved to truthy (arrays, objects, a monkey with a chainsaw)!
console.log('5' + 5); // 55
console.log('5' - 5); // 0
console.log('5' === 5); // false (the third equal is for comparing the types)
console.log('5' == 5); // true (can't think of a scenario where == should be used...)
console.log(true + 12); // 13
const type = typeof 123 // check the type using typeof
console.log(type) // number
More on type coercion here: https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/types-grammar/ch4.md (Funny I stumbled upon Kyle Simpson here, I followed a pluralsight course by him like 7-8 years ago.)
const age = 35;
let message = age >= 18 ? "Can Vote!" : "Can't Vote!"; // same as C#! GG Js!
See below the syntax for creating functions in JS (regular functions, arrow functions and methods inside classes)
const function_name = function(){}
const square_MultiLineLambda = (num) => { return num * num; }
const square_SingleLineLambda = (num) => num * num
It’s worth mentioning that lambda expressions don't have access to the context when declared inside a class, they can't access "this"!
Inside classes, define functions like in C# (minus return type, minus access modifier)
function_name(){}
In JavaScript we can simulate the same effect as encapsulating a private variable with getters and setters in C#, by using closures:
const createBankAccount = () => {
let balance = 100000;
getBalance = () => balance;
depozit = (amount) => balance += amount;
withdraw = (amount) => {
if(amount <= 5000){
balance -= amount;
}
}
return {getBalance, depozit, withdraw};
}
const bankAccount = createBankAccount();
bankAccount.depozit(6000)
console.log(bankAccount.getBalance()); // prints 106000
bankAccount.withdraw(7000)
console.log(bankAccount.getBalance()); // prints 106000 (withdraw > 5000)
bankAccount.withdraw(4000)
console.log(bankAccount.getBalance()); // prints 102000
Here we define a regular function “createBankAccount“, that has our “private“ variable “balance“. The variable is private in the sense that due to the lexical scoping it cannot be used from outside the function.
Now we don’t want anyone to be able to change this variable to their liking. For this, inside our “createBankAccount“ function we define three nested functions: one for getting the balance, one for crediting the balance, and one for debiting the balance. We can even protect our balance by adding a debit limit of 5000.
All three methods have access to the balance variable due to scoping.
Then we return an object containing a reference to each of the three nested functions. (delegates in C#)
On the line below we run the “createBankAccount“ function from top to bottom.
const bankAccount = createBankAccount();
We now have in the “bankAccount“ variable an object with three references to those nested functions that have access to “let balance”.
This is how we protect the balance and allow access only through the three nested methods defined inside the closure.
const emptyArray = [] // Empty array
const expenses = [100.10, 45, -20] // Array of numbers
const data = [true, 11, 'Paul'] // Array of mixed types
console.log(expenses[0]) // get first
console.log(expenses[expenses.length - 1]) // get last
expenses.push(12) // add items
expenses.unshift(3) // add items before
console.log(expenses) // Will print [ 3, 100.1, 45, -20, 12 ]
// Splice adds, removes, edits items anywhere
const nums = [99, 199, 299]
nums.splice(1, 0, 399) // Add item - p1: position, p2: items to delete, p3: item to add
console.log(nums) // Will print [99, 399, 199, 299]
nums.pop() // remove from end
nums.shift() // remove from beginning
console.log(nums) // Will print [399, 199]
nums.splice(0, 1) // p1: index, p2: how many elements to delete
console.log(nums) // Will print [399]
const nums2 = [10, 20, 30, 40]
nums2[2] = 3000;
nums2.splice(1, 1, 2000); // p1: at index 1, p2: delete 1 item, p3: add item 2000
console.log(nums2); // [10, 2000, 3000, 40]
For loop is the same as C#/Java
forEach is similar with linq’s foreach
const todos = ['Order cat food', 'Clean kitchen', 'Buy food', 'Do work', 'Exercise']
todos.forEach(function (todo, index) { // forEach is similar to linq's, takes a delegate as a param
const num = index + 1
console.log(`${num}. ${todo}`)
})
const index = todos.indexOf('Clean kitchen'); // indexOf gets the index searching by the content
console.log(index) // Will print 1
// but indexOf uses ""==="" to search for the index, which doesn't work on ref types": {} === {} does not return true (diff addresses)
// for getting the index in an array of objects we use findIndex to search into the objects properties
const notes = [{title: 'title 1', body: 'body 1'}, {
title: 'title 2',
body: 'body 2'
}];
const objIndex = notes.findIndex(function (note, index) {
return note.title === 'title 2'
})
console.log(index) // Will print 1
// for getting the whole object, just use find instead of findIndex:
const obj = notes.find(function (note, index) {
return note.title === 'title 2'
})
console.log(obj) // Will print { title: 'title 2', body: 'body 2' }
const todoItems = [{text: 't1', completed: false}, {text: 't2', completed: true}, {text: 't3', completed: false}]
/*
* Filter returns a NEW array with the filtered elements
* Takes as param a callback function
* - which gets called for each element with the collection and the index
* - returns true for including an element
* - returns false for excluding an element
*/
const thingsToDo = todoItems.filter(function (todo) {
return !todo.completed
});
console.log(thingsToDo) // Wil print t1 & t3 objects
/**
* Sort takes a delegate with two items of the array "a" & "b"
* Implement the delegate's callback function so that it:
* - returns -1 if "a" should come first
* - returns 1 if "b" should come first
* - returns 0 is "a" & "b" are equal
* * does NOT return a NEW collection!
*/
todoItems.sort(function (a, b) {
if (!a.completed && b.completed) {
return -1
} else if (!b.completed && a.completed) {
return 1
} else {
return 0
}
})
console.log(todoItems) // Wil print t1, t3, t2 objects (sorted by completed prop)
Find all methods in mdn docs here.
The rest parameter is very similar to C#’s params argument. You can use it as a parameter in a method signature when you have a variable number of parameters you want to pass in. The operator will receive those parameters as an array.
Suppose we have a function that sums two numbers:
const sum = (a, b) => {
return a + b;
}
console.log(sum(1,2));
}
Now suppose we want to change the function to accept being called with a variable amount of numbers to be summed? The code would look like this:
const sum2 = (...params) => {
let sum = 0;
params.forEach(i => sum += i);
return sum;
}
console.log(sum2(1, 2, 3));
console.log(sum2(1, 2, 3, 4, 5));
In JS the rest parameter has three dots before “…rest“. Also same as C# if we have multiple parameters in the function, the rest param naturally comes last.
Now we can also use the rest parameter for something else that I find both awesome and useful, and that is to deep copy an array:
const arrayOne = ["One", "Two", "Three"];
const arrayTwo = [...arrayOne];
arrayTwo.push("Four");
console.log(arrayOne); // prints [ 'One', 'Two', 'Three' ]
console.log(arrayTwo); // prints [ 'One', 'Two', 'Three', 'Four' ]
The const arrayTwo = [...arrayOne]; takes each element from arrayOne and copies it into arrayTwo. The result is a deep copy of arrayOne.
Let’s say I have the same add method that receives numbers as a rest param, and let’s say this method is part of a third party library and I cannot change it’s signature. Also imagine I have an array of numbers that I want to pass in as parameters so they can be received by the rest parameter:
const numbers = [10, 20, 30, 40, 50, 60];
// Sum should be called like this:
// sum2(10, 20, 30, 40, 50, 60);
// but my numbers are in an array!
console.log(sum2(...numbers)); // spreads out all array items as parameters
The spread operator has the same syntax as the rest parameter but it’s used in a function call (to spread out the array items as parameters) as opposed being used in a function signature (to bundle function parameters into an array).
// same syntax as C#. I imagine throwing stuff often since js refuses to fail
const addLikeAPro = (a, b) => {
if (typeof a !== "number" || typeof b !== "number") {
throw new Error("One of the params is not a number");
}
return a + b;
}
try {
const sum = addLikeAPro(10, "cow");
console.log(sum);
}
catch (e) {
console.log(e);
}
Since the last time I checked out JavaScript, it seems that the language has fixed many of its faults with the introduction of const/let and strict mode.
In part II of this three-part series I’ll explore JavaScript’s Object-Oriented Programming and its prototypical inheritance.
https://mirror.xyz/quantarcane.eth/sw3wZxsZH-JXExMDCxcJFvd2sN9iS1X2YxNFnAZRPpI
https://mirror.xyz/quantarcane.eth/fyMW6ZXkJ1AA3FN42TU522_YR5gh_QyyvMZev84Tshg
You can find the full set of examples over at my github page.
Also if you liked the article, I'm constantly tweeting about this stuff and more. Feel free to follow me on Twitter and drop a comment to say hi!
No activity yet