skip to Main Content

I tried to bind a constructor object:

"use strict";
    
let Person = function(name){
  this.name = name;
}

let age = {
  age: 128
}

let AgedPerson = Person.bind(age)
console.log(new AgedPerson("John"))

Since bind essentially sets up a context with this pointing out to some object and then new initializes this and returns it I expected that the following would be printed:

{
  age: 128,
  name: "John"
}

but instead got:

{
  name: "John"
}

Why is the age field lost after creating the object?

2

Answers


  1. When you use the new keyword before a function, the function is called with a this value set to a new empty object, regardless of whether you used .bind() on the function beforehand (ie: the this value you had set is ignored).

    Since your function doesn’t return anything and you’re using the new keyword, the default behavior is for the function to then return the this value once it’s finished executing. In your case, AgedPerson is called, with a this set to an empty object {} (due to the new keyword). this is then updated within the function to add the name property to it, which is then implicitly returned, giving you {name: "John"}.

    .bind() comes into play when your function invoked in other ways (eg: with (), as well as .call() or .apply()), but not when using new, for example:

    "use strict";
    
    const person = function(name) {
      this.name = name;
    }
    
    const age = { age: 128 };
    
    const agedPerson = person.bind(age)
    agedPerson("John"); // modifies the age object by reference
    console.log(age); // { age: 128, name: "John" }
    Login or Signup to reply.
  2. Note that in the Nick Parsons’ answer you just call a constructor on an object, so the object doesn’t became a true instance of Person. You can fix it by setting its prototype.

    Also you can use Function::call() to combine the binding and the calling into one operation.

    "use strict";
    
    const Person = function(name) {
      this.name = name;
    }
    
    const age = { age: 128 };
    
    Person.call(age, 'John');
    Object.setPrototypeOf(age, Person.prototype);
    
    console.log('age is Person:', age instanceof Person);
    console.log(age); // { age: 128, name: "John" }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search