prototype inheritance is wrong - javascript

I created a person constructor and I take a firstname = fn, and lastname = ln, and dateofbirth = dob.
That Code is :
function Person(fn, ln, dob){
this.fn = fn;
this.ln = ln;
this.dob = new Date(dob);
}
and also I added prototype
Person.prototype.calcAge = function(){
const diff = Date.now() - this.dob.getTime();
const age = new Date(diff);
return Math.abs(age.getUTCFullYear() - 1970);
}
This is my first Person constructor.
and second constructor i am taken as a customer constructor and that code is :
function Customer(fn,ln,phone,membership){
Person.call(this,fn,ln);
this.phone = phone;
this.membership = membership;
}
And I am inheriting prototype from person to customer
//Inheriting Person Prototype
Customer.prototype = Object.create(Person.prototype);
// Making Customer Prototype
Customer.prototype.constructor = Customer;
And i am console logging :
const Customer1 = new Customer('Sairam', 'Gudiputis', '790-139-7848', 'Premium');
console.log(Customer1)
but in console i am getting invalid date of birth that i am not used in customer..
function Person(fn, ln, dob){
this.fn = fn;
this.ln = ln;
this.dob = new Date(dob);
}
Person.prototype.calcAge = function(){
const diff = Date.now() - this.dob.getTime();
const age = new Date(diff);
return Math.abs(age.getUTCFullYear() - 1970);
}
function Customer(fn,ln,phone,membership){
Person.call(this,fn,ln);
this.phone = phone;
this.membership = membership;
}
//Inheriting Person Prototype
Customer.prototype = Object.create(Person.prototype);
// Making Customer Prototype
Customer.prototype.constructor = Customer;
const Customer1 = new Customer('Sairam', 'Gudiputis', '790-139-7848', 'Premium');
console.log(Customer1)

If you don't want dob in Customer, add:
if (!(this instanceof Customer)) {
this.dob = new Date(dob);
}
in Person constructor:
function Person(fn, ln, dob){
this.fn = fn;
this.ln = ln;
if (!(this instanceof Customer)) {
this.dob = new Date(dob);
}
}
Person.prototype.calcAge = function(){
const diff = Date.now() - this.dob.getTime();
const age = new Date(diff);
return Math.abs(age.getUTCFullYear() - 1970);
}
function Customer(fn,ln,phone,membership){
Person.call(this,fn,ln);
this.phone = phone;
this.membership = membership;
}
//Inheriting Person Prototype
Customer.prototype = Object.create(Person.prototype);
// Making Customer Prototype
Customer.prototype.constructor = Customer;
const Customer1 = new Customer('Sairam', 'Gudiputis', '790-139-7848', 'Premium');
console.log(Customer1)

Related

Difference between two function placements

What would be the difference between the following two ways of attaching a method(?) to a parent function:
var Person = function(first, last) {
this.first = first;
this.last = last;
};
Person.prototype.personMethod = function() {
// ...
};
And:
var Person = function(first, last) {
this.first = first;
this.last = last;
this.personMethod = function() {
// ...
};
}
In the first approach, the method is put onto the prototype. Every instance will share the same personMethod because every instance inherits from Person.prototype.
var Person = function(first, last) {
this.first = first;
this.last = last;
};
Person.prototype.personMethod = function() {
// ...
};
const p1 = new Person();
const p2 = new Person();
console.log(p1.personMethod === p2.personMethod);
console.log(p1.hasOwnProperty('personMethod'));
console.log(Object.getPrototypeOf(p1).hasOwnProperty('personMethod'));
console.log(Object.getPrototypeOf(p1) === Person.prototype);
In the second approach, every instance has its own separate method, and it's not on the prototype.
var Person = function(first, last) {
this.first = first;
this.last = last;
this.personMethod = function() {
// ...
};
}
const p1 = new Person();
const p2 = new Person();
console.log(p1.personMethod === p2.personMethod);
console.log(p1.hasOwnProperty('personMethod'));
In modern JavaScript, it's usually preferable to use a class instead, which puts methods onto the prototype.
class Person {
constructor(first, last) {
this.first = first;
this.last = last;
}
personMethod(){}
};
const p1 = new Person();
const p2 = new Person();
console.log(p1.personMethod === p2.personMethod);
console.log(p1.hasOwnProperty('personMethod'));
console.log(Object.getPrototypeOf(p1).hasOwnProperty('personMethod'));
console.log(Object.getPrototypeOf(p1) === Person.prototype);
Assigning the function inside the constructor can be useful if you want the function to close over a variable only scoped to the constructor, which wouldn't work for methods if the variable isn't set to the instance.
var Person = function(first, last) {
// say we don't want to assign these arguments to the instance
// but we can still do
this.getName = () => first + ' ' + last;
}
const p = new Person('John', 'Doe');
console.log(p.getName());

