bugfix: Node REPL to follow along: https://repljs.com
Objects
Objects are used to store keyed collections of Data. There are two ways to declare an object:
let user = new Object(); // object constructor syntax
let user = {}; // object literal syntax
We can assign properties like this:
/*Object Literal Syntax*/
let user = { // an object
name: "Vassil", // by key "name" store value "Vassil"
age:30 // by key "age" store value 30
};
and access them using one of two notations:
alert(user.name); // "Vassil"
alert(user.age); // 30
//We can also use bracket syntax
alert(user[name]); // "Vassil"
We can add or remove properties after the object declaration
user.isAdmin = true; // object now has 3 properties
delete user.age // object now has name and isAdmin properties
We can use object constructor syntax:
// Define a constructor function
function User(name, age){
this.name = name;
this.age = age;
}
let user1 = new User('James', 64);
let user2 = new User('Jane', 34);
object constructor syntax allows us to add some methods
function User(name, age){
this.name = name;
this.age = age;
}
// Add a method to the prototype
User.prototype.greet = function() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};
let user1 = new User('James', 64);
let user2 = new User('Jane', 34);
user1.greet() // Hello my name is James and I am 64 years old.
Object methods, “this”
let user = { // an object
name: "Vassil", // by key "name" store value "Vassil"
age:30 // by key "age" store value 30
sayHi(){
// "this" is the "current object"
alert(this.name)
}
};
user.sayHi(); // Vassil
let user = { // an object
name: "Vassil", // by key "name" store value "Vassil"
age:30 // by key "age" store value 30
sayHi(){
// "this" is the "current object"
alert(user.name)
}
};
//If we decide to copy `user` to another variable, e.g. `admin = user` and overwrite `user` with something else, then it will access the wrong object.
let admin = user;
user = null; // overwrite user to make it obvious
admin.sayHi(); // TypeError: Cannot read property 'name' of null
Classes
class User {
constructor(name, lastname) {
this.name = name; // Internal property
this.lastname = lastname
}
// Getter for name
get name() {
return this.name;
}
// Setter for name
set name(value) {
if (typeof value === 'string' && value.length > 0) {
this._name = value;
} else {
console.error('Invalid name');
}
}
//String method -> returns a print of this object so that you can see it
}
let user = new User('Alice');
console.log(user.name); // Output: Alice
user.name = 'Bob';
console.log(user.name); // Output: Bob
user.name = ''; // Invalid name
console.log(user.name); // Output: Bob
// In JavaScript, the use of an underscore (`_`) before a property name is a common convention to indicate that the property is intended to be private or for internal use only. This is a naming convention and not an enforced privacy mechanism by the language itself.
//
Linked List
// Define a class Node to represent a node in the linked list
// class Node {
// constructor(val) {
// this.val = val; // Assign val to the node
// this.next = null; // Initialize the next pointer to null
// }
// }
// Define a class LinkedList to represent the singly linked list
class LinkedList {
constructor() {
this.head = null; // Initialize the head of the list to null
}
// Function to insert a new node at the beginning of the list
insert(val) {
let newNode = new Node(val); // Create a new node with the given val
newNode.next = this.head; // Point the new node's next to the current head
this.head = newNode; // Update the head of the list to the new node
}
// Function to insert a new node after a given node (prev_node)
insertAfter(prev_node, val) {
if (prev_node === null) {
console.log("The given previous node must be in LinkedList.");
return;
}
let newNode = new Node(val); // Create a new node with the given val
newNode.next = prev_node.next; // Update the new node's next to prev_node's next
prev_node.next = newNode; // Update prev_node's next to the new node
}
// Function to delete the first occurrence of a key in the list
delete(key) {
let temp = this.head, prev = null;
// If the head node holds the key to be deleted
if (temp !== null && temp.val === key) {
this.head = temp.next; // Change the head of the list
return;
}
// Search for the key to be deleted
while (temp !== null && temp.val !== key) {
prev = temp; // Keep track of the previous node
temp = temp.next; // Move to the next node
}
// If key was not present in the list
if (temp === null) return;
// Unlink the node from the list
prev.next = temp.next;
}
// Function to search for a key in the list. Returns true if found, otherwise false
search(key) {
let current = this.head; // Initialize current to head
while (current !== null) {
if (current.val === key) // If the key is found, return true
return true;
current = current.next; // Move to the next node
}
return false; // Key not found, return false
}
}
// Create an instance of LinkedList
let list = new LinkedList();
// Insert nodes into the list
list.insert(1);
list.insert(2);
list.insert(3);
// Search for a key in the list and log the result
console.log("Search 2:", list.search(2)); // true
// Delete a node with a specific key from the list
list.delete(2);
// Search again for the key in the list and log the result
console.log("Search 2:", list.search(2)); // false