Reputation: 1439
Is it possible to create Kotlin like scope functions in Javascript/Typescript? Is there any library that does it?
Reference: https://kotlinlang.org/docs/reference/scope-functions.html
Upvotes: 13
Views: 7516
Reputation: 1075079
No, you can't do that in JavaScript or TypeScript. But depending on why you're trying to do it, destructuring can help.
The closest you can get is to use the deprecated with
statement (I don't recommend it), which adds an object to the top of the scope chain, so any freestanding identifier references are checked against the object's properties:
function example(o) {
with (o) { // deprecated
console.log(answer);
}
}
const obj = {
answer: 42
};
example(obj); // Outputs 42
There are several problems with with
, though, which is why it's disallowed in the strict variant of JavaScript (which is the default inside modules, class
constructs, and other new scopes created in ES2015+, as well as any function or script with "use strict";
at the beginning). Those same problems are why it's not supported in TypeScript (TypeScript will copy it over to the transpiled JavaScript code, but with an error, and it will use any
as the type of symbols inside the with
; example).
Another close version is to pass an object to a function that uses destructuring in its parameter list:
function example({answer}) {
console.log(answer);
}
const obj = {
answer: 42
};
example(obj); // Outputs 42
but a major caveat there is that you can't assign new values to properties that way (and worse, if you try — for instance, with answer = 67
— it updates the parameter's value but not the object's property value).
To deal with that, you might use destructuring inside the function instead, with const
so you don't forget you can't update the value (or to get an early error if you try):
function example(o) {
const {answer} = o;
console.log(answer);
// answer = 67; // <== Would cause error
// o.answer = 67; // <== Would work
}
const obj = {
answer: 42
};
example(obj); // Outputs 42
Upvotes: 8
Reputation: 540
If anyone is still looking for an answer, there is an excellent library for those scope functions for javascript (I am not affiliated):
https://github.com/TheDavidDelta/scope-extensions-js
Upvotes: 7
Reputation: 21
While not exactly what you're looking for, a pattern that I use let
a lot for in Kotlin is
val thing = nullable?.let{ // case if not null } ?: run { // case if null }
The closest I've come to this in Javascript (well, typescript) in terms of readability and ergonomics is something like:
const thing = some?.deeply?.nested?.nullable?.thing ?? (() => {
// case if null
})
Which gets you halfway there. :)
Upvotes: 2