Prototype Methods
Prototypes / Inheritance: Prototype Methods
What are prototype methods in JavaScript?
View Answer:
Is there a way to implement prototypal inheritance without calling proto accessor property (deprecated) in JavaScript?
View Answer:
let parent = {
greet: function() {
console.log("Hello");
}
};
let child = Object.create(parent);
child.greet(); // Outputs: "Hello"
Can you explain the function the Object.create(obj) method in JavaScript?
View Answer:
Syntax: Object.create(proto, [descriptors]);
Absolutely, here's a simple example:
let animal = {
species: "animal",
describe: function() {
return `This is a ${this.species}`;
}
};
let dog = Object.create(animal);
dog.species = "dog";
console.log(dog.describe()); // Outputs: "This is a dog"
Object.create(animal)
creates a new object dog
with animal
as its prototype.
What is the function of the Object.getPrototypeOf() method in JavaScript?
View Answer:
Syntax: Object.getPrototypeOf(obj);
const prototype1 = {};
const object1 = Object.create(prototype1);
console.log(Object.getPrototypeOf(object1) === prototype1);
// expected output: true
What is the function of the Object.setPrototypeOf(obj, proto) method in JavaScript?
View Answer:
Syntax: Object.setPrototypeOf(obj, proto);
According to the MDN, its advised to use Object.create(obj) instead of this method.
Why was __proto__
replaced by the functions getPrototypeOf / setPrototypeOf?
View Answer:
If you care about performance, you should avoid setting the [[Prototype]] of an object. Instead, create a new object with the desired [[Prototype]] using Object.create() instead of Object.setPrototypeOf().
How do prototype and a regular methods differ in an object?
View Answer:
// Regular method
function Car(make, model) {
this.make = make;
this.model = model;
this.display = function() {
return this.make + ' ' + this.model;
}
}
var myCar = new Car("Toyota", "Corolla");
console.log(myCar.display()); // Toyota Corolla
// Prototype method
function Bike(make, model) {
this.make = make;
this.model = model;
}
Bike.prototype.display = function() {
return this.make + ' ' + this.model;
}
var myBike = new Bike("Yamaha", "FZ");
console.log(myBike.display()); // Yamaha FZ
In the first case, each new Car object will have its own display
method. In the second, all Bike objects share the same display
method.
How do prototype methods help with memory management in JavaScript applications?
View Answer:
How do you add a prototype method to an existing object constructor?
View Answer:
Object.defineProperty(Constructor.prototype, 'newMethod', {
value: function() {
// Method body
},
writable: true,
configurable: true,
enumerable: false
});
This approach provides better control over method properties.
What is method sharing in JavaScript?
View Answer:
What is method shadowing in JavaScript?
View Answer:
function Vehicle() {
}
Vehicle.prototype.drive = function() {
console.log("Vehicle is driving");
};
function Car() {
}
Car.prototype = Object.create(Vehicle.prototype); // Car inherits from Vehicle
var myCar = new Car();
myCar.drive(); // Output: "Vehicle is driving"
// Now let's shadow the drive method
myCar.drive = function() {
console.log("Car is driving");
};
myCar.drive(); // Output: "Car is driving"
In this example, myCar
initially uses the drive
method from the Vehicle
prototype. After we define drive
directly on myCar
, it shadows (or overrides) the prototype method. Now, when we call myCar.drive()
, it uses the shadowed method and outputs "Car is driving".
What are some common performance considerations when using prototype methods?
View Answer:
While using prototype methods is generally good for memory efficiency since they're shared among all instances, there are considerations around lookup time and shadowing:
function Car(make, model) {
this.make = make;
this.model = model;
}
Car.prototype.display = function() { // Prototypical method
return this.make + ' ' + this.model;
}
let car1 = new Car("Toyota", "Corolla");
let car2 = new Car("Honda", "Civic");
console.time('Prototype Method');
console.log(car1.display()); // Looks up the chain to find display method on prototype
console.timeEnd('Prototype Method');
console.time('Shadowed Method');
car2.display = function() { // Shadows prototype's method; closer in scope
return this.make + ' ' + this.model;
}
console.log(car2.display()); // Finds method on the object itself
console.timeEnd('Shadowed Method');
In this example, we create a Car
constructor function with a prototype method display
. For car1
, when we call display
, JavaScript has to look up the prototype chain to find the method which can be slightly slower than calling a method defined directly on the object. For car2
, we shadow the prototype method with an own method. This can be faster, as shown by the timing logs, but it defeats the purpose of using prototype methods for memory efficiency.
How do ES6 classes relate to the concept of prototypes and prototype methods in JavaScript?
View Answer:
Here's a comparison between ES6 classes and constructor functions with prototype methods.
Using ES6 classes:
class Car {
constructor(make, model) {
this.make = make;
this.model = model;
}
display() {
return this.make + ' ' + this.model;
}
}
let myCar = new Car("Toyota", "Corolla");
console.log(myCar.display()); // Toyota Corolla
Equivalent code using constructor functions and prototype methods:
function Car(make, model) {
this.make = make;
this.model = model;
}
Car.prototype.display = function() {
return this.make + ' ' + this.model;
}
let myCar = new Car("Toyota", "Corolla");
console.log(myCar.display()); // Toyota Corolla
In both cases, the display
method behaves as a prototype method, shared among all instances of Car
. The ES6 class syntax is cleaner and more intuitive, but under the hood, it's still using JavaScript's prototype system.
Can you explain the purpose of Object.create() and how it is related to prototypes?
View Answer:
let animal = {
type: 'Animal',
describe() {
return `Type: ${this.type}`;
}
};
let dog = Object.create(animal);
dog.type = 'Dog';
console.log(dog.describe()); // "Type: Dog"
In this example, Object.create(animal)
creates a new object with animal
as its prototype. The new dog
object has access to the describe
method via prototype inheritance. When we change dog.type
to 'Dog'
, the describe
method reflects that change.
Can you name the five primitive wrapper objects?
View Answer:
function Car(make, model) {
this.make = make;
this.model = model;
}
Car.prototype.display = function() {
return this.make + ' ' + this.model;
}
let myCar = new Car("Toyota", "Corolla");
console.log('display' in myCar); // true
console.log(myCar.hasOwnProperty('display')); // false
In this code, 'display' in myCar
checks if the display
method exists anywhere in the prototype chain of myCar
(returns true
). On the other hand, myCar.hasOwnProperty('display')
only checks if display
is a direct property of myCar
, not in its prototype (returns false
).
Why is it recommended to put methods on the prototype, and not in the constructor?
View Answer:
Sure, here's an example illustrating why it's better to put methods on the prototype:
// Bad practice: Method in constructor
function Car1(make, model) {
this.make = make;
this.model = model;
this.display = function() {
return this.make + ' ' + this.model;
};
}
// Good practice: Method on prototype
function Car2(make, model) {
this.make = make;
this.model = model;
}
Car2.prototype.display = function() {
return this.make + ' ' + this.model;
};
let car1a = new Car1("Toyota", "Corolla");
let car1b = new Car1("Honda", "Civic");
let car2a = new Car2("Toyota", "Corolla");
let car2b = new Car2("Honda", "Civic");
console.log(car1a.display === car1b.display); // false
console.log(car2a.display === car2b.display); // true
In this code, Car1
defines the display
method within the constructor, meaning every instance of Car1
gets its own copy of display
. This is inefficient memory-wise, as shown by the false
output of the comparison car1a.display === car1b.display
.
In contrast, Car2
defines display
on its prototype, so all instances of Car2
share the same method, saving memory. This is confirmed by the true
output of the comparison car2a.display === car2b.display
.
Can we modify built-in/native prototype methods in JavaScript?
View Answer:
How can you check if a property is directly on an object or its prototype?
View Answer:
function Car(make, model) {
this.make = make;
this.model = model;
}
Car.prototype.display = function() {
return this.make + ' ' + this.model;
}
let myCar = new Car("Toyota", "Corolla");
// Check if property is directly on object
console.log(myCar.hasOwnProperty('make')); // true
// Check if property is on prototype
console.log(myCar.hasOwnProperty('display')); // false
console.log('display' in myCar); // true
In this code, hasOwnProperty
checks if the property is directly on the object (returns true
for make
), while the in
operator checks whether the property is on the object or its prototype (returns true
for display
).
How do you access an object's prototype in JavaScript?
View Answer:
function Car(make, model) {
this.make = make;
this.model = model;
}
Car.prototype.display = function() {
return this.make + ' ' + this.model;
}
let myCar = new Car("Toyota", "Corolla");
let carPrototype = Object.getPrototypeOf(myCar);
console.log(carPrototype); // { display: [Function: display], constructor: [Function: Car] }
In this code, Object.getPrototypeOf(myCar)
returns the prototype of the myCar
object, which includes the display
method and constructor
property.
How do you add a method to an object's prototype?
View Answer:
You can add a method to an object's prototype by simply assigning it to the prototype of the constructor function.
Constructor.prototype.newMethod = function() {
// Method body
};
This makes newMethod
available to all instances of Constructor
.
How do you create an object without a prototype in JavaScript?
View Answer:
let obj = Object.create(null);
This creates obj
with no prototype.
Can you add new methods to existing JavaScript objects?
View Answer:
let obj = {
prop1: 'property 1'
};
// Add a new method
obj.newMethod = function() {
return 'This is a new method!';
}
console.log(obj.newMethod()); // "This is a new method!"
In this code, obj
is an existing object with a property prop1
. We then add a new method newMethod
to obj
by direct assignment. When we call obj.newMethod()
, it executes the newly added method and outputs "This is a new method!".