0

When running the below code I am receiving a type error when passing my arguments. It seems I am unable to pass my JSON data as arguments to the Employee object.

This is the error I am receiving:

/home/ubuntu/test/tests/employee.js:4
     this.name = params['name'] || "";
                  ^
TypeError: Cannot read property 'name' of undefined

Below is the code:

//comment

var Employee = function (params) {
    this.name = params['name'] || "";
    this.dept = params['dept'] || "general";
}

function Manager () {
    this.reports = [];
}
Manager.prototype = new Employee;

function WorkerBee (params) {
    console.log("params "+params);
    this.base = Employee;
    this.base(params);
    //    this.projects = params['projs'] || [];                                                                                                                                      
}

WorkerBee.prototype = new Employee;

function Engineer (params) {
    this.base = WorkerBee;
    this.base(params);
    params['projs']="engineering";
    //    this.base(params['name'], "engineering", params['projs']);                                                                                                                  
    this.machine = params['mach'] || "";
}
Engineer.prototype = new WorkerBee;


var jane = new Engineer({'name': "Doe, Jane", 'projs':["navigator", "javascript"], 'mach':"belau"});
console.log(jane);

Any guidance would be appreciated to correct this example.

Val
  • 1,260
  • 5
  • 23
  • 39
  • 2
    I think the problem is with this (no params passed): `Manager.prototype = new Employee` – Bryan Downing Sep 03 '14 at 23:37
  • and `Engineer.prototype = new WorkerBee;` These are calling the constructors but you are not passing any arguments to either – Patrick Evans Sep 03 '14 at 23:38
  • I should be typing Manager.prototype = new Employee(params) when calling a new constructor? When I do that I get a reference error -> ReferenceError: params is not defined. The code works correctly when I use an ordered argument set per this site: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#Subclasses_and_inheritance. Just when I refactor the code to make it less dependent I start having issue passing the data around. – Val Sep 04 '14 at 00:29
  • Instead of `this.base(params)`, you need to do `this.base.call(base, params)`. –  Sep 04 '14 at 02:38

1 Answers1

1

That's exactly why you should not create a new instance of the parent when you want to establish inheritance: If the constructor expects an argument, what do you pass?

You should be using Object.create instead:

Child.prototype = Object.create(
  Parent.prototype,
  {constructor: {value: Child, configurable: true, writable: true}}
);

You also have to call the parent constructor as

Parent.call(this, arg1, arg2, ...);

inside the child constructor. While

this.base = WorkerBee;
this.base(params);

does work, it's a bit unconventional.


More info in: Benefits of using `Object.create` for inheritance

Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Vey well explained. Thank you for the response and information. All the bests. – Val Sep 04 '14 at 01:52
  • No, `this.base(params)` will *not* work. It would call the base constructor with no `this`. It is equivalent to `WorkerBee(params)`, which will call `WorkerBee` with no context. Needs to be `WorkerBee.call(this, params)` as you point out. –  Sep 04 '14 at 02:41
  • @torazaburo: No, If you have `foo.bar()` then `this` inside `bar` will refer to `foo`. Here it's like calling a method on `this`. As I said, it's unusual, but it works. – Felix Kling Sep 04 '14 at 02:43
  • Here is a site supporting @Felix's point regarding this keyword inside of Foo.bar(). Refer to the instance object section: http://blog.kevinchisholm.com/javascript/difference-between-object-literal-and-instance-object/ – Val Sep 04 '14 at 03:34