2

I'm trying to understand the new operator. Have a look at the following function:

var _new = function(fn) {
    var obj = Object.create(fn.prototype);
    fn.apply(obj);
    obj.constructor = fn; // <--- EDIT: unnecessary
    return obj;
};

which can be applied like that:

var Test = function(){
    this.foo = 1;
};

var instance = _new(Test);

Of course it can be easily extended to arbitrary number of arguments (I'm just trying to keep it simple).

It seems that it works like new keyword. So what is the difference if any? What else new operator does to an object?

freakish
  • 54,167
  • 9
  • 132
  • 169

1 Answers1

3

You are right, this is basically what new is doing: Create a new object that inherits from Func.prototype and call Func with this referring to this new object.

There is a slight difference to your implementation though: If the constructor (Func) does not return an object, this is implicitly returned. If it returns an object (any object) than it will become the return value of the constructor call.

So a more accurate replication would be:

var _new = function(fn) {
    var obj = Object.create(fn.prototype);
    var result = fn.apply(obj);
    return result != null && typeof result === 'object' ? result : obj;
};

That's it. You can see it as syntactic sugar if you want to, just like the conditional operator.


Some pointers to the reference: When new is used, the internal [[Construct]] function of the constructor is called. What exactly happens is described in section 13.2.2 of the specification and it pretty much does the same as the function you (and I) wrote.

The point I'm not completely sure about is that the object's internal [[Extensible]] property is set to true. I would assume that every object you create via Object.create is extensible by default (if it's prototype is extensible).

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Oh, wow. That's an interesting feature. I've always thought that it doesn't matter what constructor returns. I've never checked that though. :) Thank you for the answer! – freakish Apr 02 '13 at 16:54
  • You're welcome :) Added some small remarks... – Felix Kling Apr 02 '13 at 17:01
  • So what does it mean for an object to be extensible? Are there nonextensible objects? – freakish Apr 02 '13 at 17:01
  • Good question. The specification says *"If true, own properties may be added to the object."*. It seems to be related to the [`Object.freeze`](http://es5.github.com/#x15.2.3.9), though I don't know if that's the only place where it's used (searching for `[[Extensible]]` on the page might provide more info). – Felix Kling Apr 02 '13 at 17:04
  • 1
    @freakish: [`Object.preventExtensions({})`](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/preventExtensions) (`.freeze()` and `.seal()` do similar things) – Bergi Apr 02 '13 at 17:04
  • Wow, just when I thought I know quite a lot about JavaScript. Thank you, guys, for help. :) – freakish Apr 02 '13 at 17:07