-
Notifications
You must be signed in to change notification settings - Fork 3
Function.prototype.once vs. Function.once vs. @Function.once #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Yes, adding both is also an option, though it makes me ask if then it would not be appropriate to do the same for |
Adding static const bind = Function.call.bind(Function.bind); |
I'm for |
Ah, yeah, silly me. I had forgotten that the |
Yeah, because For let f = function a_big_func() {
/* many
many
code */
}.once() // <- only see once here Note, though |
I don't think |
It's not uncommon for developers to want callable objects. To do that, you create a function, and then attach arbitrary properties to it, like this: const myFn = Object.assign(function() {...}, { ... }) Adding new functions to the Function.prototype has a higher likelihood of causing breaking changes, because of how common the above pattern is. Let me also add a third option. This could also be done as a decorator, like this: @Function.once
function() { ... } |
Yeah, consider decorator advanced to stage 3, I hope we could revisit function decorators in future meetings. |
I'm strictly for a prototype method since it's simpler for usage in most cases. |
Vote for |
I think a prototype method isn’t sufficiently useful, and it belongs only as a static method. Shipping a decorator wouldn’t make sense because you can’t decorate standalone functions nor object property values. |
Yet... aren't there plans for a follow-on proposal for that? I hope so, because it would be odd to restrict a feature as useful as decorators so they only work within classes. Otherwise, the same argument could be made about anyone trying to make almost any kind of decorator - "You can't use decorators outside of classes, so don't use a decorator". But, I can understand not wanting to block this proposal on another proposal that hasn't even been presented, nor do we know if it would ever go through. It would just be a bit of a shame, as this seems like the exact kind of thing that decorators were built to do. |
Function.prototype.once would keep open the possibility of a @Function.once decorator, for whenever function decorators hopefully get standardized in the future. In contrast, a Function.once static method would probably permanently exclude a @Function.once decorator, even after function decorators get standardized. (The same is true for Function.prototype.memo, @Function.memo, and Function.memo; see tc39/proposal-function-memo#2.) |
@js-choi i'm not sure why; a function can know when it's being called as a decorator, so |
@ljharb Detecting whether being called as a decorator rely on the structural type of the parameter, which is not accurate. Some mechanism like And there is also another way, we could add a custom hook via well-known symbol like |
That’s true. We could distinguish decorator uses ( So if we used a
I’m not thinking about decorating instance methods but rather looking towards future general function decorators. It may make sense for the author of a side-effect function to ensure that it will only be executed at most once:
Although this is a creative idea, do you have specific examples of problems that would occur from type-based polymorphism of |
@js-choi |
That is, people who wish to declare functions that are used at most once would have to do things like this: const executeEffect = function executeEffect() {}.once(); …or: const executeEffect = function executeEffect() {} |> Function.once(^^); …rather than: @Function.once function executeEffect() {} This use case might not be a big deal, but I think it’s worth at least considering. |
Yes, that's what i meant - they'd do |
Alright, thanks. Given that we could use type polymorphism for any future decorator form, let’s ignore decorators for now. We’ve basically got three choices:
However, const ƒ = function () {
/* very long body with many lines */
}.once(); …is less readable than: const ƒ = Function.once(function () {
/* very long body with many lines */
}); Relatedly, I’ve usually seen developers (including myself) use functionVariable.bind(receiver)
object.property.chain.bind(receiver) …rather than using function () {
/* very long body with many lines */
}.bind(receiver); In this way, one could argue that the situation between (We could also have both, yes, though I don’t know of any precedent in the language for having both, and |
How about both For example Object.hasOwn also do the thing alike |
Can you elaborate by what you mean by “Object.hasOwn also do the thing alike”? We put functions like hasOwn on the Object constructor, rather than Object.prototype, because changing Object.prototype would affect nearly all objects in all codebases, including plain JavaScript objects and third-party classes that do not subclass null. We could have both Function.once and Function.prototype.once, yes, though I don’t know of any precedent in the language for having both a static function and an instance method with the same functionality. And |
We definitely don't need both; if we could get rid of Object.prototype.hasOwnProperty, we would, and it's not the same case as this because objects sometimes have null prototypes, whereas functions virtually never do. (altho, that you can |
My subjective take: I like |
Uh oh!
There was an error while loading. Please reload this page.
Should we go with an “instance” method on the prototype or a “static” function on the constructor?
Function.prototype.once
This has precedent from, e.g., Function.prototype.bind.
Examples
From [email protected]:
From [email protected]:
From [email protected]:
From [email protected]:
From jitsi-meet 1.0.5913:
Function.once
It might be easier to read inline function expressions with a prefixed constructor function? It’s more verbose, though, when including the Function constructor as a “namespace”.
Examples
From [email protected]:
From [email protected]:
From [email protected]:
From [email protected]:
From jitsi-meet 1.0.5913:
Decorator
Multiple
Having two or three of the above is an option. They would probably have to have different names, because the
Function
constructor is itself a function.The text was updated successfully, but these errors were encountered: