5

Please help me in understanding this piece of code.

var person = {
    'first-name': 'FirstName',
    'last-name': 'LastName',
    'gender': 'Male'
};

var anotherPerson = new Object(person);
anotherPerson.desig = 'Designation';

console.log('Another person designation: ' + anotherPerson['desig'] + ', person designation: ' + person['desig']);

I expected the output to be Another person designation: Designation, person designation: undefined but to my surprise I found it to be `Another person designation: Designation, person designation: Designation.

According to me anotherPerson is extending person object and properties set to anotherPerson should not be visible to person object. Am I wrong here? Or is that both the object are pointing to the same location?

[EDIT]

Now there are even more surprises.

I added the following code to the above.

person.place = 'XYZ';
console.log(person['place'] + ', ' + anotherPerson['place']); // Expected: XYZ, undefined. Result: XYZ, XYZ.

Based on the above result and answers I thought that both objects are referring to the same location. Now I added few more lines

person = undefined;
console.log(anotherPerson['place']) //Expected: error, Result: XYZ. ??!?!?
console.log(person['place']) // Expected: error, Result: error.

Can someone throw some light on me to understand this? Thanks for your help in advance

Anji
  • 725
  • 1
  • 9
  • 27

5 Answers5

2

You are not doing extending or any kind of inheritance.

This comes closer:

var Person = function () {
    this["first-name"] = 'FirstName',
    this["last-name"] = 'LastName',
    this["gender"] = 'Male'
};

var person = new Person();
var anotherPerson = new Person();

Now you have two seperate instances of Person. If you also want anotherPerson to be a subclass ..

var Person = function () {
    this["first-name"] = 'FirstName',
    this["last-name"] = 'LastName',
    this["gender"] = 'Male'
};

var AnotherPerson = function () {
    this.desig = "Designation";
}
AnotherPerson.prototype = new Person();   // inherit from Person
AnotherPerson.prototype.constructor = AnotherPerson;  // reset constructor

var person = new Person();
var anotherPerson = new AnotherPerson();

console.log(person.desig); // undefined
console.log(anotherPerson.desig); // Designation
Halcyon
  • 57,230
  • 10
  • 89
  • 128
  • 1
    I had just finished writing up the same first block of code ;) +1 – bhamlin Apr 27 '12 at 20:05
  • @Frits Thanks for your reply. I get the code you have explained. So when we do `new Object(person)` is it that `anotherPerson` is referring to the same location? I tried adding a new property to `person` and `anotherPerson` was able to read that new property successfully. Why is it so? – Anji Apr 27 '12 at 20:08
  • I'm not entirely sure what `new Object(person)` does .. maybe it just resolves to `person`? I do know that it doesn't magically extend from `person` :P – Halcyon Apr 27 '12 at 20:09
  • @FritsvanCampen Hmm very weird. I some times doubts whether I really know javascript when these kind of results are shown – Anji Apr 27 '12 at 20:24
  • I don't like the way native prototypes work in JavaScript, supposedly it has a memory leak too! Find a framework to do inheritance for you. – Halcyon Apr 27 '12 at 20:26
0

Not really a solution, but for me, this is how I clone an object in such a way that I can extend it:

var anotherPerson = new Object();
for(i in person) anotherPerson[i]=person[i];

Instead of

var anotherPerson = new Object(person);

It then works as expected.

DanRedux
  • 9,119
  • 6
  • 23
  • 41
  • May I know what exactly happens when we do `var anotherPerson = new Object(person)`? – Anji Apr 27 '12 at 20:05
0

The Object function (note: the same, even more startlingly if you're not familiar with what's going on, applies to calling new Object(...)) doesn't create a new object if it's passed something that isn't of boolean, number or string type; it just returns the already existing object. (Rationale: because it's already an Object. Almost everything is an Object in Javascript.)

Therefore, anotherPerson is the exact same object as person, so when you modify it you modify person too.

I do not claim that this is sensible behaviour; but it is what the language spec defines.

Gareth McCaughan
  • 19,888
  • 1
  • 41
  • 62
0

If you want to extend/inherit an object then you can do

var person = {
    'first-name': 'FirstName',
    'last-name': 'LastName',
    'gender': 'Male'
};
if (typeof Object.create !== 'function')
{
    Object.create=function(o)
    {
        function F(){}
        F.prototype=o;
        return new F();
    }
}
var newPerson=Object.create(person);
newPerson.age=25;
newPerson.gender="Female";

console.log(person.gender); // Male
console.log(newPerson.gender); // Female

console.log(person.age); // undefined
console.log(newPerson.age); // 25

Fiddle

Reference: Prototypal Inheritance in JavaScript

The Alpha
  • 143,660
  • 29
  • 287
  • 307
0

a general solution for inheritance implementation in JavaScript

function inherits(base, extension)
{
   for ( var property in base )
   {
      try
      {
         extension[property] = base[property];
      }
      catch( warning ){}
   }
}
Abdennour TOUMI
  • 87,526
  • 38
  • 249
  • 254