How to put functionality into abstract function in JavaScript - javascript

I am trying to make it so that I can have some methods in a JavaScript object be inheritable by a child class, but I don't want to allow the parent class to be instantiated. Here is some code that I wrote to illustrate this:
/**
* Shows how basic abstraction works with JavaScript
*/
//Define the person object with a first name, last name, and an age
function Person(firstName, lastName, age) {
//Make it so that this object cannot be instantiated by identifying its constructor
if(this.constructor === Person) {
throw new Error("Can't instantiate an abstract class of type Person!");
}
//Assign instance variables
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
//Create simple get methods
this.getName = function(){
return this.firstName + " " + this.lastName;
}
this.getFirstName = function() {
return this.firstName;
}
this.getLastName = function() {
return this.lastName;
}
this.getAge = function() {
return this.age;
}
}
//Define the student constructor
function Student(firstName, lastName, age, subject) {
//Assign the instance variables including the new subject variable
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.subject = subject;
//Add a new function to get the subject from Student
this.getSubject = function() {
return this.subject;
}
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
//Testing the inheritance
var joe = new Student("Joe", "Shmo", 33, "Computer Science");
console.log("First Name: " + joe.getFirstName()); //The getFirstName() function is defined in the superclass
console.log("Subject: " + joe.getSubject()); //The getSubject() function is defined in the subclass
With this code I get an error when trying to call getFirstName on the Student object joe. It seems that it would be very useful to have getFirstName be inheritable by the subclass.
I really want to be able to define the getName function in the parent class so that I can then just have that functionality inherited by the subclasses such as Student. Is there any way to do that? I would really appreciate any help!

You need to define your methods in the Person prototype, not in an instance of Person. That way they will be copied when you do Object.create(Person.prototype):
/**
* Shows how basic abstraction works with JavaScript
*/
//Define the person object with a first name, last name, and an age
function Person(firstName, lastName, age) {
//Make it so that this object cannot be instantiated by identifying its constructor
if(this.constructor === Person) {
throw new Error("Can't instantiate an abstract class of type Person!");
}
//Assign instance variables
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
Person.prototype.getName = function(){
return this.firstName + " " + this.lastName;
}
Person.prototype.getFirstName = function() {
return this.firstName;
}
Person.prototype.getLastName = function() {
return this.lastName;
}
Person.prototype.getAge = function() {
return this.age;
}
//Define the student constructor
function Student(firstName, lastName, age, subject) {
//Assign the instance variables including the new subject variable
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.subject = subject;
//Add a new function to get the subject from Student
this.getSubject = function() {
return this.subject;
}
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
//Testing the inheritance
var joe = new Student("Joe", "Shmo", 33, "Computer Science");
console.log("First Name: " + joe.getFirstName()); //The getFirstName() function is defined in the superclass
console.log("Subject: " + joe.getSubject()); //The getSubject() function is defined in the subclass

Related

Getting undefined value while inheritance in JavaScript OOPS

Getting undefined value while inheritance in JavaScript OOPS. Student object doesn't inheritance the Person Object
function person(name, age) {
this.name = name;
this.age = age;
this.say = function() {
return this.name + " says Hi..";
}
}
var p1 = new person("Mahesh", "33");
var p2 = new person("Girish", "30");
console.log(p1.say());
console.log(p2.say());
// Inheritance
function student() {};
student.prototype = new person();
var stud1 = new student("Nakktu", "32");
console.log(stud1.say());
You still have to call your super class from within the constructor of the sub class. See this MDN link for more information.
function person(name, age) {
// When no name is provided, throw an error.
if (name === undefined) {
throw 'Unable to create instance of person. Name is required.';
}
this.name = name;
this.age = age;
this.say = function() {
return this.name + " says Hi..";
}
}
var p1 = new person("Mahesh", "33");
var p2 = new person("Girish", "30");
console.log(p1.say());
console.log(p2.say());
// Inheritance
function student(name, age) {
// You need to call your super class.
person.call(this, name, age);
};
// Don't use "new person()", your code will stop working when person() throws
// an error when the 'name' param is required and missing.
student.prototype = Object.create(person.prototype);
var stud1 = new student("Nakktu", "32");
console.log(stud1.say());

Creating a Class Method

function Person(firstName = "John", lastName = 'Doe', age = 0, gender = 'Male') {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.gender = gender;
this.sayFullName = function() {
return this.firstName + " " + this.lastName
};
}
Person.prototype.greetExtraTerrestrials = function(raceName) {
return `Welcome to Planet Earth ${raceName}`;
};
What is wrong with this code? Doesn't it create a class method called greetExtraTerrestrials?
Don't place that function on prototype, place that on Class itself like
Person.greetExtraTerrestrials = function(raceName) {
return `Welcome to Planet Earth ${raceName}`;
};
and call it like
Person.greetExtraTerrestrials('ABC');
You can do both! The difference in
class Person(...) {
...
}
Person.myFunction = function(val) { // This is a public function
return val;
}
Person.prototype.myFunction = function(val) { // This is a private function
return val;
}
is how you access it.
Access the public function :
var r = Person.myFunction("Hello!");
console.log(r);
Access the private function:
var person1 = new Person(...);
var r = person1.myFunction("Hello!");
console.log(r);
See also this question.
Actually it works, but firstly you need to create an instance of Person to be able call its methods. For example:
var john = new Person("John");
console.log(john.greetExtraTerrestrials("predator"));

Javascript call the base class constructor

Person is base class and Emp inherits from Person. I am trying to use name, location properties of Person in Emp.
function Person(name, location){
this.name = name;
this.location = location;
}
Person.prototype.getName = function(){
return 'Name: ' + this.name;
}
function Emp(id, name, location){
this.id = id;
Person.call(this, name);
Person.call(this, location);
}
Emp.prototype = Object.create(Person.prototype);
var e1 = new Emp(1, 'John', 'London');
e1.id // 1
e1.name // 'London'
e1.location //undefined
What is causing this error and why is name taking value of London?
Why are you calling the constructor twice with a single argument?
function Emp(id, name, location){
this.id = id;
Person.call(this, name, location);
}

Add new property to Prototype using contructor argument

If I have:
function Person(name, age){
this.name = name;
this.whoIs = function(){
alert('I am ' + this.name);
}
}
var john = new Person('John');
john.whoIs();
all will work and I will get a nice alert with: "I am John".
Is there a way to add method to the prototype after the constructor and that will have access to the constructor arguments?
Something like:
function Person(name, age){
this.name = name;
this.whoIs = function(){
alert('I am ' + this.name);
}
}
Person.prototype.age = Person.arguments[1];
var john = new Person('John', 20);
john.age; // would give 20
Is there a way to do this? Ie: being able to add a property or method to a prototype that will have access to the arguments when a new instance is created?
It doesn't make sense to have a dynamic property in the prototype. See the prototype as the blueprint of your object.
You can do this:
function Person(name, age){
this.name = name;
this.whoIs = function(){
alert('I am ' + this.name);
}
this.age = age;
}
var john = new Person('John', 20);
john.age; // would give 20
Also, the whoIs function is added for each Person object. You can add it to the prototype instead:
function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype.whoIs = function () {
return 'I am ' + this.name;
}
var john = new Person('John', 20);
john.whoIs(); // would give "I am John"

How to do prototypal inheritance in JavaScript?

I've tried several ways but I couldn't do it.
On the next example I want the Soldier gets all properties of Person, and allowing to add more properties. How to do it correctly?
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.hi = function (message) {
console.log(message + "!!!");
};
var Soldier = new(Person); // it is not the way to do it
Soldier.prototype.good_hi = function (message) {
console.log("Sir! " + message + ", sir!");
};
You don't have a Soldier constructor. You need to make that first. Then you'd apply the Person constructor to new Soldier instances.
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.hi = function (message) {
console.log(message + "!!!");
};
function Soldier(name, age) {
Person.apply(this, arguments);
}
Soldier.prototype = Object.create(Person.prototype); // is better
Soldier.prototype.constructor = Soldier;
Soldier.prototype.good_hi = function (message) {
console.log("Sir! " + message + ", sir!");
};
Then use it like this:
var s = new Soldier("Bob", 23);
s.good_hi("Hello");
DEMO: http://jsfiddle.net/3kGGA/

Categories

Resources