Primitives in JS: null, undefined, Number, BigInt [1n], String, Boolean, Symbol [Symbol('description'), Symbol.for('namespace')]
null: absence of an object
undefined: absence of a defined value.
string: can use single or double quotes, or backticks (it is a template string)
Symbols: built-in object whose constructor returns a symbol which is unique. It can be used as unique identifier keys in objects[1]
Prototype: it is the built-in property that every object has. It is a mechanism by which JavaScript objects inherit features from one another. [2][3][4]
Function: is an object
Function assigned to an object: 'this' refers the function called. 'this' context changes to the object that call internal funcion.
The call method that exist to every function can be used to set the 'this' context
Lambda functions (arrow function) do not have their own this context. 'this' inside the lambda function is the context of the nearest parent non-lambda function
Lambda function does not have prototype: typeof normalFunc.prototype is 'object' and typeof lambdaFunc.prototype is 'undefined'
Prototypal Inheritance: it is a chain of prototype. It can be created by different approache like: functional, contructor functions and class-syntax contructor. When use MyObject.prototype.myFunciont, it will be one object myFunction to all objectos from MyObject. Bad practices create a method inside the function constructor.
Class-Syntax Constructor: Class is a syntactic sugar to creates a function. it creates prototype chains. All method created in the class is added to the prototype object.
Buffer and Streams (11%)
Buffer
Definition:Buffer objects are used to represent a fixed-length sequence of bytes. [1]
Allocation
The 'new' to create a buffer is deprecated. It used to have the Buffer.unsafeAlloc which means unallocated memory. The buffer can contain fragments of previously deleted data. It is used to performance porpose.
ArrayBuffer -> Float64Array -> 8 bytes -> 64-bit floating point number
Int32Array -> 4 bytes -> 32 bits -> signed integer
Uint8Array -> each byte is unsigned integer (0-255)
Buffer is subclass of Uint8Array: an object is Buffer and Uint8Array
Buffer.prototype.slice (buffer instance with reference to original data) overrides Uint8Array.prototype.slice (do a copy)
Strings
Created from string:
Converting Buffers to String:
Buffer instance can be represented by a JSON:
Streams
Definition: A stream is an abstract interface for working with streaming data in Node.js. Streams can be readable, writable, or both. All streams are instances of EventEmitter.[4][5]
Types of Streams: Readable, Writable, Duplex, Transform
Examples APIs that expose streams: process, net, http and fs, child_process expose.
The Stream constructor is the default export of the stream module and inherits from the EventEmitter constructor from the events module.
The Stream constructor implements the pipe method
Events emmited: data (Readable), end (Readable), finish (Writable), close (when destroyed), error
Stream Mode (option when stream is instantiated): (1) Binary Streams: default, only read or write Buffer instances; (2) Object stream, which can read/write JS objects and primitives (but not null)
Readble Stream:
EventEmitter > Stream > Readable
As data becomes available, a readable stream emits a data event.
Readable streams emit buffers by default
Set objectMode to true to not use buffer
Writeble Streams:
EventEmitter > Stream > Writable
Emit the finish event when the stream is ended
Take the string inputs, convert them to Buffer instance and then write them
The default objectMode is false and the strings written to writable instance is converted to buffer
The objectMode have to be set to true to support string
Readable > Duplex. Deuplex mix functionalities from Writable
Duplex > Transform -> Casual relatioship between read and write: a data is written in the transform instace, then a data event is emitted on readable side, then the data in buffer is converted to string
Transform > PassThrough. Transform stream where use Transform is not possible.
End of Streams: it can be identified by some events as close, error, finish or end. Then the resource can be deallocated.
Piping Streams:
Example a common Bash command: cat some-file | grep find-something
The pipe [8] return a stream then can be done a chain of pipe calls.
Pipeline[9] is the correct way to chain pipes to avoid memory leaks in case of fails.
readable streams -> writes to the writable streams
Control flow (12%)
Sync: the thread is blocked until the process is finished. Async: A second process can run while the first process wait for a return. It uses the callback functions. [1][2][3]
Event Loop [4][5]: node is single thread. It is responsible for executing the code, collecting and processing events, and executing queued sub-tasks.
Child Process (8%)
Methods in child_process modules that result in a process: exec & execSync; spawn & spawnSync; execFile & execFileSync (variations of exec and execSync); fork (specialization of the spawn)[1][2][3][4]. For all of them is possible to use env and cwd as arguments.
execSync: execute a command and return a buffer with the chould process output.
exec: it is an async funcion split STDOUT and STDERR and pass then to the callback
spawn & spawnSync: it uses executable path and an array of flags, and return info about the process that was spawned. The spawn not accept callback; spawn doesn't buffer child process output
***PS: The asynchronous methos retun a ChildProcess instance with stdin, sdtout and stderr streams of subprocess. However, this behaviour can be changed.[5][6][7][8]
Error is a runtime errors or an object created programatically [1][2][3][4]
Inherit from Error: EvalError, SyntaxError, RangeError, ReferenceError, TypeError, URIError
Node.JS CLI (4%)
The CLI [1][2] is the command line that make possible, e.g., to debug and execute scripts.
Events (11%)
Event [1][2] is an action on a computer. It can be fire, create or listen by the Event Module. To assign an event you can use the EventEmitter object.
Listeners are called in the order that they are registered and they will be invoked every time the named event is emitted. To run once you can use myEmitter.once(...) method.
We can use an AbortController to cancel the promisifed listener. It's useful when a event can not be emitted or spend too long.
Path module: path manipulation and normalization across platforms [1]
file located: variables that are always present in every module: _ _ filename (absolute path to the current file) and _ _ dirname (absolute path to the current directory).
Watching: fs.watch method is in Node core to tap into file system events.[2]
Reading Directories: it is a type of file. The fs module also provides multiple ways to read a directory: Synchronous, Callback-based, Promise-based. Ex: readdirSync, readdir[3] which list the files inside the folder.
fs module: provides APIs to deal with the business of reading, writing, file system meta-data and file system watching [4]
1 Synchronous: block anything else until the process is finished.
readFileSync(_ _ filename) -> read content into a buffer
For a better performance with Node to manage I/O in background while the process is in execution, the alternatives are the callback and promise based filesystem APIs.
2 Callback based the execution is free to continue while the operation is performed. The callback function is called when the operation is completed.
3 Promise based: it s the same async process but using async/await that let the code better to read. The methods return promises.
4 Stream based: It is good for large files. The fs module has createReadStream(createReadStream(__filename))[5] and createWriteStream('out.txt')[6] methods to read and write files in chunks. The memory usage is constant as the file is read and write in small chunks. [7][8]
Process/Operating System (6%)
The process object provides information about, and control over, the current Node.js process.[1][2]. Node.js is a single-threaded, non-blocking performance and works for a single process.
process.stdin - Readable stream for process input
process.stdout - Writable stream for process output
process.stderr - Writable stream for process error output
process.exit - process finish ok. Any non-zero code indicates failure
process info - ID (process.pid) , Platform (process.platform), Directory (process.cwd()), Environment variables (process.env.HOME)
process stats - resource usage (process.uptime(), process.cpuUsage(), process.memoryUsage())
System Info: os module used to get ingo about Operating System
The modules are block of code that can be exposed to be reused.[1][2]
module.exports will be the value that is returned when the module is required.
Modules expose functionalities
File can be a module
ESM: language-native EcmaScript Modules
CJS: CommonJS
An important difference between CJS and ESM is that CJS loads every module synchronously and ESM loads every module asynchronously.
Faux-ESM is transpiled with Babel. In Node it is compiles to CommonJS. In browser use synchronous loader.
Whereas CJS modifies a module.exports object, ESM introduces native syntax.
npm ecosystem is built upon CommonJS format.
Package.json (6%)
npm is a CLI tool installed with Node.JS and used as a package manager. Another well known is yarn.
A package[1][2] is a folder with a package.json file in it. It is used to inicialized a Node.JS project.
The package-lock.json file is used to install the exact same dependencies. It has the exact versions.
npm test and start is alias to npm run test and npm run start.
SemVer: the format is three numbers separated by dots (Major.Minor.Patch). The Major is the changes break, the Minor is add new something and the patch is bugfix. Ex: ^8.14.1 is the same 8.x.x and it means that will match MINOR and PATCH positions.
scripts is a field inside the package.json file with alias to execute commands.
Unit Testing (6%)
The core assert module exports a function that will throw an AssertionError when the sentence is not valid. The categories are Thruthness, equality and Pattern Match, deep equality, Errors and Unreacheability. [1][2][3][4]