Kotlin 喜欢 Javascript 中的作用域函数(let、also、apply、run)吗?

Muh*_*mil 11 javascript kotlin typescript

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

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

T.J*_*der 7

不,您不能在 JavaScript 或 TypeScript 中执行此操作。但根据您尝试这样做的原因,解构会有所帮助。

\n

您可以得到的最接近的是使用已弃用的with语句,它将一个对象添加到作用域链的顶部,因此任何独立标识符引用都会根据该对象的属性进行检查:

\n

\r\n
\r\n
function example(o) {\n    with (o) { // deprecated\n        console.log(answer);\n    }\n}\nconst obj = {\n    answer: 42\n};\nexample(obj); // Outputs 42
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

不过,存在几个问题with,这就是为什么它在 JavaScript 的严格变体中是不允许的(这是classES2015+ 中创建的模块、构造和其他新范围内的默认设置,以及带有"use strict";at的任何函数或脚本)开始)。

\n

另一个接近的版本是将对象传递给在其参数列表中使用解构的函数:

\n

\r\n
\r\n
function example({answer}) {\n    console.log(answer);\n}\nconst obj = {\n    answer: 42\n};\nexample(obj); // Outputs 42
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

一个主要的警告是,您不能以这种方式为属性分配新值(更糟糕的是,如果您尝试使用 \xc2\xa0\xe2\x80\x94 为例,使用answer = 67\xc2\xa0\xe2\x80\x94它更新参数的值,但不更新对象的属性值)。

\n

为了解决这个问题,您可以在函数内部使用解构,这样const您就不会忘记您无法更新该值(或者如果您尝试的话会收到早期错误):

\n

\r\n
\r\n
function example(o) {\n    const {answer} = o;\n    console.log(answer);\n    // answer = 67;   // <== Would cause error\n    // o.answer = 67; // <== Would work\n}\nconst obj = {\n    answer: 42\n};\nexample(obj); // Outputs 42
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

  • 除此之外,根据作者的用例,原型函数可用于复制 Kotlin 作用域函数的“一些”效果。例如, `Object.prototype.let = function (fn) { return fn(this); }`。作用域链本身不会改变(与“with”不同),但它们可以允许更函数式的编程风格。当然,这是否有用再次取决于所需的用例。[scope-extensions-js](https://github.com/TheDavidDelta/scope-extensions-js) 是一个使用这种技术的小型 TS 库。 (3认同)
  • 谢谢@迈克。只是一个小注意事项:如果您要扩展 `Object.prototype`,重要的是不要以这种特定方式进行操作,因为它会在 `Object.prototype` 上创建一个可枚举属性,这会与考虑不周的 ` for-in` 循环。相反,请使用`Object.defineProperty(Object.prototype, "let", { value(fn) { return fn(this); },configurable: true, writable: true });`,因此该属性是不可枚举的。(关于扩展本机原型的所有注意事项都适用。例如,永远不要在库中这样做,但在您自己的页面/应用程序中这样做就可以了。):-) (2认同)

Ext*_*ely 6

如果有人仍在寻找答案,那么有一个优秀的 javascript 作用域函数库(我不隶属):

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