3

From here:

function highest(){ 
  return makeArray(arguments).sort(function(a,b){ 
    return b - a; 
  }); 
} 

function makeArray(array){ 
  return Array().slice.call( array ); 
} 

assert(highest(1, 1, 2, 3)[0] == 3, "Get the highest value."); 
assert(highest(3, 1, 2, 3, 4, 5)[1] == 4, "Verify the results.");

Now, why does Array() even return something meaningful, without a new operator? Most "class" definitions I've seen in JS return undefined if called without new:

function User(name) {
  this.name = name;
  this.jump = function() {
    console.log(name + " is jumping!");
  }
}

assert(typeof(User("no New")) == 'undefined');
ripper234
  • 222,824
  • 274
  • 634
  • 905
  • 1
    It's not so much "Why does .slice() work?" as "Why does `Array()` seem to do the same thing as `new Array()`?" - the answer to which can be summed up as "Because the spec says so". See [What's the difference between `Array(1)` and `new Array(1)`?](http://stackoverflow.com/questions/5827008/whats-the-difference-between-array1-and-new-array1-in-javascript). – nnnnnn Mar 10 '12 at 09:34
  • @nnnnnn - Aye, voted to closed as dup, thanks. – ripper234 Mar 10 '12 at 09:54

2 Answers2

6

The specification explicitly dictates this:

When Array is called as a function rather than as a constructor, it creates and initialises a new Array object. Thus the function call Array(…) is equivalent to the object creation expression new Array(…) with the same arguments.

How it's done internally depends on the implementation, but for custom constructors you can use the following trick:

if(!(this instanceof User)) return new User(name);

... because new User(...) sets this to the created User instance, whereas User(...) sets it to the global object. (So you were in fact setting global variables in the last snippet.)

pimvdb
  • 151,816
  • 78
  • 307
  • 352
1

Based on Chrome's debugging panel, Array() returns a new array in the same way that new Array() does or that [] does. My guess would be that it's either for ease of use of the language, or its related to the [] syntax (which of course does not require a new).

It's actually possible with your own functions to optionally require a new:

function User(name) {
    if (!(this instanceof User)) {
        return new User(name);
    }
    this.name = name;
    this.jump = function() {
        console.log(name + " is jumping!");
    };
}

​

Then both User('blah') and new User('blah') work.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Corbin
  • 33,060
  • 6
  • 68
  • 78