JavaScript Core Flashcards
What are the benefits of using array methods (forEach, map, etc.) over loops?
- they’re more meaningful and expressive
- the code is more declarative – it means that I define what I want to reach instead of describing the way how to do it
- using loops we need to care about the number of elements, starting point, and the iteration process
- A programming language is low level when its programs require attention to the irrelevant.” — Alan Perlis
How does .map() work?
- .map is applied to an array
- It accepts one parameter: a transformation function
- It returns a new array containing the same number of elements as the original array but with the transformation applied
- The original array is not modified
- We always receive a new array, so we need to assign the result to a variable
const strings = ['42', '23', '15', '2']; const numbers = strings.map(s =\> Number(s)); // [42, 23, 15, 2] (notice the lack of quote ')
How does .filter() work?
- The filter function is applied to an array
- It accepts one parameter: a condition function (also called a predicate or callback function)
- It returns a new array with only the elements for which the condition is true
- It always returns a new array, and the original array is not modified
- Filter can be used on arrays with elements of any type
const numbers = [4, 2, 1, 3, 5, 8]; const evens = numbers.filter(num =\> num % 2 === 0); // [4, 2, 8]
- The following example does not assign the result, so it is not used and is ignored.
numbers. filter(num => num % 2 === 0);
How does .reduce() work?
- reduce accepts two parameters: a reducer function and an initial value
- It is named ‘reduce’ because it reduces a collection of elements to a single value by applying the reducer function to each element
- The initial value is used in the first iteration, as the accumulated value
- Iterating the array, at each step, the reducer function is called
- The reducer function receives the accumulated value and the current element of the collection and combines them in some way
- Any sort of collection can be reduced
- If you don’t supply an initial value, the first element of the collection will be used
- Reduce can return any type of data - array, boolean, string, etc.
const numbers = [2,5,7]; const sum = numbers.reduce((sum, number) =\> sum + number, 0);
const animals = ['cat', 'dog']; const joined = animals.reduce((res, animal) =\> res + ', ' + animal)); // no initial value
const joined = animals.reduce((res, animal) => res + ‘, ‘ + animal, ‘’); // with initial value
How can implement filter by using reduce?
const filter = (array = [], filterFn) =\> { const result = array.reduce((acc, el, index, arr) =\> { if (filterFn(el, index, arr)) { acc.push(el); } return acc; }, []);
return result;
};
const filtered = filter([2, 6, 5, 8, 10], (el) =\> el \> 5); console.log(filtered); // [6, 8, 10]
How can implement mapby using reduce?
const map = (array = [], mapFn) =\> { const result = array.reduce((acc, el, index, arr) =\> { acc.push(mapFn(el, index, arr)); return acc; }, []);
return result;
};
console.log(map([1, 2, 3], (el) => el * 2)); // [2, 4, 6]
What is NPM?
Node Package Manager e мениджър на JS пакети, които са публикувани от различни програмисти в общността.
Пакетите може да са единични файлове, JS библиотеки, или по-сложни колекции от библиотеки, цели JS frameworks.
Те решават различни проблеми и могат да се ползват от различни програмисти.
What are the benefits of using it?
NPM пакетите се ползват, защото:
- се пести време - не е нужно да се написват отначало фунционалности, които вече са написани от друг програмист
- намаляваме вероятността от грешки, като преизползваме даден код
- осигуряваме си надеждност, като интегрираме пакет, който се използва от други разработчици, които гарантират, че кода е тестван за edge cases и ни позволява да се концентрираме върху нашата логика
Предимства на NPM:
- пакетите са open source и ние можем да разглеждаме кога и да се запознаем как работи
- повечето пакети са тествани и доказано са с работещ код
- повечето пакети се update - ват регулярно и всякакви грешки по кода се оправят и кода се подобрява
What is Node.js?
Node.js е сървърно приложение, създаващо среда за изпълнение на JS код, т.е. run time environment.
Node.js прави възможно изпълнението на JS код, директно на сървъра, когато обикновено JS се изпълнява в browser-а.
За да ползваме NPM трябва да имаме инсталиран Node.js.
Или:
Node.js is an open source server environment
Node.js is free
Node.js runs on various platforms (Windows, Linux, Unix, Mac OS X, etc.)
Node.js uses JavaScript on the server
What is the package.json file?
Когато сваляме пакет с npm, този пакет се сваля в папка node_modules в нашия проект.
NPM знае версиите на всички пакети, които използваме в проекта и ги запазва в специален файл - Package.json
package-lock.json - в него подробно се описват всички пакети, както и всички пакети на които зависят тези пакети, заедно с версиите на всички
How can create a package.json file?
To create a package.json file run the following comman in the bash terminal whithin the project’s folder:
npm init -y
This will create a package.json file with a template structure and default values:
- description: кратко описание на проекта, модула
- main: стартовия файл на проекта
- scripts: обект от скриптове/предефинирани команди (например за стартиране на файлове), които се ползват в проекта
- keywords: ключови думи, които описват пакета. Те са полезни когато търсим пакета в интернет или регистрите на npm
- dependancies: описват се всички пакети, необходими за проекта да работи
- dev-dependancies: описват се пакетите, които помагат (на програмистите при писане на самия пакет
What is a NPM project?
NPM е такъв, в който имаме package.json файл, в който се описват пакетите ползвани с проекта.
How to determine the version of an installed package?
Execute the following command in bash terminal:
- node -v
- npm -v
- package name -v
How can install a npm package?
Execute the following command in the bash terminal within the npm project’s folder:
- npm install [name_of_package] -D
- D means saving the dependency in the dev0dependancies array in the package.json file.
This will install the package in the current npm project.
Do I need to have node_modules when I use npm project?
No, you need to havejust a package.json file. Той съдържа цялата информация за всички пакети, които се ползват в пакета. Затова не е необходимо да качваме/изпращаме тази папка с проекта.
Като си копираме/сваляме проекта е необходимо само да изпълним:
npm install
Така всички dependencies from pachage.json ще бъдат инсталирани в node_modules папката.
How can install a npm packege globally?
Open the cmd/bash terminal anywhere in the system.
Execute the following command:
- npm install [package_name] -g
- g comes from global
Example:
npm install lodash -g
How can setup and run a custom script in npm?
In package.json > scripts type the custom command:
“scripts” {
“start”: “node main.js”
},
Има предефинирани скриптове/команди за start and end. Ако използваме тези предефинирани команди/думи - не е необходимо да използваме думата run при пускане на скрипта.
Ако обаче ползваме различни думи, трябва да ползваме run:
“scripts” {
“log”: “node log.js”
},
npm run log
What are ES Modules? Explain what ES Modules are and what problems they solve.
Когато NPM и Node.js са били създадени JavaScript не е имала собствена модулна система. Браузърите са работели по различен начин, а Node.js е работел с CommonJS модулна система.
ES6 предоставя като обща модулна система ES Modules. Браузърите започват да предоставят поддръжка за нея, също и Node.js от версия 14.
ЕS Modules става универсална модулна система за JavaScript ecosystem.
What is a npm module?
Модул - това е JS файл, който декларира и експортва една или повече стойности - функции или променливи, използвайки ‘export’.
What is important to know about the node modules?
- Те се инициализират веднъж и след това Node.js и браузъра ги кешират
- Ако експорта е референтен тип, то реално импортваме референцията към референтната стойност/обект
- Скоупа на декларираните в даден модул променливи и функции е самия модул. Модулите ни позволяват скриване на данни, т.е скриваме данни, които не сме експортнали
- Модулите могат да импортват други модули, които да използват в кода си
How can I use the ES Modules system?
You need to type in the package.json file the following (no matter where in the file on the first level):
“types”: “modules”,
How can I create an npm module?
Можем да експортваме стойности от файла ни една по една с думата “export”:
export const defaultMsg = ‘Default message’
export function log(msg) {
console.log(msg);
}
Това ще генерира обект с имената на всички експортнати променливи и функции.
export {
defaultMsg,
log,
}
How can I import an npm module?
- За да импортна само определени функционалности/пропертита он модула, мога да ползвам module/object destructuring:
import { defaultMsg, log } from ‘logger.js’
- Ако искам да импортна цялата функционалност от модула и да го именувам:
import * as logger from ‘./logger.js’
Сега всяка функционалност от Logger.js може да бъде достъпена през logger.
- Импортването на модул само по име - ще импортне само default export:
import log from ‘path_to_module.js’
През log можем да достъпим всичко от default export.
What is a default export?
Един модул може да има 0 или 1 default export и/ или много именувани exports.
export default function (msg) {
console.log(msg);
}
export function named () {
console.log(‘named’)
}
А може направим default export на обект от фунционалности:
export default {
defaultMsg,
log,
named
}
Импортването на модул само по име - ще импортне само default export:
import log from ‘path_to_module.js’
През log можем да достъпим всичко от default export.
What is a “tree shaking”?
Tree shaking - това означава да използваме само тези функционалности от модула, които ни трябват.
Да импортнем и кешираме само кода, необходим за нас. Това е и основното предимство на ES Modules пред CommonJS.
What are objects? Provide an example.
- Explain what objects are and how do they compare to primitive types.
In JavaScript, an object is an unordered collection of key-value pairs. Each key-value pair is called a property.
The key of a property can be a string. And the value of a property can be any value, e.g., a string, a number, an array, and even a function.
A property’s value can be a function, in which case the property is known as a method.
const person = { name: ['Bob', 'Smith'], age: 32, bio: function() { console.log(`${this.name[0]} ${this.name[1]} is ${this.age} years old.`); }, introduceSelf: function() { console.log(`Hi! I'm ${this.name[0]}.`); } };
Summary
- An object is a collection of key-value pairs.
- Use the dot notation ( .) or array-like notation ([]) to access a property of an object.
- The delete operator removes a property from an object.
- The in operator check if a property exists in an object.
What do we use objects for?
- Demonstrate how we can use objects.
- Explain how objects help build more complex applications.
Objects in JavaScript, just as in many other programming languages, can be compared to objects in real life. The concept of objects in JavaScript can be understood with real life, tangible objects.
In JavaScript, an object is a standalone entity, with properties and type. Compare it with a cup, for example. A cup is an object, with properties. A cup has a color, a design, weight, a material it is made of, etc. The same way, JavaScript objects can have properties, which define their characteristics.
Objects in JavaScript are ubiquitous and versatile. An object can be used as a bag of parameters with several handler functions attached. An object can group associated values but also structure a program. For example, you can put several similar functions on one object and let them operate on the same data.
What are the differences between primitive and reference types? Give code examples.
- Explain the difference between primitive and reference types.
- Demonstrate the difference between primitive and reference types.
- Javascript has two types of values: primitive values and reference values.
- You can add, change, or delete properties to a reference value, whereas you cannot do it with a primitive value.
- Copying a primitive value from one variable to another creates a separate value copy. It means that changing the value in one variable does not affect the other.
- Copying a reference from one variable to another creates a reference so that two variables refer to the same object. This means that changing the object via one variable reflects in another variable.
Primitive values: var a = 3.14; // Declare and initialize a variable var b = a; // Copy the variable's value to a new variable a = 4; // Modify the value of the original variable alert(b) // Displays 3.14; the copy has not changed
Reference values: var a = [1,2,3]; // Initialize a variable to refer to an array var b = a; // Copy that reference into a new variable a[0] = 99; // Modify the array using the original reference alert(b); // Display the changed array [99,2,3] using the new reference
What is destructuring, object destructuring?
Object destructuring assigns the properties of an object to variables with the same names by default.
let person = { firstName: 'John', let { firstName: fname, lastName: lname } = person; lastName: 'Doe' };
let { property1: variable1, property2: variable2 } = object;
The identifier before the colon (:) is the property of the object and the identifier after the colon is the variable.
If the variables have the same names as the properties of the object, you can make the code more concise as follows:
let { firstName, lastName } = person;
When you assign a property that does not exist to a variable using the object destructuring, the variable is set to undefined.
In this example we assign the currentAge property to the age variable with the default value of 18:
let { firstName, lastName, middleName = ‘’, currentAge: age = 18 } = person;
A function may return an object or null in some situations. The code will throw a TypeError. To avoid this, you can use the OR operator (||) to fallback the null object to an empty object:
let { firstName, lastName } = getPerson() || {};
Nested object destructuring: Assuming that you have an employee object which has a name object as the property: let employee = { id: 1001, name: { firstName: 'John', lastName: 'Doe' } };
The following statement destructures the properties of the nested name object into individual variables:
let {
name: {
firstName,
lastName
}
} = employee;
Array destructuring
ES6 provides a new feature called destructing assignment that allows you to destructure elements of an array into individual variables.
Assuming that you have a function that returns an array of numbers as follows:
function getScores() { return [70, 80, 90]; }
Destructing assignment: let [x, y, z] = getScores(); // x = 70, y = 80, z = 90
It’s possible to take all remaining elements of an array and put them in a new array by using the rest syntax (…):
let [x, y ,…args] = getScores(); // [70, 80, 90, 100]; -> x = 70, y = 80, args = [90, 100]
You can skip elements and sent a default values: let [, , thirdItem = 0] = getItems(); // thirdItem = 0
If the getItems() function doesn’t return an array and you expect an array the destructing assignment will result in an error (TypeError):
To avoid the error use this: let [a = 10, b = 20] = getItems() || [];
Nested array destructuring:
function getProfile() {
return [
‘John’,
‘Doe’,
[‘Red’, ‘Green’, ‘Blue’]
];
}
Nested array destructuring: let [firstName, lastName, [ color1, color2, color3] ] = getProfile();
Swapping variables: let a = 10, b = 20; -> [a, b] = [b, a]; // a = 20, b = 10
Spread Operator
- The spread operator is denoted by three dots (…).
- The spread operator unpacks elements of iterable objects such as arrays, sets, and maps into a list.
- The rest paramter is also denoted by three dots (…). However, it packs the remaining arguments of a function into an array.
- The spread operator can be used to clone an iterable object or merge iterable objects into one.
const odd = [1,3,5]; const combined = [2,4,6, ...odd]; // [2, 4, 6, 1, 3, 5] The spread operator (...) unpacks the elements of the odd array.
Here are the main differences bertween rest and spread operators:
- The spread operator (…) unpacks the elements of an iterable object.
- The rest parameter (…) packs the elements into an array.
- The rest parameters must be the last arguments of a function. However, the spread operator can be anywhere:
const odd = [1,3,5]; const combined = [2,...odd, 4,6]; // [2, 1, 3, 5, 4, 6]
JavaScript spread operator and array manipulation
1) Constructing array literal - the spread operator allows you to insert another array into the initialized array when you construct an array using the literal form:
let initialChars = ['A', 'B']; let chars = [...initialChars, 'C', 'D']; // ["A", "B", "C", "D"]
2) Concatenating arrays: you can use the spread operator to concatenate two or more arrays:
let numbers = [1, 2];
let moreNumbers = [3, 4];
let allNumbers = […numbers, …moreNumbers]; // [1, 2, 3, 4]
3) Copying an array: you can copy an array instance by using the spread operator
let scores = [80, 70, 90];
let copiedScores = […scores];
console.log(copiedScores); // [80, 70, 90]
JavaScript spread operator and strings:
let chars = ['A', ...'BC', 'D']; console.log(chars); // ["A", "B", "C", "D"]
Rest Parameters
(…). A rest parameter allows you to represent an indefinite number of arguments as an array.
function fn (a, b, ...args) { //... }
All the arguments you pass to the function will map to the parameter list. In the syntax above, the first argument maps to a, the second one maps to b, and the third, the fourth, etc., will be stored in the rest parameter args as an array.
fn(1, 2, 3, “A”, “B”, “C”); // [3, ‘A’, ‘B’, ‘C’]
The rest parameters must appear at the end of the argument list. The following code will result in an error:
function fn(a, ...rest, b) { // error // SyntaxError: Rest parameter must be last formal parameter }
Assuming that the caller of the sum() function may pass arguments with various kinds of data types such as number, string, and boolean, and you want to calculate the total of numbers only:
function sum(...args) { return args .filter(function (e) { return typeof e === 'number'; let result = sum(10, 'Hi', null, undefined, 20); // 30 }) .reduce(function (prev, curr) { return prev + curr; }); }
Filter the arguments based on a specific type such as numbers, strings, boolean, and null:
function filterBy(type, ...args) { return args.filter(function (e) { return typeof e === type; }); }
Rest parameters and arrow function:
const combine = (...args) =\> { return args.reduce( (prev, curr) =\> prev + ' ' + curr); };
let message = combine(‘JavaScript’, ‘Rest’, ‘Parameters’); // JavaScript Rest Parameters
How can I access the object’s properties?
To access a property of an object, you use one of two notations:
- the dot notation
- array-like notation
dot notation:
objectName.propertyName
array-like notation:
objectName[‘propertyName’]
We use dot notation when we know the name of the property.
We use array-like notation when we DO NOT know the name of the property and we need to ‘construct’ it.
How can I check if an object has a property?
- hasOwnProperty() method
const hero = { name: 'Batman' }; hero.hasOwnProperty('name'); // =\> true hero.hasOwnProperty('realName'); // =\> false
- “in” operator
const hero = { name: 'Batman' }; 'name' in hero; // =\> true 'realName' in hero; // =\> false
- Comparing with undefined
const hero = { name: 'Batman' }; hero.name; // =\> 'Batman' hero.realName; // =\> undefined
But be aware of false negatives. If the property exists but has an undefined value:
const hero = { name: undefined }; hero.name !== undefined; // =\> false
What is primitive value in JS?
Primitive values are: null, undefined, boolean, number, string, symbol, and BigInt
Static data is the data whose size is fixed at compile time. Static data includes: primitive and reference values.
JavaScript engine stores primitive values and variables on the stack.
let age = 25; let newAge = age;
newAge = newAge + 1; console.log(age, newAge); // newAge = 26 // age =25
What is a reference type value in JS?
When you declare variables, the JavaScript engine allocates the memory for them on two memory locations: stack and heap.
Reference values that refer to objects.
Unlike the stack, JavaScript stores objects (and functions) on the heap. The JavaScript engine doesn’t allocate a fixed amount of memory for these objects. Instead, it’ll allocate more space as needed.
let person = { name: 'John', age: 25, };
let member = person;
member.age = 26;
console. log(person);
console. log(member);
What is the main difference between reference copy and shallow copy?
var obj1 = new object() var obj2 = obj1
Reference copy refers to the fact that both objects refer to the same object without creating a new object. When one object changes, the other object will also change.
Shallow copy will create a new object, this object has an exact copy of the original object property values
- If the attribute is a basic type, the value of the basic type is copied
- If the attribute is a reference type, the memory address is copied (that is, the referenced
object is copied but not the referenced object), so if one of the objects changes this
address, it will affect the other object