Trying to understand the new keyword

2019-05-25 00:08发布

问题:

I'm trying to understand exactly what the javascript new keyword means, why it is necessary and when I should use it.

Consider the following examples:

      var x = new function(){
        var self=this;
        this.myFunction = function(){alert('foo ' + self.v)}
        this.v='x';
      };

      var y = function(){
        var self=this;
        this.myFunction = function(){alert('foo ' + self.v)}
        this.v='y';
        return this;
      }();


      var f=function(){
        var self=this;
        this.myFunction = function(){alert('foo ' + self.v)}
        this.v='z';
      }

      var z = new f();

      x.myFunction();
      y.myFunction();
      z.myFunction();

x,y and z are all objects. Potentially with public and private member variables.

x and z where constructed with the use of the new keyword. As far as I can tell, the new keyword simply executes the function and returns the context. So I guess in the above example x and y are essentially singletons since any reference to the original function is lost?

Apart from that are they all exactly equivalent? If not what are the differences and when would I want to use one approach or avoid another?

Thanks for any explanations.

回答1:

I'm trying to understand exactly what the javascript new keyword means

a = new X() means something like:

  • create new object A
  • set its prototype to the object called X.prototype (all functions have a "prototype" property which is just an object and you can modify it to add behaviour to objects created using this function and new),
  • call X with this=a to initialize the object.

This is similar to:

a = Object.create(/* prototype */ X.prototype, {});
a.constructor = X; /* magic property which can be read after */
X.apply(/* this */ a, /* args */[]);

why it is necessary and when I should use it.

It isn't and you don't have to. Object.create works more naturally with JS prototype-based object model and lets you create arbitrary prototype chains.

When new is used, it's used like this:

function Class(constructor_args) {
   // init an object
   this.a = 10;
};
Class.prototype.method1 = function() {
   console.log(this.a);
}
var obj = new Class();

Then after you create an object using new Class(), its prototype refers to the object Class.prototype which contains its methods while the object itself contains the fields.

(Personal opinion: The keyword new was introduced to make it easier in Javascript to write code which resembles Java/C++ and classical non-prototypal object model.)

Plase read these excellent articles:

Classical inheritance in Javascript

Prototypal inheritance