accessing a method from function constructor

How can the retirementAge method access the value of calculateAge method in the same Person function constructor?
var Person = function(name, job, yearOfBirth) {
this.name = name;
this.yearOfBirth = yearOfBirth;
this.calculateAge = function() {
console.log(2018 - this.yearOfBirth)
};
this.retirementAge = function(el) {
console.log(66 - this.calculateAge)
}
}
var john = new Person('John', 'teacher', 1998);
john.retirementAge(john.calculateAge());
You need to return a value from this.calculateAge if you want to get the value by calling it. When you do that, you can just call the function this.calculateAge() and it should work as expected:
let Person = function(name, job, yearOfBirth) {
this.name = name;
this.yearOfBirth = yearOfBirth;
this.calculateAge = function() {
return 2018 - this.yearOfBirth
};
this.retirementAge = function(el) {
return 66 - this.calculateAge()
}
}
var john = new Person('John', 'teacher', 1998);
console.log("Age:", john.calculateAge())
console.log("Years to retirement:", john.retirementAge())
It can access it, you just forgot the parentheses and return the value.
var Person = function(name, job, yearOfBirth) {
this.name = name
this.yearOfBirth = yearOfBirth
this.calculateAge = function() {
return 2018 - this.yearOfBirth
};
this.retirementAge = function(el) {
return 66 - this.calculateAge()
}
}
var john = new Person('John', 'teacher', 1998);
console.log(john.retirementAge(john.calculateAge()))

Underfined in a prototype

I changed the Human Prototype and now I am still getting undefined when I check a property:
function Human() {
this.name = "Default Human";
this.age = "Default Age";
this.height = 122;
}
function humanExtend() {
this.address = "Updated Address Sun";
this.power = "ShowBoat";
}
var banmeet = new Human();
console.log(banmeet.name);
Human.prototype = humanExtend;
var bradPitt = new Human();
console.log(bradPitt.power);
But I am getting an undefined for bradPitt.power..
Why is that?
you should have been assigned instance of HumanExtend as below -
function Human() {
this.name = "Default Human";
this.age = "Default Age";
this.height = 122;
}
function humanExtend() {
this.address = "Updated Address Sun";
this.power = "ShowBoat";
}
var banmeet = new Human();
console.log(banmeet.name);
//Assign instance of HumanExtend here
Human.prototype = new humanExtend();
var bradPitt = new Human();
console.log(bradPitt.power);

Javascript Classical Inheritance calling parent

