Objects have properties and methods associated with them.
An example of an array of objects.
const technologyStacks = [
{
role: 'iOS Developer',
userInterface: ['UIKit', 'SwiftUI'],
codingPlatform: ['Xcode', 'AppCode'],
languages: ['Swift', 'Objective-C'],
backend: ['Firebase', 'Realm']
},
{
role: 'Full-Stack Web Developer',
userInterface: ['React, CSS, HTML'],
codingPlatform: ['Visual Studio Code', 'WebStorm'],
languages: ['JavaScript', 'TypeScript'],
backend: ['Express', 'Node', 'PostgresSQL']
}
]
const fellow = {
// properties
name: 'Brian',
stack: 'iOS',
isMentor: true,
// methods
info: function() {
console.log(`Hi my name is ${this.name}.`)
}
};
console.log(fellow.stack); // iOS
fellow.info(); // Hi my name is Brian.
const book = new Object();
book.title = '1984';
book.author = 'George Orwell';
book.isAvailable = false;
book.checkIn = function() {
this.isAvailable = true;
};
book.checkOut = function() {
this.isAvailable = false;
};
console.log(typeof book); // object
book.checkIn();
book.isAvailable // true
console.log(book.title);
const value = book['title'];
console.log(value);
book.checkIn // [Function: checkIn]
// invoke (call) the checkIn function
book.checkIn();
book['checkin'];
const language = {
name: 'Swift',
platform: 'iOS',
currentVersion: 5.2,
update: function() {
this.currentVersion = 5.3; // refers to the property `currentVersion`
return this; // refers to the object instance
}
}
console.log(language.update()); // prints language object
/*
{
name: 'Swift',
platform: 'iOS',
currentVersion: 5.3,
update: [Function: update]
}
*/
The this
global context in a Node environment and Browser environment varies.
Example of running this
in a repl.it
environment provides the following output
`this` global output
{
console: {
log: [Function: log],
warn: [Function: warn],
dir: [Function: dir],
time: [Function: time],
timeEnd: [Function: timeEnd],
timeLog: [Function: timeLog],
trace: [Function: trace],
assert: [Function: assert],
clear: [Function: clear],
count: [Function: count],
countReset: [Function: countReset],
group: [Function: group],
groupEnd: [Function: groupEnd],
table: [Function: table],
debug: [Function: debug],
info: [Function: info],
dirxml: [Function: dirxml],
error: [Function: error],
groupCollapsed: [Function: groupCollapsed],
Console: [Function: Console],
profile: [Function: profile],
profileEnd: [Function: profileEnd],
timeStamp: [Function: timeStamp],
context: [Function: context]
},
alert: [Function: log],
prompt: [Function: prompt],
confirm: [Function: confirm],
module: Module {
id: '.',
path: '/home/runner/JavaScript-Playgrounds',
exports: {},
parent: null,
filename: '/home/runner/JavaScript-Playgrounds/index.js',
loaded: false,
children: [],
paths: [
'/home/runner/JavaScript-Playgrounds/node_modules',
'/home/runner/node_modules',
'/home/node_modules',
'/node_modules'
]
},
require: [Function: bound ],
__dirname: '/home/runner/JavaScript-Playgrounds',
__filename: '/home/runner/JavaScript-Playgrounds/index.js',
global: {
console: {
log: [Function: log],
warn: [Function: warn],
dir: [Function: dir],
time: [Function: time],
timeEnd: [Function: timeEnd],
timeLog: [Function: timeLog],
trace: [Function: trace],
assert: [Function: assert],
clear: [Function: clear],
count: [Function: count],
countReset: [Function: countReset],
group: [Function: group],
groupEnd: [Function: groupEnd],
table: [Function: table],
debug: [Function: debug],
info: [Function: info],
dirxml: [Function: dirxml],
error: [Function: error],
groupCollapsed: [Function: groupCollapsed],
Console: [Function: Console],
profile: [Function: profile],
profileEnd: [Function: profileEnd],
timeStamp: [Function: timeStamp],
context: [Function: context]
},
alert: [Function: log],
prompt: [Function: prompt],
confirm: [Function: confirm],
module: Module {
id: '.',
path: '/home/runner/JavaScript-Playgrounds',
exports: {},
parent: null,
filename: '/home/runner/JavaScript-Playgrounds/index.js',
loaded: false,
children: [],
paths: [Array]
},
require: [Function: bound ],
__dirname: '/home/runner/JavaScript-Playgrounds',
__filename: '/home/runner/JavaScript-Playgrounds/index.js',
global: [Circular],
clearInterval: [Function: clearInterval],
clearTimeout: [Function: clearTimeout],
setInterval: [Function: setInterval],
setTimeout: [Function: setTimeout] {
[Symbol(nodejs.util.promisify.custom)]: [Function]
},
queueMicrotask: [Function: queueMicrotask],
clearImmediate: [Function: clearImmediate],
setImmediate: [Function: setImmediate] {
[Symbol(nodejs.util.promisify.custom)]: [Function]
},
checkForGlobalThis: [Function: checkForGlobalThis]
},
clearInterval: [Function: clearInterval],
clearTimeout: [Function: clearTimeout],
setInterval: [Function: setInterval],
setTimeout: [Function: setTimeout] {
[Symbol(nodejs.util.promisify.custom)]: [Function]
},
queueMicrotask: [Function: queueMicrotask],
clearImmediate: [Function: clearImmediate],
setImmediate: [Function: setImmediate] {
[Symbol(nodejs.util.promisify.custom)]: [Function]
},
checkForGlobalThis: [Function: checkForGlobalThis]
}
function checkForGlobalThis() {
return this; // `this` here is bound to the `global` scope
}
const person = {
name: 'Kate',
info: function() {
return this; // does refer to the global context but refers to the object instance
}
}
console.log(checkForGlobalThis() === globalThis); // true
console.log(person.info() === globalThis); // false
MDN documentation: The Object.entries() method returns an array of a given object's own enumerable string-keyed property [key, value] pairs, in the same order as that provided by a for...in loop. (The only important difference is that a for...in loop enumerates properties in the prototype chain as well).
The order of the array returned by Object.entries() does not depend on how an object is defined. If there is a need for certain ordering, then the array should be sorted first, like Object.entries(obj).sort((a, b) => b[0].localeCompare(a[0]));.
const grades = {
adam: 85,
rachel: 90,
bob: 100,
cindy: 75
};
for (const [name, grade] of Object.entries(grades)) {
console.log(`${name} grade is ${grade}`);
}
/*
adam grade is 85
rachel grade is 90
bob grade is 100
cindy grade is 75
*/
const nancy = {
name: 'Nancy'
}
const heather = {
name: 'Heather'
}
function update(fellow1, fellow2) {
fellow1 = { name: 'Tony' }; // changing the object itself doesn't change the insstance, pass-by-value
fellow2.name = "Alex"; // changing the properties changes the insstance properties, pass-by-reference
}
update(nancy, heather);
console.log(nancy); // { name: 'Nancy' }
console.log(heather); // { name: 'Alex' }
MDN documentation: Prototypes are the mechanism by which JavaScript objects
inherit
features from one another.
MDN documentation: JavaScript is often described as a prototype-based language — to provide inheritance, objects can have a prototype object, which acts as a template object that it inherits methods and properties from.
An object's prototype object may also have a prototype object, which it inherits methods and properties from, and so on. This is often referred to as a
prototype chain
, and explains why different objects have properties and methods defined on other objects available to them.
// Here we are using upppercase to denote that Person is a type as opposed to a function person() - good convention practice with naming
function Person(first, last, age, gender, interests) {
// property and method definitions
this.name = {
'first': first,
'last': last
}
this.age = age;
this.gender = gender;
}
const person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);
The Person
instance prototype object also inherits from the Object.prototype
so methods such as valueOf
, toString
are available to it.
console.log(person1.valueOf());
/*
Person {
name: { first: 'Bob', last: 'Smith' },
age: 32,
gender: 'male'
}
*/
Providing our own valueOf
will cause our version on the person1
instance to be printed to the console
function Person(first, last, age, gender, interests) {
// property and method definitions
this.name = {
'first': first,
'last': last
}
this.age = age;
this.gender = gender;
this.valueOf = function() {
console.log(`The person\'s age is ${age}`);
}
}
console.log(person1.valueOf());
// The person's age is 32
Person.prototype.bio = function(job) {
this.job = job;
console.log(`Hi, my name is ${this.name.first} and I work as a ${this.job}.`);
};
person1.bio('Full-Stack developer'); // now the `Person` object has a bio() method associated with all it's instances
// Hi, my name is Bob and I work as a Full-Stack developer.
class Venue {
constructor(name, location) { // similar to an initializer in Swift
this.name = name;
this.location = location
}
info() { // class method in JavaScript or instance method in Swift
console.log(`${this.name} is located in ${this.location}.`);
}
}
// now we can use the `new` keyword to create an instance of Venue()
const arthurAsheStadium = new Venue('Arthur Ashe', 'Flushing Meadows, NY');
arthurAsheStadium.info();
// Arthur Ashe is located in Flushing Meadows, NY
The Recipe Card
Never forget another recipe!
-
Create an object to hold information on your favorite recipe. It should have properties for title (a string), servings (a number), and ingredients (an array of strings).
-
On separate lines (one console.log statement for each), log the recipe information so it looks like:
- Mole
- Serves: 2
- Ingredients:
- cinnamon
- cumin
- cocoa
Solution
const recipe = {
title: 'Strawberry Cake',
servings: 8,
ingredients: ['Flour', 'Butter', 'Strawberries', 'Sugar']
}
for (const [key, value] of Object.entries(recipe)) {
if (key === 'title') {
console.log(value);
}
if (key === 'servings') {
console.log(`Servings: ${value}`);
}
if (key === 'ingredients') {
console.log('Ingredients:')
for (const ingredient of value) {
console.log(ingredient);
}
}
}
/*
Strawberry Cake
Servings: 8
Ingredients:
Flour
Butter
Strawberries
Sugar
*/
Write a JavaScript program to list the properties of a JavaScript object.
Sample object:
const student = {
name : "David Rayy",
sclass : "VI",
rollno : 12
};
_Sample Output: [ 'name', 'sclass', 'rollno' ]_
const student = {
name : "David Rayy",
sclass : "VI",
rollno : 12
};
console.log(Object.keys(student));
Solution
const student = {
name : "David Rayy",
sclass : "VI",
rollno : 12
};
console.log(Object.keys(student)); // [ 'name', 'sclass', 'rollno' ]
Create a class called Person
which accepts the name of a person as a string, and his/her age as a number.
The Person class should have a method called describe which returns a string with the following syntax: "name, age years old". So for example, if John is 19 years old then the function describe of his object will return "John, 19 years old".
Solution
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
describe() {
return `${this.name}, ${this.age} years old.`
}
}
const george = new Person('George', 29);
george.describe(); // George, 29 years old.
The Reading List
Keep track of which books you read and which books you want to read!
- Create an array of objects, where each object describes a book and has properties for the title (a string), author (a string), and alreadyRead (a boolean indicating if you read it yet).
- Iterate through the array of books. For each book, log the book title and book author like so: "The Hobbit by J.R.R. Tolkien".
- Now use an if/else statement to change the output depending on whether you read it yet or not. If you read it, log a string like 'You already read "The Hobbit" by J.R.R. Tolkien', and if not, log a string like 'You still need to read "The Lord of the Rings" by J.R.R. Tolkien.'
Solution
const readingList = [
{ title: 'Good to Great', author: 'Jim Collins', alreadyRead: false },
{ title: 'Unbroken', author: 'Laura Hillenbrand', alreadyRead: true },
{ title: 'Next', author: 'Michael Crichton', alreadyRead: true }
]
for (const book of readingList) {
const message = (book.alreadyRead) ? 'You already read' : 'You still need to read';
console.log(`${message} \"${book.title}\" by ${book.author}.`);
}
/*
You still need to read "Good to Great" by Jim Collins.
You already read "Unbroken" by Laura Hillenbrand.
You already read "Next" by Michael Crichton.
*/
Write a function called cashRegister
that takes a shopping cart object. The object contains item names and prices (itemName: itemPrice). The function should return the total price of the shopping cart.
Example
// Input
const cartForParty = {
banana: '1.25',
handkerchief: '.99',
tShirt: '25.01',
apple: '0.60',
nalgene: '10.34',
proteinShake: '22.36'
};
// Output
cashRegister(cartForParty)); // 60.55
Solution
function cashRegister(shoppingCart) {
let totalPrice = 0;
for (let [itemName, price] of Object.entries(shoppingCart)) {
price = parseFloat(price);
totalPrice += price;
}
return totalPrice;
}
const cartForParty = {
banana: '1.25',
handkerchief: '.99',
tShirt: '25.01',
apple: '0.60',
nalgene: '10.34',
proteinShake: '22.36'
};
let totalPrice = cashRegister(cartForParty);
console.log(`The total price of the shopping cart is ${totalPrice}`);
// The total price of the shopping cart is 60.55
Write a class Vec
that represents a vector in two-dimensional space.
It takes x and y parameters (numbers), which it should save to properties of the same name.
Give the Vec prototype two methods, plus
and minus
,
that take another vector as a parameter and return a new vector
that has the sum or difference of the two vectors’ (this
and the parameter) x and y values.
Add a getter property length
to the prototype that computes the length of the vector—that is,
the distance of the point (x, y) from the origin (0, 0).
// Your code here.
console.log(new Vec(1, 2).plus(new Vec(2, 3)));
// → Vec{x: 3, y: 5}
console.log(new Vec(1, 2).minus(new Vec(2, 3)));
// → Vec{x: -1, y: -1}
console.log(new Vec(3, 4).length);
// → 5
Solution
class Vec {
constructor(x,y) {
this.x = x;
this.y = y;
}
get length() {
return Math.sqrt((this.x * this.x) + (this.y * this.y));
}
plus(vec) {
return new Vec(this.x + vec.x, this.y + vec.y)
}
minus(vec) {
return new Vec(this.x - vec.x, this.y - vec.y)
}
}
console.log(new Vec(1, 2).plus(new Vec(2, 3))); // Vec { x: 3, y: 5 }
console.log(new Vec(1, 2).minus(new Vec(2, 3))); // Vec { x: -1, y: -1 }
console.log(new Vec(3, 4).length); // 5
Define a repeatify
function on the String
object. The function accepts an integer that specifies how many times the string has to be repeated. The function returns the string repeated the number of times specified. For example:
console.log('hello'.repeatify(3));
Should print hellohellohello
.
Solution
String.prototype.repeatify = function(times) {
let str = '';
for (let index = 0; index < times; index++) {
str += this;
}
return str;
}
'Alex is coding......'.repeatify(3);
/*
Alex is coding......Alex is coding......Alex is coding......
*/