Object+Oriented+Programming+in+JavaScript+Notes
Object+Oriented+Programming+in+JavaScript+Notes
Object Oriented
Programming in
Javascript
Table of Contents
Module 1: Objects basics ...................................................................................... 2
Module 2: Objects – Constructors, getters, setters and more ............................ 15
Module 3: Prototypes & Prototype Inheritance ................................................. 27
Module 3: Classes (ES6) & Class Inheritance ....................................................... 32
Module 4: Modules (ES6) .................................................................................... 47
Copyright @ DigiFisk.com
Page 2 of 52
And let’s say these are the properties of the 2nd person.
Person2:
Name: Gary
Copyright @ DigiFisk.com
Page 3 of 52
Age: 40
Height: 180
Hair: blond
So, as you can see here, they have the same properties, but the values differ in
some cases, but remain the same in others. They both have blond hair.
So, this is how objects are written. In fact, person2, which is a different object,
can in fact have more properties or different properties than the person1 object.
Let’s add eye color to the 2nd object.
eyeColor: blue
So, this illustrates what objects are, and how their properties and values are
derived.
Copyright @ DigiFisk.com
Page 4 of 52
The first method is more commonly used, so let’s stick to that. We just created an
empty object so far. What if we need to insert properties and values into them?
The easiest way to do that would be while creating the object.
For person2:
let person2 = { name: "Gary", age: 40, height: 180, hair:
"blond", eyeColor: "blue" };
As you can see here, you declare the variable first, and the variable gets
converted to an object based on what is assigned to it, which is in this case
property value pairs.
An object’s values are created within two flower braces.
The property is written first, and with a color, the value for that property is
written, just like in the case of a CSS stylesheet. This is a property value pair as
well.
This is called encapsulation. Everything that is related to person 1 is encapsulated
inside that object, in the form of properties and its values.
Copyright @ DigiFisk.com
Page 5 of 52
Let’s try displaying the values on our live editor. Let’s say we want to know that
person1’s height is. To do that, let’s alert:
alert(person1.height);
If we run the above line of code, we get Susan’s height, which is 160 cms.
Let’s try doing the same with the 2nd method now.
alert(person1["height"]);
Delete properties
You can delete the properties from the object as well, by using the pre-defined
delete property of the Object.
delete person2.canVote;
console.log(person2);
Dynamic access
You can make accessing, adding or anything of a property in an object dynamic by
declaring a variable and using that as the point of reference.
let prop = "hair";
console.log(person1[prop]);
person1[prop] = "brunette";
prop = "name";
console.log(person2[prop]);
Copyright @ DigiFisk.com
Page 6 of 52
You can get the value of prop from the user to make it truly dynamic, like this:
let prop = prompt("What do you want to see?","hair");
alert(`Person 1's ${prop} is ${person1[prop]}`);
We get undefined because prop isn’t an actual property, we need to replace the
string inside it in the square brackets for it to work.
Muli-word properties
We can create multi-word properties within square brackets.
person1["can vote"] = true;
person1.can vote = true; //doesn’t work
It thinks person1.can is the correct syntax, and vote will produce an error.
After the dot, you need a valid variable that adheres to variable rules: starts with
$ or letters, contains $, letters, numbers or _, no spaces or other special
characters, etc.
The following will produce an error too.
person1.%vote = true;
But square brackets always work with multi-word properties, to set properties,
update them, delete them, etc. They should always be within quotes though,
single, or double.
Shorthand
Look at the example below:
let fName = "John";
let lName = "Doe";
let age = 35;
Copyright @ DigiFisk.com
Page 7 of 52
let person1 = {
fName: fName,
lName: lname,
age: age
};
Sometimes, the property name and their values are the same.
In that case, we can use shorthand to save some space, like this:
let person1 = {
fName,
lName,
age
};
console.log(fName);
This works with functions too. Sometimes, we receive values as arguments inside
a function and we return an object with them, like this:
function createPerson(fName, lName, age) {
let fullName = `${fName} ${lName}`;
return {
fName: fName,
lName: lName,
age: age,
fullName: fullName
};
}
console.log(createPerson("John","Doe",35));
Copyright @ DigiFisk.com
Page 8 of 52
Arrays as objects
You can also create an array of objects. As you know, an object holds the
properties and values of a single object. What if you want to hold the properties
of multiple objects? Arrays are your best bet.
Let’s create a variable called just person this time. This variable should hold and
array that has 2 object, one which has the properties we assigned to the person1
object and the other which has the properties we assigned to the person2 object.
let person = [{ name: "Susan", age: 35, height: 160, hair:
"blond" }, { name: "Gary", age: 40, height: 180, hair: "blond",
eyeColor: "blue" }];
So, all you must do is, create the object’s property value pairs within a flower
bracket, and separate them by commas.
Now, to access the values, use the same method as before, but this time with
array indexes so your browser knows which object you are referring to.
So, let’s say we want to get the eye color of the 2nd object.
Then, you must do it like this. The variable name, then the array index of that
object, which in this case is 1, and follow that up with the dot and the property
name, as usual.
person[1].eyeColor
Copyright @ DigiFisk.com
Page 9 of 52
const PI = 3.14;
PI = 4; //error
We can change the property to anything, and it’ll affect the object.
The below line of code changes the object.
let person = "John Doe";
Copyright @ DigiFisk.com
Page 10 of 52
Copyright @ DigiFisk.com
Page 11 of 52
Object methods
Can create methods just as we can create properties. They are basically functions
that pertain to that particular object.
let person = {
fName: "Jane",
lName: "Doe",
fullName: function() {
return person.fName + " " + person.lName;
}
};
console.log(person.fullName());
Why person.fName, why not just fName because it is inside the object after all.
Let’s try.
It says undefined. That’s because fName as such wasn’t declared, it’s a part of the
object.
fullName() {
return person.fName + " " + person.lName;
}
The above works too because of the ES6 update. We don’t have to rely on
function expressions anymore.
We can create methods outside of the object too, but in that case, you need to do
something like this:
person.fullName = function() {
return person.fName + " " + person.lName;
}
But if we tried what we did before, we’ll get an error.
person.fullName() {
return person.fName + " " + person.lName;
}
Copyright @ DigiFisk.com
Page 12 of 52
console.log(person.fullName);
We’ll just get the function definition.
We can assign functions that we’ve defined before to an object’s method too.
let person = {
fName: "Jane",
lName: "Doe",
fullName: fullName
};
function fullName() {
return person.fName + " " + person.lName;
}
console.log(person.fullName());
Since it is a normal function definition and not a function expression, you can
place it after you create an object as well and it’ll work the same as placing it
before the object.
“this” in methods
In the above examples, we accessed properties that were inside the objects for
our method, so we used person.propertyName to access them. But its right
inside, so why not use “this”?
let person = {
fName: "Jane",
lName: "Doe",
fullName() {
return this.fName + " " + this.lName;
}
};
“this” in this case refers to the object within which the method resides.
It’ll work the same if we create the method outside the object as well (show).
Why do we even bother with “this”? Why not just stick to person.fName?
Well, because referencing the object name as such is unreliable. What if we copy
the object to another variable? Create a copy of it? Then if we try to reference the
method, we won’t get what we want.
let person1 = person;
Copyright @ DigiFisk.com
Page 13 of 52
This creates a reference to the object in person1 too. I’ll explain about object
referencing in a future lesson.
console.log(person1.fullName());
console.log(person1);
The above works, but what if we change person?
What if we make person null? Technically, person1 should still work because it is
still referencing the original object and still has everything, right?
Let’s check.
Ok, person1 is still there.
But if we try to access the function, what happens?
console.log(person1.fullName());
We’re getting an error: “Cannot read fName of Null”.
But if it were “this”, we wouldn’t have gotten this problem.
return this.fName + " " + this.lName;
So now it works.
This is the main advantage of using “this” over the object name in methods like
this. It makes the methods more dynamic and not bound to one object name.
It’ll only work if you use function expressions. “this” doesn’t work with arrow
functions.
“this” refers to whatever object calls the function. When we later learn about
constructors and creating multiple objects out of the same constructor, you’ll
understand how truly dynamic “this” is.
Copyright @ DigiFisk.com
Page 14 of 52
In objects, if you try to access a property that’s not in an object, you’ll just get
undefined, and not an error (show). That’s why it shows as true and false in here.
Realistically, you can do this as well:
console.log(person.name == undefined);
But what if name was assigned undefined in the object. Then we would not know
for sure if the object has that property or not. That’s why we’re better off using
“in”.
That said, in can be used to parse through all the keys in the object in a for loop,
by using the for…in loop.
for(let prop in person) {
console.log(person[prop]);
}
It shows the values of both the properties and methods.
Copyright @ DigiFisk.com
Page 15 of 52
If we check in the console, both have the same property and values, but they
don’t actually store them separately. Let me prove that to you.
Let me change the value of one of the properties of person1.
person1.fName = "John";
console.log(person);
We just changed person1, but person has changed as well. This proves that both
the variables are just referencing a common property.
If you compare these objects, you’ll know the truth.
Copyright @ DigiFisk.com
Page 16 of 52
It’s proper cloning now. Changing one object doesn’t change the other one.
Example:
let person1 = Object.assign({}, person);
console.log(person1);
Copyright @ DigiFisk.com
Page 17 of 52
You can use this to merge multiple objects into one object as well, in which case
you don’t have to assign it to a variable.
After the person object, let’s create more objects called voting and career.
let voting = {
canVote: true,
gender: "female"
};
let career = {
graduate: true,
hasJob: true;
}
Object.assign(person,voting,career);
console.log(person);
Constructors
JavaScript constructors is used to set the initial properties of the object that it
creates.
If you want multiple objects to have the same set of properties and methods, but
save typing the same thing over and over again, constructors are the best way to
go about it.
They look just like functions, but the difference in how you call the function.
It’s good practice to name the constructor function with a starting capital letter.
function People(fName, lName) {
this.fName: fName;
this.lName: lName;
}
let person1 = new People("John","Doe");
let person2 = new People("Susan", "Dee");
When the new keyword is used, it creates an empty object, replaces “this” with
the new object (person1 or person2), then assigns the attribute values and
returns them back to the object.
Copyright @ DigiFisk.com
Page 18 of 52
console.log(person1);
console.log(person2);
console.log(person1.fName);
console.log(person2.lName);
We should not call objects without new, then it’ll take “this” as window, and
this.fName would become window.fName – that’s not good practice.
To prevent that, can use new.target. It returns empty if called without new and
the function (true) if returned with new.
function People(fName, lName) {
if(!new.target) {
return new People(fName, lName); //call it back with
new so its rectified
}
this.fName = fName;
this.lName = lName;
}
If called without new in ‘use strict’ mode, then it’ll show an error. So, in use strict,
if you don’t want error, use the if to circumvent the call so you don’t get, “can’t
set property fName of undefined”.
Can get return from constructors though constructors automatically return the
property and method values without mentioning.
If you return an object, then it’ll be returned, and the rest will be overridden. If
you return primitive, it’ll be ignored.
function People(fName, lName) {
this.fName = fName;
this.lName = lName;
return {
name: "Jane Doe",
age: 30
};
Copyright @ DigiFisk.com
Page 19 of 52
}
console.log(person1);
Output: {name: "Jane Doe", age: 30}
But, if you just the following, your browser will ignore it:
return "Jane Doe";
Was ignored.
Constructor expressions:
Just like functions, you can create constructors as function expressions as well.
Let’s see how:
let People = function(fName,lName) {
this.fName = fName;
this.lName = lName;
}
let person1 = new People("John","Doe");
console.log(person1);
Copyright @ DigiFisk.com
Page 20 of 52
The above lines of code returns the list of properties in an array: ["fName",
"lName"]
This will not return the symbols (I’ll teach this in a later lesson) or methods.
So, while accessing a property, the only thing we see is the value. Where do we
see the rest of the descriptors?
Copyright @ DigiFisk.com
Page 21 of 52
As you can see, by default, the values for writable, enumerable, and configurable
are true. That is, by default, a property’s value can be changed, it’ll be shown on
loops and it can be deleted, or the descriptor values can be changed.
But what if we want to change one of these?
We can use the defineProperty method.
Its syntax is as follows:
Object.defineProperty(obj,property,descriptor);
Examples:
If we want to change values:
Object.defineProperty(person1,"fName",{
value: "Gary"
});
console.log(person1.fName);
Copyright @ DigiFisk.com
Page 22 of 52
Non enumerable:
Object.defineProperty(person1,"fName",{
enumerable: false
});
for(let prop in person1) {
console.log(prop);
}
Non configurable:
Object.defineProperty(person1,"fName",{
configurable: false
});
delete person1.fName;
As you can see with defineProperty, we can actually use it to create a new
property as well, or update the value of a property, instead of using the usual
methods that involve the dot notation or the square brackets.
Doing it one property at a time is very time consuming though. You can define
multiple properties at the same time by using the defineProperties method.
Object.defineProperties(objName,{
property1 : {descriptor : value...},
property2 : {descriptor : value...},
property3 : {descriptor : value...}
});
Copyright @ DigiFisk.com
Page 23 of 52
Copyright @ DigiFisk.com
Page 24 of 52
}
};
Symbols
Symbols are another data type of JavaScript which are mostly used with respect
to objects.
So, this is how you create them:
let sym = Symbol("id");
“id” here is just a label. It doesn’t mean anything. It’s mostly used to identify the
symbol, for debugging purposes etc.
But, every symbol is unique. If you create another symbol, even if it has the same
label, then it’ll still be unique. Let me prove that to you.
let sym = Symbol("id");
let sym1 = Symbol("id");
Copyright @ DigiFisk.com
Page 25 of 52
Copyright @ DigiFisk.com
Page 26 of 52
You can create global symbols as well, that is, symbols that are the same, if
created with the same label.
let sym = Symbol.for("id");
let sym1 = Symbol.for("id");
console.log(sym === sym1);
You can get the label for a symbol by using the keyFor property.
console.log(Symbol.keyFor(sym));
console.log(Symbol.keyFor(sym1));
Copyright @ DigiFisk.com
Page 27 of 52
Copyright @ DigiFisk.com
Page 28 of 52
Copyright @ DigiFisk.com
Page 29 of 52
Prototype inheritance
You can inherit the properties and methods of one object to another. That’s
called prototype inheritance.
You can inherit the prototype, especially, so all the methods under the prototype
will be accessible by the inherited object.
An object can only inherit from one object, not many, and the inheritance cannot
be cyclic. That is, if obj2 inherits from obj1, and obj3 inherits from obj2, then obj1
cannot inherit from either obj2 or obj3.
function Person(fName, lName) {
this.fName = fName;
this.lName = lName;
}
Person.prototype.fullName = function() {
return `${this.fName} ${this.lName}`;
}
//So Runner inherits from Prototype
Runner.prototype = Person.prototype;
function Runner(speed,...args) {
//lets get the property values of People inside an array
and apply that using the apply pre-defined function - bind this
to that array and apply it to Person
Person.apply(this,args);
this.speed = speed;
}
Runner.prototype.isTop10 = function() {
if(this.speed < 5) {
return `${this.fullName()} is in the top 10`;
}
else {
return `${this.fullName()} is not in the top 10`;
}
}
let person1 = new Person("John", "Doe");
Copyright @ DigiFisk.com
Page 30 of 52
You can inherit only one of the object instance and not everything as well. That’s
up to you.
Let’s remove this line:
Runner.prototype = Person.prototype;
Let’s retain the apply because we are just getting the rest parameter. If it has
nothing, it’ll have nothing to bind (lets check).
And also change the dependence code like this:
Runner.prototype.isTop10 = function() {
if(this.speed < 5) {
return `$The runner is in the top 10`;
}
else {
return `$The runner is not in the top 10`;
}
}
let person1 = new Person("John","Doe");
let runner1 = new Runner(4.5); //don’t have to give fName and
lName because we are directly inheriting from an object instance
which already has those values assigned
let person2 = new Person("Gary","Smith");
let runner2 = new Runner(6);
runner1.__proto__ = person1;
console.log(runner1);
console.log(runner1.fullName());
console.log(runner2.fullName()); //error
Prototype chain:
let person = {
fName : "John",
lName : "Doe"
};
let sportsPerson = {
sports : "Runner",
__proto__ : person
Copyright @ DigiFisk.com
Page 31 of 52
};
let runner = {
speed : 4.5,
__proto__ : sportsPerson
};
console.log(runner);
Look at the protos - 3 protos - first for runner, then sportsPerson, then person and
finally goes to the main Object __proto__ which has all the pre-defined methods -
this is called prototype chaining
If you use for…in over an inherited object ,it’ll iterate over the inherited
properties as well:
for(let key in runner) {
console.log(key);
}
Copyright @ DigiFisk.com
Page 32 of 52
Copyright @ DigiFisk.com
Page 33 of 52
Function comes from the constructor method. The constructor method is not
compulsory. You can write a class without one as well. If there’s no constructor,
it’ll be considered empty.
All the methods are automatically stored in Person.prototype. You don’t have to
separately create them like you did when working with constructors and
prototypes. So, classes are a higher form of them, but it uses them in the
background.
So, whenever we call a method from an object created with the class, it takes the
method from the prototype.
//Person is actually a constructor and it’s a function because
of the constructor method
console.log(Person === Person.prototype.constructor);
Copyright @ DigiFisk.com
Page 34 of 52
It uses strict mode by default as well. So, if we don’t use new to call the class
constructor, even if your code is not in strict mode, you’ll get an error, unlike with
normal constructors.
Remove use strict statement.
Now,
let person1 = People("John","Doe");
Error: Class constructor People cannot be invoked without 'new'
So, classes have some differences to normal constructors and prototypes. It’s not
just syntactic sugar. It made some improvements to Javascript.
Class fields
We can create properties outside of the class constructor as well. Can use it to get
input from user and other complicated things. These are called class fields.
Copyright @ DigiFisk.com
Page 35 of 52
Copyright @ DigiFisk.com
Page 36 of 52
fullName() {
return `${this.f} ${this.l}`;
}
}
let person1 = new People("John","Doe");
console.log(person1.fullName());
console.log(person1.fName); //invokes the setter for fName
console.log(person1); //look inside proto, getters and setters
were created inside the prototype
Method chaining
You can chain method calls one after the other to save some line of space.
class Person {
constructor(fName,lName,age) {
this.fName = fName;
this.lName = lName;
this.age = age;
}
isMajor() {
if(this.age > 18) {
console.log("Major");
}
else {
console.log("Minor");
}
}
fullName() {
console.log(`${this.fName} ${this.lName}`);
}
}
let person1 = new Person("John","Doe",40);
person1.isMajor().fullName(); //get an error saying cannot call
fullName() of undefined.
Copyright @ DigiFisk.com
Page 37 of 52
Class inheritance
Classes have inheritance like prototypes do.
We must use the extends keyword with the class that we want to inherit from the
parent class.
class Person{
constructor(fName,lName,age) {
this.fName = fName;
this.lName = lName;
this.age = age;
}
fullName() {
return `${this.fName} ${this.lName}`;
}
}
class Major extends Person {
isMajor() {
if(this.age > 18) {
return true;
}
else {
return false;
}
}
}
let person1 = new Major("John","Doe",40);
console.log(person1.isMajor());
Copyright @ DigiFisk.com
Page 38 of 52
this.fName = fName;
this.lName = lName;
this.age = age;
}
fullName() {
return `${this.fName} ${this.lName}`;
}
isMajor() {
return (this.age > 18) ? `Major` : `Minor`;
}
}
class Major extends Person {
isMajor() {
return this.age > 18 ? `true` : `false`;
}
}
let person1 = new Major("John","Doe",40);
console.log(person1.isMajor()); //true
So, class Major’s isMajor() function was executed, not the Person class’s. So, the
one nearest in the inheritance tree will be executed.
This is called method overriding.
But sometimes, we might want the child class’s method to be executed, after
which, or before which, the parent class’s method to ALSO be executed.
So, in those classes, use the super keyword, and call the parent method from the
child method to get around method overriding.
class Person{
constructor(fName,lName,age) {
this.fName = fName;
this.lName = lName;
this.age = age;
}
fullName() {
return `${this.fName} ${this.lName}`;
}
isMajor() {
if(this.age > 18) {
return `${this.fullName()} is a Major`;
}
Copyright @ DigiFisk.com
Page 39 of 52
else {
return `${this.fullName()} is a Minor`;
}
}
}
class Major extends Person {
isMajor() {
console.log(this.age > 18 ? `true` : `false`);
return super.isMajor(); //calling parent isMajor()
after the child isMajor is executed. Can't give a return
statement before this though, then it would never reach this
line. So changing it to a cosnsole. But I'm returning
super.isMajor() or else the parent will return nothing and it'll
be undefined (show)
}
}
let person1 = new Major("John","Doe",40);
console.log(person1.isMajor());
Overriding a constructor
So far, our child classes never had constructors. But what if they did, because they
wanted to assign properties while creating the object like a normal class would?
Then how would you assign the properties of your parent constructor?
By using super again. Let’s see how.
Let’s receive age in the major class now and have just one isMajor function in the
inherited class, and see what happens.
I’m getting this error:
Uncaught ReferenceError: Must call super constructor in derived
class before accessing 'this' or returning from derived
constructor
at new Major
So, let’s add super. Call super first to instanciate the parent constructor first and
then works on the child constructor. You need to receive all the property values in
Copyright @ DigiFisk.com
Page 40 of 52
the child constructor and send the corresponding ones to the parent constructor,
like this:
class Person{
constructor(fName,lName,age) {
this.fName = fName;
this.lName = lName;
}
fullName() {
return `${this.fName} ${this.lName}`;
}
}
class Major extends Person {
constructor(fName, lName, age) {
super(fName,lName);
this.age = age;
}
isMajor() {
console.log(this.age > 18 ? `true` : `false`);
return super.isMajor();
}
}
let person1 = new Major("John","Doe",40);
console.log(person1);
Copyright @ DigiFisk.com
Page 41 of 52
this.age = age;
}
fullName() {
return `${this.fName} ${this.lName}`;
}
}
let person1 = new Person("John","Doe",40);
let person2 = new Person("Susa","Smith",36);
console.log(`${person1.fullName()} is a ${Person.species}`);
That’s how you use properties.
You can use methods to compare and operate on multiple object’s property
values from within the class.
For example, let’s say we want to know who’s older between the two objects we
sent. We can do that comparison within the Person class by using the static
keyword.
static whoIsOlder(person1,person2) {
if(person1.age1 > person2.age2) {
console.log(`${person1.fullName()} is older than
${person2.fullName()}`);
}
else {
console.log(`${person2.fullName()} is older than
${person1.fullName()}`);
}
}
Person.whoIsOlder(person1,person2);
Copyright @ DigiFisk.com
Page 42 of 52
Protected property
So, let’s look at protected first. We can use getters and setters to do that. But we
can also use normal functions/methods as well, so let’s look at both ways of doing
that.
It’s usually good practice to prefix the name of the protected property with an _.
It’s not compulsory, but it’s done.
class People {
Copyright @ DigiFisk.com
Page 43 of 52
}
let runner1 = new Runner();
runner1.name = "Susan Dee";
console.log(runner1); //accesses _name which is a hidden
property
console.log(runner1.name);
But there is a problem with this method. If you know the name of the hidden
property, you can actually access it from the outside, so it is not really hidden,
after all.
console.log(person1._name);
Instead of getters and setters, you can use functions as well.
class People {
_name = ''; //protected
setName(n) {
this._name = n;
}
getName() {
return this._name;
}
}
let person1 = new People();
person1.setName("John Doe");
console.log(person1.getName());
console.log(person1);
Copyright @ DigiFisk.com
Page 44 of 52
There’s an actual syntax for private properties now. It’s a latest addition to the
Javascript language so there is not much browser support for it yet, but let’s look
at it.
So, you just prefix the property with # to make it private. The color changes in
your editor, and it’ll be have as a private property should.
class People {
#name = ''; //protected
set name(n) {
this.#name = n;
}
get name() {
return this.#name;
}
}
let person1 = new People();
person1.name = "John Doe";
console.log(person1.name);
console.log(person1);
console.log(person1.#name); //error - private field #name must
be declared in an enclosing class
Now let’s look at inheriting this private property from inside the child class.
Copyright @ DigiFisk.com
Page 45 of 52
Factories in Javascript
At the base of it all, factories are just functions that return objects. In most cases,
you can use factory functions instead of classes and they are much simpler than
classes.
So why use factories instead of classes? Well, first, it’s yet another way of creating
objects. Also, you don’t have to mess around with “this” and “new” anymore
(you’ll see how) and so you can avoid a lot of the problems that come with “this”
and “new”.
Also, you can make properties and their values truly private without having to
jump through a lot of loops like you would with classes.
So, let’s look at an example of a factory function with private properties now.
You don’t have to capitalize the first letter of a factory function because it is just a
function.
function people(f,l) {
let fName = f; //private - not accessible from outside the
function, even by the object instances
let lName = l; //both can't have the same name or you'll
get an error
return {
fullName() {
return `${fName} ${lName}`;
}
}
}
let person1 = people("John","Doe");
console.log(person1.fullName());
console.log(person1.fName); //undefined - not accessible
Copyright @ DigiFisk.com
Page 46 of 52
Of course, you can make the properties public like you would with a normal class
as well:
function people(fName,lName) {
return {
fName : fName, //can be the same name now since one of
them is a property name and not a variable name
lName : lName,
fullName() {
return `${fName} ${lName}`;
}
}
}
Now you can access them from the outside.
Copyright @ DigiFisk.com
Page 47 of 52
You can import it into the other file by using the import keyword.
import {name} from './hello.js';
Examples of export:
You can export anything.
Copyright @ DigiFisk.com
Page 48 of 52
You can import arrays and use them in any way we want.
export let arr = [1,2,3,"Hello"];
Reassigning doesn’t work between modules, no matter what type of variable that
is. The outside module can’t reassign a variable that wasn’t originally its.
Changing array elements worked because we aren’t completely changing the
array, but that isn’t the case with primitive data types like string, Boolean or
numbers, so you can’t change them in any way outside of the module. The minute
it is exported, your browser will import it as a constant in the other modules.
export let str = "Hello";
import {str} from "./hello.js";
str = "hi"; //error
The same rule follows for objects, constructors, and classes. Let’s take a look at
them now.
Copyright @ DigiFisk.com
Page 49 of 52
}
Sports.prototype = Person.prototype;
let sports1 = new Sports();
console.log(sports1); //look into proto and you'll see fullName
method inside prototype.
//Let's create a simple method inside Person prototype and see
if that is inherited within sports.
Person.prototype.sayHi = function() {
Copyright @ DigiFisk.com
Page 50 of 52
console.log("Hello there!");
}
sports1.sayHi();
Obviously, you can export and import functions as well. We’ve already looked at
some examples of doing the same when we looked at objects, constructors and
classes.
Works with constants as well. Usually constants cannot be changed, and that
holds true for modules as well:
export const PI = 3.14;
Copyright @ DigiFisk.com
Page 51 of 52
If you export multiple things at the same time, then you can import multiple
things at the same time too.
import {PI,sayHi,person} from "./hello.js";
console.log(`${person.fName} says ${sayHi()} and ${PI}`);
You can export everything you can from a module with the asterisk symbol, at
which point it’ll be imported as an object, and this is how you make it work:
import * as all from "./hello.js";
console.log(`${all.person.fName} says ${all.sayHi()} and
${all.PI}`);
Copyright @ DigiFisk.com
Page 52 of 52
Copyright @ DigiFisk.com