2

I having trouble to understand why the new keyword is facultative for javascript API object/interface feature.

d = new String(); // javascript native object
d2 = String();
console.log(d);
console.log(d2);

results in console (that seems pretty normal):

 String {}
 (an empty string)

but:

b = new Blob(); // API object
b2 = Blob();
console.log(b);
console.log(b2);

results:

Blob { size=0, constructor=function(), type="", more...}
Blob { size=0, constructor=function(), type="", more...}

and not:

Blob { size=0, constructor=function(), type="", more...}
Blob() is undefined or (an empty blob)

It all work just fine but I'm curious...

TGrif
  • 4,873
  • 8
  • 27
  • 44

1 Answers1

2

It's a wart in JS. There are functions that construct objects internally and return them (don't need new), and "constructor functions" using new that do a bunch of magic.

The usual recommendation is to never write your own types to require new, because new requiring functions do bad but subtle things if you omit it (specifically, they bind this to the global object instead of a new object, so the instance variables are really the global variables, and assigning to instance members clobbers globals). If you must use them, JavaScript: The Good Parts recommends using initial capitals in the name to mean "requires new" and initial lowercase for everything else.

Community
  • 1
  • 1
ShadowRanger
  • 108,619
  • 9
  • 124
  • 184
  • They both add object to the global Window (maybe because my browser isn't so recent) – TGrif Oct 06 '15 at 20:50
  • It's not about whether the result of the assignment is placed on the global `window` (usual case for variables not declared with `var`). It's whether assignments internal to the constructor use a `this` of the new object being constructed (using `new`) or use a `this` that's the same `this` the caller had (usually the global `window`, though not always). If I define `var Foo = function(x) { this.ab = x; }`, then do `var f1 = new Foo("123");` then `f1` is a new object with attribute `ab` set to `"123"`. If I forget the `new`, then `f1` is `undefined` and there is a global `ab` set to `"123"`. – ShadowRanger Oct 06 '15 at 22:05
  • By constrast, a constructor-like function not designed to use `new` would do all the work internally and `return` the newly constructed object; it doesn't rely on `new` having been used to give it a special `this`. Since the two forms are mostly incompatible, you have to choose, and the non-`new` form is more flexible, and has less surprising side-effects when misused. – ShadowRanger Oct 06 '15 at 22:07
  • There are things you can do to try and handle both cases, but they can't handle all the corner cases, and they're generally just confusing, so the usual approach is to stick to only one method of writing constructors (usually w/o `new`), except in those annoying cases where the browser builtins require `new` usage. – ShadowRanger Oct 06 '15 at 22:10
  • 1
    Thank you a lot for your great explaination. – TGrif Oct 07 '15 at 18:14