0% found this document useful (0 votes)
6 views7 pages

JavaScript Object Cloning Techniques

Uploaded by

Mansi Patel
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views7 pages

JavaScript Object Cloning Techniques

Uploaded by

Mansi Patel
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Cloning and merging, [Link] Now it’s not enough to copy [Link] = user.

sizes,
because the [Link] is an object, it will be copied by
So, copying an object variable creates one more reference. So clone and user will share the same sizes:
reference to the same object. Like this:

let user = {
To make duplicate an object
name: "John",
sizes: { height: 182, width: 50 } };
Methods : [Link] iteration 2. [Link]
let clone = [Link]({}, user);
By iteration
let user = { name: "John", age: 30 }; alert( [Link] === [Link] ); //
let clone = {}; // the new empty object true, same object

// let's copy all user properties in it // user and clone share sizes
[Link]++;
for (let key in user) {
clone[key] = user[key]; // change a property from one place
}
//now clone is a fully independent alert([Link]); // 51, see
clone the result from the other one
[Link] = "Pete"; // changed the
data in it
alert( [Link] ); // still John in
To fix that, we should use the cloning loop that examines
the original object
each value of user[key] and, if it’s an object, then
replicate its structure as well. That is called a “deep
[Link]
cloning”.
- The syntax is: [Link](dest, [src1, src2, src3...])
We are using below method for this…will see later
- properties of all arguments starting from the 2nd are
_.cloneDeep(obj)
copied into the 1st. Then it returns dest.

let user = { name: "John" };


let permissions1 = { canView: true };
let permissions2 = { canEdit: true };

// copies all properties from permissions1 and


permissions2 into user
[Link](user, permissions1,
permissions2);
// now user = { name: "John", canView:
true, canEdit: true }

If the receiving object (user) already has the same named


property, it will be overwritten:
let user = { name: "John" };
// overwrite name, add isAdmin
[Link](user, { name: "Pete",
isAdmin: true });
// now user = { name: "Pete", isAdmin:
true }

- Until now we assumed that all properties of user are


primitive. But properties can be references to other
objects(object inside object). What to do with them?
Like this:
let user = {
name: "John",
sizes: { height: 182, width: 50 } };
alert( [Link] ); // 182
In JavaScript, the difference between strict mode Non-Strict Mode (Default)
and non-strict mode mainly revolves around how the
code is executed and the level of errors that are In non-strict mode, JavaScript allows more lenient
enforced. Here's a breakdown: syntax and does not enforce the rules that strict mode
does. This can lead to potential errors going
Strict Mode ("use strict";) unnoticed, especially in larger codebases.

Strict mode is a way to opt into a restricted variant of Key Differences in Non-Strict Mode:
JavaScript, which helps catch common coding
mistakes and "unsafe" actions. It can be enabled by 1. Allows Silent Errors: Some errors, such as
placing "use strict"; at the top of a script or a assignments to non-writable properties or
function. undeclared variables, do not throw errors and
instead fail silently.
Key Differences in Strict Mode: 2. Global this: In non-strict mode, this in a
function refers to the global object (window in
1. Eliminates Silent Errors: Some actions that browsers), which can lead to unintended
would otherwise fail silently in non-strict consequences.
mode will throw errors in strict mode. This 3. Permits eval() and with: The eval()
makes debugging easier. function and with statement are allowed,
2. Disallows this Keyword in Global Scope: which can lead to harder-to-debug code and
In strict mode, this is undefined in functions potential security risks.
that are not methods of an object, while in 4. No Duplicate Parameter Check: Functions
non-strict mode, this defaults to the global can have parameters with the same name
object (window in browsers). without throwing an error.
3. Prevents Variable Declarations Without
var, let, or const: If you forget to declare a Ex. function nonStrictExample() {
variable, strict mode will throw a
ReferenceError. In non-strict mode, the undeclaredVariable = 10;
variable is created as a global variable. // No error, variable is created
4. Disallows Duplicate Parameter Names: In globally
strict mode, defining a function with duplicate }
parameter names will throw a SyntaxError.
5. Restricts Deleting Variables: Strict mode nonStrictExample();
disallows deleting variables, functions, or [Link](undeclaredVariable); /
/ Outputs: 10
arguments. Attempting to do so will throw an
error.
6. Secures JavaScript: Strict mode disallows
eval() and with statements, making code Ex. function sayHi() { alert(this); }
more predictable and less prone to security sayHi();
vulnerabilities. // value of this in such case will be the global
object ( window in a browser )
Ex. "use strict";

