0

Under normal conditions, new.target will be either undefined, the class of a constructor or a subclass or the function it is in or a subclass.

Supposedly, Reflect.construct(target, argumentsList, newTarget=target) is equivalent to target.[[Construct]](CreateListFromArrayLike(argumentsList), newTarget). This allows us to set arbitrary Objects as new.target. The [[Construct]] internal method has this to say about newTarget (The second argument):

The second argument is the object to which the new operator was initially applied.

So what does it mean for it to be a completely different value? (Especially for built-in functions)

For example, in the console:

>> Reflect.construct(String, [], String)
String { "", 1 more… }
>> Reflect.construct(String, [], Array)
String
>> let c = Reflect.construct(String, ['123'], Array); c
String
>> Object.getPrototypeOf(c) === Array.prototype
true
>> c.toSource()
"["1", "2", "3"]"
>> c = Reflect.construct(String, ['1', '2', '3'], Array);
>> // new Array('1', '2', '3') ??
>> c[1]
>> '2'
>> c.constructor
function Array()
>> // Seems that `String` has been totally discarded.
>> // So `newTarget` only makes sense for subclasses to emulate `super()`?
Artyer
  • 15,829
  • 2
  • 29
  • 51
  • "*Seems that `String` has been totally discarded*" - not really, no. All you have shown is that `c` inherits `.toSource` and `.constructor` from its prototype (which you have shown to be `Array.prototype`), and that `.toSource()` (and basically all other [generic array methods](https://stackoverflow.com/q/29835765/1048572)) work on the `String` instance due to the similarity between string and array objects. To see a difference to an actual array, you could try changing the own properties (`0`, `1`, `2`, `length`) of the string. – Bergi Oct 15 '17 at 21:58
  • @Bergi Your right. When I do `c = Reflect.construct(String, ['123'], Number)`, both `Number.prototype[method].call(c)` and `String.prototype[method].call(c)` throw TypeError (`method called on incompatible String`) But I still don't know what `c` is – Artyer Oct 15 '17 at 22:01
  • It should basically be equivalent to `Object.setPrototypeOf(new String('123'), Array.prototype)`. It's a really weird thing - and of course you never should create `String` instances in general. Btw, in my Chrome `String.prototype.slice.call(c)` does not throw an exception, but it does call `Array.prototype.toString` on the object first. Using `String.prototype.toString.call(c)` or `String.prototype.valueOf.call(c)` (which are not generic) does return the expected values though – Bergi Oct 15 '17 at 22:12

0 Answers0