0

What does the new keyword do that allows the following binding on the this object:

function Person(first, last) {
    this.first = first;
    this.last = last;
}
Person.prototype.greet = function() {
    console.log(`Hello, ${this.first} ${this.last}.`);
};
let p = new Person('Tom', 'Jones');
p.greet();

Whereas without the new keyword, this.first would raise an error since it is undefined. Conceptually speaking, what is new doing here in how it modifies the function?

Without new:

function Person(first, last) {
    this.first = first;
    this.last = last;
}
Person('Tom', 'Jones');
// TypeError: Cannot set property 'first' of undefined

And without using new seems the following is a crude way to simulate it:

function Person(first, last) {
    this.first = first;
    this.last = last;
    return this;
}
Person.prototype.greet = function() {
    console.log(`Hello, ${this.first} ${this.last}.`);
};

Person.prototype.greet.call(Person.call({}, 'Tom', 'Jones'));
David542
  • 104,438
  • 178
  • 489
  • 842
  • @evolutionxbox it says it does right here though: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new#:~:text=Binds%20the%20newly%20created%20object%20instance%20as%20the%20this%20context%20(i.e.%20all%20references%20to%20this%20in%20the%20constructor%20function%20now%20refer%20to%20the%20object%20created%20in%20the%20first%20step). – David542 Mar 25 '22 at 17:39
  • `new` is creating an object. Without an object, there is no `this`. – Robert Harvey Mar 25 '22 at 17:42
  • @RobertHarvey I see -- would it be possible to show in an answer an example of how `new` is working within javascript? or is it more at the language/lexical level and you can't really emulate it with functions or something else? – David542 Mar 25 '22 at 17:44
  • 2
    @David542 Constructing an object from a constructor function is a core language functionality. You can use `Reflect.construct` to avoid the `new` operator, or you can [approximate its behaviour when called on constructors defined as `function`](https://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible), but truly the passing of a `this` value to a function call is a native functionality. (And then, `this` in the constructor of a `class` extending a superclass [works even differently](https://stackoverflow.com/a/32458960/1048572)). – Bergi Mar 25 '22 at 17:50
  • @David542 Same thing as asking "*What does `….…()` do to modify the `this` object in a function?*", like in your `p.greet();` method call. – Bergi Mar 25 '22 at 17:53
  • @Bergi I've noticed that `this` answer has so much information -- particularly the first answer, which I'll just skip over, as it's way above my head, it almost reads like the ecma documentation itself (though I'm guessing more advanced programmers would find it fantastic). Does this answer hold up? https://stackoverflow.com/a/54408272/651174 I've found that the most helpful to conceptualize... – David542 Mar 25 '22 at 18:02
  • ...I updated the last part of the question to show an example without using `new` -- is that a valid way to do it? – David542 Mar 25 '22 at 18:03
  • 1
    @David542 It's not bad. It's definitely a good model to conceptualise every function as having a zeroth parameter, `this`, and a "this argument" or "receiver" being passed with every function call. But ignore the sentence "*If you just call a function then this is the "global object"*" in that answer, focus only on the strict mode (explained right below it) - and always use it when experimenting!. But no, this answer won't help you understand how `new` works. – Bergi Mar 25 '22 at 18:09
  • 1
    @David542: When calling a function in your example. It's like you did this...`window.Person` you created a function on the `window` object. However the `this` keyword inside Person assumes there also two properties on the window object called `first` and `last`. Ex. If you did `var first` and `var last` prior to declaring `Person`. It would be as if you did this: `window.first` and `window.last` and `Person` would now work as called. `window.first = "Tom" window.last = "Jones"` The `new` keyword binds the `Person`function to a new `{}`! In your case `{first : 'Tom', last: 'Jones' }` – Antonio Pavicevac-Ortiz Mar 25 '22 at 18:11
  • 1
    @David542 As for your edit, it should be `Object.create(Person.prototype)` instead of `{}`, but other than that it's ok – Bergi Mar 25 '22 at 18:11

0 Answers0