2

I want to create an instance of a Point with and without the new operator like:

Point(5, 10); // returns { x: 5, y: 10 }
// or
new Point(5, 10); // also returns { x: 5, y: 10 }

I got it working so far with the help of StackOverflow.

function Point() {
  if (!(this instanceof Point)) {
    var args = Array.prototype.slice.call(arguments);
    // bring in the context, needed for apply
    args.unshift(null);
    return new (Point.bind.apply(Point, args));
  }
  // determine X and Y values
  var pos = XY(Array.prototype.slice.call(arguments));
  this.x = pos.x;
  this.y = pos.y;
}

But that looks horrible, I am even unshifting null into the array so I can use apply. That just doesn't feel right.

I found a lot of solutions how to achieve it with new constructors and constructor wrappers but I want to keep it as simple as possible (it's just a plain, simple Point).

Is there an easier way to achieve this behaviour?

2
  • Will this have to be for all functions or just 1? If just 1, quite frankly it'd be better to rewrite that function. Commented Jun 12, 2013 at 10:52
  • @Qantas94Heavy It's just the Point function which I want to behave like this. But of course it's called multiple times. Commented Jun 12, 2013 at 10:53

1 Answer 1

3

If you don't mind using ECMAScript 5 functions, Object.create() could help:

function Point()
{   var args = Array.prototype.slice.call(arguments);
    if (this instanceof Point) return Point.apply(null, args);
    var pos = XY(args); 
    var result = Object.create(Point.prototype);
    result.x = pos.x;
    result.y = pos.y;
    return result;
}

If you need ECMAScript 3 compatibility, this crazy, convoluted solution is yet another one (note that it's just a wrapper for an internal equivalent of new Point):

function Point() 
{   var pos = XY(Array.prototype.slice.call(arguments));
    function internalPoint()
    {   this.x = pos.x;
        this.y = pos.y;
    }
    internalPoint.prototype = Point.prototype;
    return new internalPoint;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Ugh! I think I am going with ECMAScript5.
@DanLee: note that the first method won't be supported by IE8 and below , unless you add a shim for Object.create(). Having said that, I'd agree that the second one is crazy, but less crazy than the one you made :O.
Haha, yeah it was puzzled together :) I am trying to get my head around these structures.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.