function strictExample() {

undeclaredVariable = 10;
// ReferenceError:
undeclaredVariable is not defined
}

strictExample();

Ex. function sayHi() { alert(this); }


sayHi(); // undefined

Ex. function sayHi()


{ alert([Link]);}
sayHi(); // Error
Object methods let user = {
name: "John",
A function that is the property of an object is called its age: 30,
method. The value of this is defined at run-time. When a sayHi() {
function is declared, it may use this , but that this has no alert( [Link] ); // leads to error
value until the function is called. }};
let admin = user;
We can define method in 2 ways. user = null; // overwrite to make things obvious
1. Using function keyword [Link](); // Whoops! inside sayHi(), the old
user = { name is used! error!
name : “Raj”,
sayHi: function() { If we used [Link] instead of [Link] inside the alert
alert("Hello"); then the code would work.
}};
2. Without using function keyword “this” is not bound
user = { The value of this is evaluated during the run-time,
name : “Raj”, depending on the context. And it can be anything.
sayHi() {
alert("Hello");
The consequences of unbound this
}};
If you come from another programming language, then
So, here we’ve got a method sayHi of the object user .
you are probably used to the idea of a "bound this ",
Of course, we could use a pre-declared function as a where methods defined in an object always have this
method, like this: referencing that object.
In JavaScript this is “free”, its value is evaluated at call-
// first, declare
time and does not depend on where the method was
function sayHi() { alert("Hello!"); };
declared, but rather on what’s the object “before the
let user = { ... }; dot”.

// then add as a method


Lexical Scoping: In JavaScript, lexical scoping means
[Link] = sayHi;
that the accessibility of variables is determined by the
[Link](); // Hello!
physical structure of the code. Outer scopes can be
};
accessed by inner functions, but inner variables are not
"this” in Object accessible from the outer functions because they are
confined to the inner function's scope.
It’s common that an object method needs to access the
- This design promotes encapsulation and prevents
information stored in the object to do its job.
unintended interference with variables inside inner
For instance, the code inside [Link]() may need the
functions.
name of the user .
- When a function is executed, JavaScript first looks for
To access the object, a method can use the this keyword. variables within the function's own scope. If it doesn't
The value of this is the object “before dot”, the one used find them there, it moves up the scope chain to the
to call the method. next outer scope, continuing until it either finds the
variable or reaches the global scope.
let user = { function outerFunction() {
name: "John", const outerVar = "I'm outside!";
age: 30,
sayHi() { alert([Link]); function innerFunction() {
} }; const innerVar = "I'm inside!";
[Link](); // John [Link](outerVar); //accessible
}
Here during the execution of [Link]() , the value of innerFunction();
this will be user .
[Link](innerVar); // Error:
Technically, it’s also possible to access the object without innerVar is not defined
this , by referencing it via the outer variable: }
…But such code is unreliable. If we decide to copy user to
outerFunction();
another variable, e.g. admin = user and overwrite user
with something else, then it will access the wrong object.
That’s demonstrated below:
Constructor, operator "new"
Arrow functions have no “this”
const person = {
name: "John", The regular {...} syntax allows to create one object. But
greet: function() { often we need to create many similar objects, like
const innerGreet = () => {
[Link](`Hello, ${[Link]}`); multiple users or menu items and so on.
}; That can be done using constructor functions and the
innerGreet(); "new" operator
}
};
Constructor function
[Link](); // Output: "Hello, John" Constructor functions technically are regular functions.
There are two conventions though:
Explanation: 1. They are named with capital letter first.
2. They should be executed only with "new" operator.
 In this example, innerGreet is an arrow
function, which means it doesn't have its own function Person(){
this. Instead, it inherits this from its lexical [Link] = "Elon",
scope, which is the greet function in this [Link] = "Musk"
case. This allows innerGreet to correctly }
refer to [Link] even though it is defined
inside another function. const person1 = new Person();
 For instance, here innerGreet() uses “this” const person2 = new Person();
