Nonconstructors
On Mon, Apr 24, 2017 at 1:42 PM, Raul-Sebastian Mihăilă <raul.mihaila at gmail.com> wrote:
I have a dilemma. I like how typically the built-in methods are not constructors (like Array.prototype.forEach). I have cases in which I'm creating a function in which I want to use
this
but I would like the function to not be constructible. There are ways of doing this:
- checking new.target - but you have to check and the last time I checked uglifyjs was failing because of it.
- ({function() { ... }}).function - but this requires creating an object every time, so it's ugly.
It would probably be too much to add a new kind of function definition, but I was wondering if anybody ever cared about this kind of things. For instance, would people usually expect frameworks/libaries or Javascript itself to not make functions constructible if they're not meant to be?
The obvious question is, why do you want to use this
?
You can use:
const foo = { bar() { // Not constructible } }; new foo.bar; //TypeError: foo.bar is not a constructor
function Entity() { if (this instanceof Entity) throw new Error("Please do not call with new"); }
oh the other side; you can bind this to a simple function call...
function f() { } var fWithThis = f.bind( {} /*Something to use as 'this' */ )
call with fWithThis()
and f's this will be the object you passed to bind.
Arrow functions are not constructible; just use one of those.
On Tue, Apr 25, 2017 at 12:15 AM, Tab Atkins Jr. <jackalmage at gmail.com> wrote:
The obvious question is, why do you want to use
this
?~TJ
For cases such as a debounce function:
const debounce = (func, delay) => {
let timeout;
return function (...args) {
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(this, args);
}, delay);
};
};
If func is using this
the resulted function (returned by debounce
)
should pass its this
.
Another case is related to form fields. Let's say a form field is an object
with a validate
method. I provide a createValidator
function to the
user that accepts multiple functions in order to call them 1 by 1 until one
of them returns an error. The result of createValidator
is a function
that then becomes the value of the field's validate
method (which the
user will call in order to validate the field). So the function will want
to use this
because it will forward it to the functions provided by the
user. This is expected because the function will be called as a method of
the field object.
On Mon, Apr 24, 2017 at 10:53 PM, Raul-Sebastian Mihăilă <raul.mihaila at gmail.com> wrote:
On Tue, Apr 25, 2017 at 12:15 AM, Tab Atkins Jr. <jackalmage at gmail.com> wrote:
The obvious question is, why do you want to use
this
?~TJ
For cases such as a debounce function:
const debounce = (func, delay) => { let timeout; return function (...args) { clearTimeout(timeout); timeout = setTimeout(() => { func.apply(this, args); }, delay); }; };
If func is using
this
the resulted function (returned bydebounce
) should pass itsthis
. Another case is related to form fields. Let's say a form field is an object with avalidate
method. I provide acreateValidator
function to the user that accepts multiple functions in order to call them 1 by 1 until one of them returns an error. The result ofcreateValidator
is a function that then becomes the value of the field'svalidate
method (which the user will call in order to validate the field). So the function will want to usethis
because it will forward it to the functions provided by the user. This is expected because the function will be called as a method of the field object.
Ah, these use-cases are reasonable.
In that case, then, yeah, checking new.target
seems to be the way
you want to go. That's explicitly what it was defined to do:
if(new.target) throw "Foo() must not be called with new";
There's no shorter way to do this; all the shorter methods rely on the function clearly existing as a method, syntactically.
I have a dilemma. I like how typically the built-in methods are not constructors (like Array.prototype.forEach). I have cases in which I'm creating a function in which I want to use
this
but I would like the function to not be constructible. There are ways of doing this:It would probably be too much to add a new kind of function definition, but I was wondering if anybody ever cared about this kind of things. For instance, would people usually expect frameworks/libaries or Javascript itself to not make functions constructible if they're not meant to be?