You want to 'inherit' from Person's prototype object:

var Person = function (name) {
    this.name = name;
    this.type = 'human';
};

Person.prototype.info = function () {
    console.log("Name:", this.name, "Type:", this.type);
};

var Robot = function (name) {
    Person.apply(this, arguments);
    this.type = 'robot';
};

Robot.prototype = Person.prototype;  // Set prototype to Person's
Robot.prototype.constructor = Robot; // Set constructor back to Robot

person = new Person("Bob");
robot = new Robot("Boutros");

person.info();
// Name: Bob Type: human

robot.info();
// Name: Boutros Type: robot

Simpler "prose-like" syntax with Object.create()

And the true prototypial nature of Javascript

*This example is updated for ES6 classes and TypeScript.

Firstly, Javascript is a prototypal language, not class-based. Its true nature is expressed in the prototypial form below, which you may come to see that is very simple, prose-like, yet powerful.

TLDR;

Javascript

const Person = { 
    name: 'Anonymous', // person has a name
    greet: function() { console.log(`Hi, I am ${this.name}.`) } 
} 
    
const jack = Object.create(Person)   // jack is a person
jack.name = 'Jack'                   // and has a name 'Jack'
jack.greet()                         // outputs "Hi, I am Jack."

TypeScript

In TypeScript, you will need to set up interfaces, which will be extended as you create descendents of the Person prototype. A mutation politeGreet shows an example of attaching new method on the descendent jack.

interface Person {
    name: string
    greet(): void
}

const Person =  {
    name:  'Anonymous',  
    greet() {
        console.log(`Hi, I am ${this.name}.`)
    }
}

interface jack extends Person {
    politeGreet: (title: 'Sir' | 'Mdm') => void
}

const jack: jack = Object.create(Person)
jack.name = 'Jack'
jack.politeGreet = function(title) {
    console.log(`Dear ${title}! I am ${this.name}.`)
}
jack.greet()  // "Hi, I am Jack."
jack.politeGreet('Sir') // "Dear Sir, I am Jack."

