3

For the below code

   // Parent constructor function
    function Person(name, age, gender){
        this.name = name;
        this.age = age;
        this.gender = gender;
    };

    //Child constructor function
    function Employee(name, age, gender, empId){
        // Is this the right way ?
        Person.call(this, name, age, gender);
        this.empId = empId;
    };

    //Inherit the properties from Parent
    Employee.prototype = Object.create(Person.prototype);

    // Fix the inherited constructor
    Employee.prototype.constructor = Employee;

    john = new Employee('John', 21, 'male', 213);

    console.log(john.hasOwnProperty('empId')); // true
    
    // Shoudn't this be false
    console.log(john.hasOwnProperty('name')); // true
    
    // Shouldn't the above statement work similar to this one
    console.log(john.hasOwnProperty('toString')); // false
    

My question is how do we pass name, age, gender to Person constructor in ES5?

What is the right way to do it ?

Update:

If the above is right then why is console.log(john.hasOwnProperty('name')); // true. Should'nt this be false ?

Flying Gambit
  • 1,238
  • 1
  • 15
  • 32
  • One of my collegue mentioned that it should have been `Person.prototype.name = this.name;` instead of `Person.call(this, name, age, gender);` Is this right ? – Flying Gambit May 24 '18 at 09:18
  • 1
    Nope, unless you want all the employees share the same name. – Teemu May 24 '18 at 09:25
  • @Teemu Thanks that makes sense – Flying Gambit May 24 '18 at 09:31
  • @FlyingGambit That's a horrible idea. [Never change the prototype inside the constructor](https://stackoverflow.com/questions/28255957/assigning-prototype-methods-inside-the-constructor-function-why-not). – Bergi May 24 '18 at 09:54

3 Answers3

2

Yes, using Person.call(this, ...) is the right way.

However, if you want to use classes, consider using ES6 and ES6 classes, and compiling it with Babel or Closure Compiler for ES5 compatibility.

Babel may be also used as a part of browserify/webpack pipeline.

// Shoudn't this be false?
console.log(john.hasOwnProperty('name'));

hasOwnProperty behavior is exactly as expected. It is object-based, and you have just assigned some attributes to this object, right? While using prototypes gives nice illusion of classes and inheritance, there are no classes and no inheritance. There is prototype chaining, but Person.call(...) is just a normal function call.

One of my collegue mentioned that it should have been

Person.prototype.name = this.name;

instead of

Person.call(this, name, age, gender);

Is this right ?

Your colleague is partly right: you'd have to write Person.prototype.name = name to get hasOwnProperty('name') == false, but this would set the value for all objects with this prototype. That makes sense: it wouldn't be an own property, because it would be shared between many objects. Of course, it is not what you want to do. Name is definitely supposed to be own property of the Person object.

Frax
  • 5,015
  • 2
  • 17
  • 19
  • Hi, thanks for the answer, can you elaborate why `name` property is considered as its own property ? Shouldn't it behave like 'toString' ? – Flying Gambit May 24 '18 at 09:30
  • @Gambit added explanation. – Frax May 24 '18 at 09:51
  • @FlyingGambit It's not inherited, it's a property directly on that object. That `name` and `empId` were created in different functions doesn't matter - both constructors did initialise the *same* object. – Bergi May 24 '18 at 09:57
  • @Bergi I'd say even the word "initialize" is a bit of stretch here. There are no classes, so there is no initialization, at least not in a language-lawyer sense. Semantically, this is just a function call. – Frax May 24 '18 at 10:03
  • @Frax I don't know what exactly initialisation means in the languages where it has a lawyery meaning, but I think it's comparable to what I meant here. I just like the term as it neatly describes the creation of properties with their values on the object. – Bergi May 24 '18 at 11:08
  • @FlyingGambit, did my answer answer your question? If so, you could consider [marking it as accepted](https://stackoverflow.com/help/someone-answers). – Frax May 27 '18 at 17:02
1

The above code is the correct way to do inheritance and pass args to its parent. object.hasOwnProperty(property name) - method returns a boolean indicating whether the object has the specified property as its own property (as opposed to inheriting it). But, check that you're calling BaseClass.call(this) on SubClass's constructor, means that you're adding BaseClass properties and functions to SubClass instance, because this is instance of SubClass.

// Parent constructor function
    function Person(name, age, gender){
        this.name = name;
        this.age = age;
        this.gender = gender;
    };

    //Child constructor function
    function Employee(name, age, gender, empId){
        // Is this the right way ?
        Person.call(this, name, age, gender);
        this.empId = empId;
    };

    //Inherit the properties from Parent
    Employee.prototype = Object.create(Person.prototype);

    // Fix the inherited constructor
    Employee.prototype.constructor = Employee;

    john = new Employee('John', 21, 'male', 213);
    
    //it is returning the expected data, which we pass to parent
    console.log(john.age); //21
    
Jay
  • 338
  • 1
  • 5
0

Yes, the behavior above is correct. The created Employee object (john) will have the property name which is being inherited from the parent class.

Van
  • 636
  • 3
  • 14