from the outer [Link]() method:
[Link](person1);
//{ firstName:"Elon", lastName:”Musk”}
- Create a calculator using object
let calculator = { [Link](person2);
sum() { //{ firstName:"Elon", lastName:”Musk”}
return this.a + this.b;
},
mul() { If we have argument in the function then we can use it in
return this.a * this.b; the below way.
},
read() { function Person(first, last){
this.a = +prompt('a?', 0); [Link] = first,
this.b = +prompt('b?', 0); [Link] = last
} }
};
[Link](); const person1 = new Person("Elon",
alert( [Link]() ); "Musk");
alert( [Link]() ); const person2 = new Person("Bill",
"Gates");

[Link](person1);
//{firstName:"Elon", lastName:”Musk”}

[Link](person2);
//{firstName:" Bill ",lastName:”Gates”}
Now let’s add a method

function Person (first, last){


[Link] = first,
[Link] = last,
[Link] = function(){
return [Link] + " " +
[Link]; }
}
const person1 = new Person("Elon",
"Musk");
const person2 = new Person("Bill",
"Gates"); Here you can see that gender property is not available in
the Person but still you can access it bcos it is available in
[Link]([Link]()); the Prototype…
//Elon Musk
In the same way... you can store the method in the
[Link]([Link]());
prototype
//Bill Gates
function Person(fName, lName) {
[Link] = fName,
Here issue is that, whenever new Object is created with [Link] = lName
the new Operator then every time this method will be }
created in the every new created object…which is not
memory efficient [Link]() =
function {
To fix this issue we are using prototype. return [Link] + " " +
[Link]; }
- In JS. Every function and Object has its own
property called Prototype const person1 = new Person("Elon",
- Prototype stored the method and share it with all "Musk");
the new created object. const person2 = new Person("Bill",
- We can use the Prototype to add properties and "Gates");
methods to a constructor function.
- objects inherit the properties and methods from a [Link]([Link]());
prototype. //Elon Musk
- That’s the main purpose of constructors – to [Link]([Link]());
implement reusable object creation code. //Bill Gates

function Person(fName, lName) {


[Link] = fName,
[Link] = lName
}

[Link] = "Male";

const person1 = new Person("Elon",


"Musk");
const person2 = new Person("Bill",
"Gates");

[Link](person1); // see image


[Link]([Link]); // Male
[Link]([Link]); // Male
- If a prototype value is changed, then all the new
Que. Is it possible to create functions A and B such as new
objects will have the changed property value.
A()==new B() ?
All the previously created objects will have the
previous value.
function A() { ... }
function B() { ... }
let a = new A;
function Person(){ let b = new B;
[Link] = "Elon Musk" alert( a == b ); // true
}
Solution :
[Link] = 25;
const person1 = new Person(); let obj = {};
function A() { return obj; }
[Link] = {age: 52} function B() { return obj; }
const person2 = new Person(); alert( new A() == new B() ); // true

[Link]([Link]); //25
Yes, it’s possible. If a function returns an object then new
[Link](person2 age); //52
returns it instead of this . So they can, for instance, return
the same externally defined object obj :
Return from constructors
Que. Create a constructor function Calculator
- Usually, constructors do not have a return function Calculator() {
statement [Link] = function() {
- Their task is to write all necessary stuff into this , this.a = +prompt('a?', 0);
and it automatically becomes the result. But if this.b = +prompt('b?', 0);
there is a return statement, then the rule is simple };
1. return with an object returns that object, [Link] = function() {
2. In all other cases this is returned. return this.a + this.b;
};
function BigUser() { [Link] = function() {
[Link] = "John"; return this.a * this.b;
return { name: "Godzilla" }; };
// <-- returns an object }
} let calculator = new Calculator();
alert( new BigUser().name ); [Link]();
// Godzilla alert( "Sum=" + [Link]() );
alert( "Mul=" + [Link]() );
And here’s an example with an empty return

function SmallUser() {
[Link] = "John";
return; // finishes the execution,
returns this
// ...
}
alert( new SmallUser().name ); //
John

Omitting parentheses : we can omit parentheses after


new , if it has no arguments:
let user = new User;
let user = new User();

// Both are same

You might also like