This absolves the sometimes convoluted constructor pattern. A new object inherits from the old one, but is able to have its own properties. If we attempt to obtain a member from the new object (#greet()) which the new object jack lacks, the old object Person will supply the member.

In Douglas Crockford's words: "Objects inherit from objects. What could be more object-oriented than that?"

You don't need constructors, no new instantiation. You simply create Objects and then extend or morph them.

This pattern also offers immutability (partial or full), and getters/setters.

Clean and clear. It's simplicity does not compromise features. Read on.

Creating an descendant/copy of Person prototype (technically more correct than class).

*Note: Below examples are in JS. To write in Typescript, just follow the example above to set up interfaces for typing.

const Skywalker = Object.create(Person)
Skywalker.lastName = 'Skywalker'
Skywalker.firstName = ''
Skywalker.type = 'human'
Skywalker.greet = function() { console.log(`Hi, my name is ${this.firstName} ${this.lastName} and I am a ${this.type}.`

const anakin = Object.create(Skywalker)
anakin.firstName = 'Anakin'
anakin.birthYear = '442 BBY'
anakin.gender = 'male' // you can attach new properties.
anakin.greet() // 'Hi, my name is Anakin Skywalker and I am a human.'

Person.isPrototypeOf(Skywalker) // outputs true
Person.isPrototypeOf(anakin) // outputs true
Skywalker.isPrototypeOf(anakin) // outputs true

If you feel less safe throwing away the constructors in-lieu of direct assignments, one common way is to attach a #create method:

Skywalker.create = function(firstName, gender, birthYear) {

    let skywalker = Object.create(Skywalker)

    Object.assign(skywalker, {
        firstName,
        birthYear,
        gender,
        lastName: 'Skywalker',
        type: 'human'
    })

    return skywalker
}

const anakin = Skywalker.create('Anakin', 'male', '442 BBY')

Branching the Person prototype to Robot

When you branch the Robot descendant from Person prototype, you won't affect Skywalker and anakin:

// create a `Robot` prototype by extending the `Person` prototype:
const Robot = Object.create(Person)
Robot.type = 'robot'

Attach methods unique to Robot

Robot.machineGreet = function() { 
    /*some function to convert strings to binary */ 
}

// Mutating the `Robot` object doesn't affect `Person` prototype and its descendants
anakin.machineGreet() // error

Person.isPrototypeOf(Robot) // outputs true
Robot.isPrototypeOf(Skywalker) // outputs false

In TypeScript you would also need to extend the Person interface:

interface Robot extends Person {
    machineGreet(): void
}
const Robot: Robot = Object.create(Person)
Robot.machineGreet = function() { console.log(101010) }

And You Can Have Mixins -- Because.. is Darth Vader a human or robot?

const darthVader = Object.create(anakin)
// for brevity, property assignments are skipped because you get the point by now.
Object.assign(darthVader, Robot)

Darth Vader gets the methods of Robot:

darthVader.greet() // inherited from `Person`, outputs "Hi, my name is Darth Vader..."
darthVader.machineGreet() // inherited from `Robot`, outputs 001010011010...

Along with other odd things:

console.log(darthVader.type) // outputs robot.
Robot.isPrototypeOf(darthVader) // returns false.
Person.isPrototypeOf(darthVader) // returns true.

Which elegantly reflects the "real-life" subjectivity:

"He's more machine now than man, twisted and evil." - Obi-Wan Kenobi

"I know there is good in you." - Luke Skywalker

Compare to the pre-ES6 "classical" equivalent:

function Person (firstName, lastName, birthYear, type) {
    this.firstName = firstName 
    this.lastName = lastName
    this.birthYear = birthYear
    this.type = type
}

// attaching methods
Person.prototype.name = function() { return firstName + ' ' + lastName }
Person.prototype.greet = function() { ... }
Person.prototype.age = function() { ... }

function Skywalker(firstName, birthYear) {
    Person.apply(this, [firstName, 'Skywalker', birthYear, 'human'])
}

// confusing re-pointing...
Skywalker.prototype = Person.prototype
Skywalker.prototype.constructor = Skywalker

const anakin = new Skywalker('Anakin', '442 BBY')

// #isPrototypeOf won't work
Person.isPrototypeOf(anakin) // returns false
Skywalker.isPrototypeOf(anakin) // returns false

ES6 Classes

Clunkier compared to using Objects, but code readability is okay:

class Person {
    constructor(firstName, lastName, birthYear, type) {
        this.firstName = firstName 
        this.lastName = lastName
        this.birthYear = birthYear
        this.type = type
    }
    name() { return this.firstName + ' ' + this.lastName }
    greet() { console.log('Hi, my name is ' + this.name() + ' and I am a ' + this.type + '.' ) }
}

class Skywalker extends Person {
    constructor(firstName, birthYear) {
        super(firstName, 'Skywalker', birthYear, 'human')
    }
}

const anakin = new Skywalker('Anakin', '442 BBY')

// prototype chain inheritance checking is partially fixed.
Person.isPrototypeOf(anakin) // returns false!
Skywalker.isPrototypeOf(anakin) // returns true

Further reading

Writability, Configurability and Free Getters and Setters!

For free getters and setters, or extra configuration, you can use Object.create()'s second argument a.k.a propertiesObject. It is also available in #Object.defineProperty, and #Object.defineProperties.

To illustrate its usefulness, suppose we want all Robot to be strictly made of metal (via writable: false), and standardise powerConsumption values (via getters and setters).


// Add interface for Typescript, omit for Javascript
interface Robot extends Person {
    madeOf: 'metal'
    powerConsumption: string
}

// add `: Robot` for TypeScript, omit for Javascript.
const Robot: Robot = Object.create(Person, {
    // define your property attributes
    madeOf: { 
        value: "metal",
        writable: false,  // defaults to false. this assignment is redundant, and for verbosity only.
        configurable: false, // defaults to false. this assignment is redundant, and for verbosity only.
        enumerable: true  // defaults to false
    },
    // getters and setters
    powerConsumption: {
        get() { return this._powerConsumption },
        set(value) { 
            if (value.indexOf('MWh')) return this._powerConsumption = value.replace('M', ',000k') 
            this._powerConsumption = value
            throw new Error('Power consumption format not recognised.')
        }  
    }
})

// add `: Robot` for TypeScript, omit for Javascript.
const newRobot: Robot = Object.create(Robot)
newRobot.powerConsumption = '5MWh'
console.log(newRobot.powerConsumption) // outputs 5,000kWh

And all prototypes of Robot cannot be madeOf something else:

const polymerRobot = Object.create(Robot)
polymerRobot.madeOf = 'polymer'
console.log(polymerRobot.madeOf) // outputs 'metal'

If you haven't yet figured out a way, use the associative property of JavaScript objects to add an extend function to the Object.prototype as shown below.

Object.prototype.extend = function(obj) {
   for (var i in obj) {
      if (obj.hasOwnProperty(i)) {
         this[i] = obj[i];
      }
   }
};

You can then use this function as shown below.

var o = { member: "some member" };
var x = { extension: "some extension" };

o.extend(x);

In ES6, you may use spread operator like

var mergedObj = { ...Obj1, ...Obj2 };

Note that Object.assign() triggers setters whereas spread syntax doesn't.

For more info see link, MDN -Spread Syntax


Old Answer :

In ES6, there is Object.assign for copying property values. Use {} as first param if you don't want to modify the target object (the first param passed).

var mergedObj = Object.assign({}, Obj1, Obj2);

For more details see link, MDN - Object.assign()

In case if you need is a Polyfill for ES5, the link offers it too. :)


Different approach: Object.create

Per @osahyoun answer, I find the following as a better and efficient way to 'inherit' from Person's prototype object:

function Person(name){
    this.name = name;
    this.type = 'human';
}

Person.prototype.info = function(){
    console.log("Name:", this.name, "Type:", this.type);
}

function Robot(name){
    Person.call(this, name)
    this.type = 'robot';
}

// Set Robot's prototype to Person's prototype by
// creating a new object that inherits from Person.prototype,
// and assigning it to Robot.prototype
Robot.prototype = Object.create(Person.prototype);

// Set constructor back to Robot
Robot.prototype.constructor = Robot;

Create new instances:

var person = new Person("Bob");
var robot = new Robot("Boutros");

person.info(); // Name: Bob Type: human
robot.info();  // Name: Boutros Type: robot

Now, by using Object.create:

Person.prototype.constructor !== Robot

Check also the MDN documentation.