archives

« Bugzilla Issues Index

#695 — Please require "new" with TypedArray constructor functions


In the new sections on Typed Arrays in the ES6 draft:

15.13.5.1 The ArrayBuffer Object Called as a Function
15.13.6.1 TypeArray Constructors Called as a Function
15.13.7.1 The DataView Constructor Called as a Function

I would like to require that the "new" operator be used with the ArrayBuffer, Typed Array and DataView constructors.

Pure JavaScript constructor functions do not work correctly without using the "new" operator. There should not be an expectation that these built-ins do.

Some web platform constructor functions necessarily support calling them without the "new" operator because of necessary backward compatibility requirements. The typed array constructors have no such legacy. It is difficult to support calling them without the "new" operator in some browser implementations -- at least as long as they are implemented at the DOM binding level and not in the JS engine directly. Further, the typed array spec editors have to this point declined requests to require support for calling them without the "new" operator. Please don't add this requirement in the ES6 spec.


I've love to spec. it in the way you suggest. However, when I checked I found that Firefox doesn't require the use of new.


If you can confirm that other browsers don't already work like Firefox in this regard then I'll make the change you are requesting.


It definitely doesn't work in any WebKit based browser.

Chrome:

> var t = Float32Array(5);
< TypeError: DOM object constructor cannot be called as a function.

WebKit nightly:

> var t = Float32Array(5);
< TypeError: '[object Float32ArrayConstructor]' is not a function (evaluating 'Float32Array(5)')

> t = new Float32Array(5);
< [0, 0, 0, 0, 0]


Dmitry Lomov (CC'd) has been working on implementing Typed Arrays directly in the V8 VM. He points out that in the VM, it is trivial to make

Float32Array(5)

work the same as

new Float32Array(5)

Since a goal of typed arrays' incorporation into the ES spec is to make them work similarly to Arrays, perhaps their constructors should be allowed to be called as functions after all, because "var t = Array(5)" works in every browser.

If it seems this should be possible then please close this bug.


(In reply to comment #3)
> Dmitry Lomov (CC'd) has been working on implementing Typed Arrays directly in
> the V8 VM. He points out that in the VM, it is trivial to make
>
> Float32Array(5)
>
> work the same as
>
> new Float32Array(5)
>
> Since a goal of typed arrays' incorporation into the ES spec is to make them
> work similarly to Arrays, perhaps their constructors should be allowed to be
> called as functions after all, because "var t = Array(5)" works in every
> browser.
>
> If it seems this should be possible then please close this bug.

Actually, in ES6 we have moving away from using constructor functions in this manner. While it is easy enough for engines (particularly V8) to make this distinction, it is harder for JS code to do so. In particular in ES6 we have this problem:
class Foo {
constructor() {
if /*called directly */ {/* act like a factory */}
else if /* super called from subclass constructor */
{/* initialize subclass provided this value */}
else /* must be a new Foo call */
{ /* initialize new Foo instance */ }
}
}
class Bar extends Foo () {
constructor() {
super();
}
}

The issue is what do those predicated look like coded in JS? They have to be written by the JS programmer and it is actually pretty difficult of reliably discriminate the cases. Because of this, I expect having class constructors that also act as factory functions is going to become an ES6 anti-pattern.

Also for Binary Data, we want calls like Int8Array(10) to produce a type object describing a 10 element Int8Array rather than an actual array. The present state where using new is required for portable code, in theory, lets us apply that interpretation to calls without new.

Hopefully, V8 won't change its current behavior until ES6 if finalized in this regard. Making the new optional on Typed Array constructors at this time would probably turn that into a de facto standard and block that aspect of the Binary Data extension.

Given all of this, I think your original bug is correct. We do want to require new for actual data object creation by these constructors.


Great, I am fine either way (and happy to see "constructor as function" pattern gone); and I'll be happy to kill this behavior in V8 implementation.
It will be great to reflect this decision in the spec draft (in rev 15 e.g. it is still "If its this value is undefined, it creates and initialises a new ArrayBuffer object. Thus the function call ArrayBuffer(…) is equivalent to the object creation expression new ArrayBuffer (…) with the same arguments."