Determining if an object can be constructed

Jordan Harband ljharb at gmail.com
Mon Jan 23 18:49:13 UTC 2017


Unfortunately, the only practical way to know that without risking side
effects is to read the human-produced documentation on the function, or to
have a human read the code.

On Mon, Jan 23, 2017 at 8:19 AM, Isiah Meadows <isiahmeadows at gmail.com>
wrote:

> I'll point out that all I need is some way to detect anything that is
> callable except for classes. Basically, anything that has a `[[Call]]` that
> doesn't throw unconditionally without entering a different scope (like
> classes, but not %ThrowTypeError%).
>
> And to clarify, these would both be included per above, since it does
> enter a different scope:
>
> ```js
> // New language scope
> function foo() {
>   throw new TypeError()
> }
>
> // New native scope (%ThrowTypeError%)
> "use strict"
> var foo = Object.getOwnPropertyDescriptor(
>   arguments, "callee"
> ).get
> ```
>
> `Reflect.isConstructor` isn't sufficient for my needs, since it would
> still consider the first `foo` above to be a constructor.
>
> On Sat, Jan 21, 2017, 01:14 Jordan Harband <ljharb at gmail.com> wrote:
>
>> The reality here is that we're all playing around what the definition of
>> "constructor" and "callable" mean.
>>
>> In the spec, "constructors" are defined as having a `[[Construct]]`
>> internal slot; something is "callable" if it has a `[[Call]]` internal
>> slot. By that definition (https://tc39.github.io/
>> ecma262/#sec-isconstructor and https://tc39.github.io/
>> ecma262/#sec-iscallable), a `class` constructor is indeed callable
>> (because it's defined to have `[[Call]]` throw a `TypeError`). Similarly,
>> as defined in the spec, `typeof class Foo {}` is "function" only because it
>> has a `[[Call]]` internal slot (https://tc39.github.io/ecma262/#table-35);
>> if constructors lacked a `[[Call]]` slot (such that `IsConstructor`
>> returned `true` for them), then `typeof someConstructor` would return
>> "object".
>>
>> Obviously the committee could have chosen to define these things
>> differently; but this is how things are defined.
>>
>>
>>
>> I'm going to claim that conceptually - eg, to the majority of users -
>> something is a constructor when it's *intended* to be used with `new`. In
>> other words, "what it returns" isn't actually the point - if you're "meant"
>> to use it with `new`, it's a constructor, otherwise, it's a function - and
>> functions that work with both can be thought of as a dual
>> constructor/factory (the factory calls the constructor for you). However,
>> that conceptual definition is not one that can be programmatically
>> determined, because "programmer intention" in this regard simply isn't
>> inherently enshrined in an observable way, whether choosing `class` or
>> `function`.
>>
>> Personally I think it would be wonderful to expose `IsConstructor`
>> (`IsCallable` is already exposed via `typeof` returning "function"), but I
>> feel quite confident that neither actually address any of the use cases in
>> this thread.
>>
>> In addition, "safe to call" or "safe to use with `new`" all depends on
>> your definition of "safe", and it's clear from this thread that that does
>> not have a universally agreed-upon definition either.
>>
>> It might be useful to distill things down to 1) concrete use cases for
>> calling or instantiating a function where you don't already know what it
>> does, and can't assert in your human documentation what you expect; 2) a
>> definition of "constructor", either a different one if you don't agree with
>> mine above, or if you do, a form of mine that can be programmatically
>> determined, and 3) a definition of "safe" which means more than "doesn't
>> throw an exception".
>>
>> On Fri, Jan 20, 2017 at 6:52 PM, Scott Sauyet <scott at sauyet.com> wrote:
>>
>> Bradley Meck wrote:
>> >> 1. every call to `new Foo(...args)` creates a distinct object not
>> >> reference-equal to any other such call.
>> >
>> > Would this mean
>> >
>> > ```
>> > function factory() { return []; }
>> > ```
>> >
>> > would qualify as a constructor?
>>
>> I'm thinking of that as a necessary, but not a sufficient condition.
>>
>> If it fails that test it cannot be a constructor.  It's clear that
>> there are other tests.  It's not clear to me what they are.
>>
>>   -- Scott
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170123/df9f7bcd/attachment-0001.html>


More information about the es-discuss mailing list