Kotlin 喜欢 JavaScript 中的作用域函数(让、也、应用、运行)?

是否可以在 Javascript/Typescript 中创建类似 Kotlin 的范围函数?有没有图书馆可以做到这一点?

参考: https://kotlinlang.org/docs/reference/scope-functions.html

stack overflow Kotlin like scope functions (let, also, apply, run) in Javascript?
原文答案
author avatar

接受的答案

不,您不能在JavaScript或Typescript中执行此操作。但是,根据 why 的不同,您正在尝试做到这一点,破坏会有所帮助。

您可以获得的最接近的是使用已弃用的 with 语句,该语句将对象添加到示波器链的顶部,因此对对象的属性检查了任何独立的标识符引用:

function example(o) {
    with (o) { // deprecated
        console.log(answer);
    }
}
const obj = {
    answer: 42
};
example(obj); // Outputs 42

但是, with 有几个问题,这就是为什么在JavaScript的严格变体中禁止它(这是模块内部的默认值, class 构造,以及在ES2015+中创建的其他新范围,以及任何函数或在开始时带有 "use strict"; 的脚本)。

另一个关闭版本是将对象传递给使用其参数列表中破坏性的函数:

function example({answer}) {
    console.log(answer);
}
const obj = {
    answer: 42
};
example(obj); // Outputs 42

但是一个主要的警告是,您不能以这种方式为属性分配新值(例如,如果您尝试 - 例如,使用 answer = 67 } - 它会更新参数的值,而不是对象的属性值)。

为了解决这个问题,您可能会使用 const 来使用破坏性函数,这样您就不会忘记无法更新值(或者如果尝试,则会出现早期错误):

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

答案:

作者头像

https://www.npmjs.com/package/lazymacro

该软件包提供了您需要的功能,其实现非常简单(通过 Object.defineProperty 请参阅 code )。

  • obj.PIPE(f) 与Kotlin中的 let 相似
  • obj.PIPETHIS(f) 与Kotlin中的 run 相似
  • obj.WITH(f) 与Kotlin中的 also 相似
  • obj.WITHTHIS(f) 与Kotlin中的 apply 相似

然后,您可以写类似的东西:

["I", "am"]
    .WITH(v => v.push("lazynode."))
    .WITH(console.log)
    .PIPE(v => v.join(" "))
    .PIPE(v => console.log(`${v}`))
    ?.PIPE(v => console.log("null safety features can be used together!"));

和加法

它为 Promise 提供了范围函数,可以将您从 await / then 地狱中保存下来

  • promise.THEN(f)
  • promise.WAIT(f)

例子:

Promise.resolve({})
    .WAIT(async local => local.datax = await getSomeRemoteData())
    .WAIT(async local => local.datay = await getSomeRemoteData())
    .WAIT(async local => local.dataz = await getSomeRemoteData())
    .WAIT(async local => await doSomething(local.datax, local.datay, local.dataz));
作者头像

虽然不是您要寻找的东西,但我在Kotlin中经常使用 let 的模式是

val thing = nullable?.let{ // case if not null } ?: run { // case if null }

我在JavaScript(嗯,typescript)中最接近的是可读性和人体工程学,就是这样的:

const thing = some?.deeply?.nested?.nullable?.thing ?? (() => {
// case if null
})

这使您到了一半。:)

作者头像

您可以使用 Kotlin/js 。它允许您将Kotlin代码转换为JavaScript或Typescript,并且使用JavaScript生态系统 fully interoperable

作者头像

如果有人仍在寻找答案,那么对于JavaScript的这些范围功能就有一个出色的库(我没有附属):

https://github.com/TheDavidDelta/scope-extensions-js