I want to call the super method in an extended javascript 'class' by applying classical inheritance.
function Person(name, age) {
this._name = name;
this._age = age;
}
Person.prototype.exposeInfo = function() {
alert(this._name + ' - ' + this._age);
}
function Employee(name, age) {
this.parent.constructor.call(this, name, age);
}
Employee.prototype.exposeInfo = function() {
alert('Call employee');
this.parent.exposeInfo();
}
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.parent = Person.prototype;
var p1 = new Person('John Doe', 30);
p1.exposeInfo();
var p2 = new Employee('John Foobar (empl.)', 35);
p2.exposeInfo();
JS Fiddle
The problem is that the method is not being called in the extended class, but only in the parent (Person).
That's because the overriding exposeInfo is being attached to the former prototype object, which is then replaced:
Employee.prototype = Object.create(Person.prototype);
You'll want to reverse the order, attaching methods after creating the prototype:
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.parent = Person.prototype;
Employee.prototype.exposeInfo = function() {
// ...
}
You'll also need to use .call() or .apply() with exposeInfo as you did with the constructor:
Employee.prototype.exposeInfo = function() {
alert('Call employee');
this.parent.exposeInfo.apply(this, arguments);
}
Otherwise, the value of this will be determined by the last member operator:
// so, calling:
this.parent.exposeInfo();
// is equivalent to:
alert(this.parent._name + ' - ' + this.parent._age);
// ...
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.parent = Person.prototype;
Employee.prototype.exposeInfo = function() {
this.parent.exposeInfo.apply(this, arguments);
// ...
}
It's not going to work.
Example:
// ...
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.parent = Person.prototype;
Employee.prototype.exposeInfo = function() {
this.parent.exposeInfo.apply(this, arguments);
// ...
}
ParttimeEmployee = Object.create(Employee.prototype);
ParttimeEmployee.prototype.constructor = ParttimeEmployee;
ParttimeEmployee.prototype.parent = Employee.prototype;
ParttimeEmployee.prototype.exposeInfo = function() {
this.parent.exposeInfo.apply(this, arguments);
// ...
}
var p1 = new Person('Jack', 30);
p1.exposeInfo(); // ok
var p2 = new Employee('Jane', 25);
p2.exposeInfo(); // ok
var p3 = new ParttimeEmployee('John', 20);
p3.exposeInfo(); // infinite recursion !!!
Correct version:
// Person
function Person(name, age) {
this._name = name;
this._age = age;
}
Person.prototype.exposeInfo = function() {
alert(this._name + ' - ' + this._age);
}
// Employee
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.parent = Person.prototype; // <--
Employee.prototype.exposeInfo = function() {
Employee.parent.exposeInfo.apply(this, arguments); // <--
// ...
}
// ParttimeEmployee
ParttimeEmployee = Object.create(Employee.prototype);
ParttimeEmployee.prototype.constructor = ParttimeEmployee;
ParttimeEmployee.parent = Employee.prototype; // <--
ParttimeEmployee.prototype.exposeInfo = function() {
ParttimeEmployee.parent.exposeInfo.apply(this, arguments); // <--
// ...
}
var p1 = new Person('Jack', 30);
p1.exposeInfo(); // ok
var p2 = new Employee('Jane', 25);
p2.exposeInfo(); // ok
var p3 = new ParttimeEmployee('John', 20);
p3.exposeInfo(); // ok

Why does one need to call the function in an Object (constructor) in order to use a method that uses .this (JavaScript)

var setAge = function (newAge) {
this.age = newAge;
};
// now we make bob
var bob = new Object();
bob.age = 30;
bob.setAge = setAge;
bob.setAge(50);
console.log(bob.age);
This works, but when I try to do this
var setAge = function (newAge) {
this.age = newAge;
};
var bob = new Object();
bob.age = 30;
bob.setAge(50);
console.log(bob.age);
it returns "bob.setAge() is not a function" in the compiler?
The second example doesn't work because you haven't defined setAge, as you have here bob.setAge = setAge;. You created a new Object(), not a new custom-defined object. You're using sorta hybrid code... this is how you could do "classes"
var MyObject = function (age) {
this.age = age;
var that = this;
this.setAge = function (newAge) {
that.age = newAge;
}
};
var foo = new MyObject(10);
alert(foo.age);
foo.setAge(20);
alert(foo.age);
You have created an object 'Bob', but that object does not have the method 'setAge' until you assign it.
You may want to look into doing something like this in your design:
function Person(){
this.age = 30;
this.setAge = function(age){
this.age = age;
return this;
}
}
var bob = new Person;
bob.setAge(20);
console.log(bob.age);

Categories

Resources