用 Javascript 析构 Clojure

用 Javascript 析构 Clojure

原文:https://medium.com/hackernoon/destructuring-clojure-with-javascript-bd1398bdacb6

Clojure 是我在 T2 Swym 公司工作时学习的一种语言。当我去年加入时,我不知道它意味着什么,除非它是导致 Javascript for loops 出现问题的事实证明它非常接近于 Javascript

Source — http://java.ociweb.com/mark/clojure/article.html

来到 Clojure。这是一种美丽的语言。一开始很奇怪,但你会慢慢喜欢的。函数式语言似乎更倾向于。在这篇文章中,我将谈论许多语言共有的一个特性,但在 Clojure 和 Javascript 中有具体的细节,有它们的快乐和痛苦。破坏。为什么是 Clojure?—那是以后的事了。

析构使赋值变得更容易,这可能需要多行代码。

简单的解构,

简单来说,从向量和数组中快速加载变量,不多不少重复一个字。

//JS// Old way
var list = [1,2,3];
var x = list[0], y = list[1], z = list[2];
console.log(x, y, z);// Destructured way
var list = [1,2,3];
var [x, y, z, a] = list;
console.log(x, y, z, a);
// Note - Any extra parameter not accounted for becomes *undefined*

Clojure 和 JS 的一个明显区别是数据结构的不变性。Like 变量赋值可用,但不一定好用。这在理解 Clojure 时起了很大作用,我最初认为这是一个障碍。但是随着时间的推移,直觉显现出来了。

;; Clojure;; Using let definition, same can be done with a *def* for the list
(let [list [1 2 3]
  [x y z] list]
  (println x y z));; Better one, list ref created within the destructuring
(let [[x y z a :as list] [1 2 3]]
 (println x y z a list))
;; Note - Extra parameter unaccounted for becomes *nil*

更深入地研究向量,尤其是当你不想列出参数和析构的时候

// JS
// Bunching rest of the values with a spread operator
var list = [1, 2, 3, 5, 6, 7, 8];
var [x, y, z, …a] = list;
console.log(x, y, z, a);
// Note - The last param will be the spread operator(...) Powerful for array merging, and data processing. [More on spread operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator)// Ignoring parts
var list = [1, 2, "ignore me", 3];
var [x,y,,z] = list;
console.log(x,y,z);

Clojure 与之匹配

;; Clojure
;; Spread operator
(let [[x y z & rest-of-it :as list] [1 2 3 5 6 7 8]]
 (println x y z rest-of-it));; Ignoring 
(let [[x y _ z :as list] [1 2 "ignore me" 3]]
  (println x y z))

选择缺省值很简单,没有以前那些脆弱的 if 检查。

// JS
// Old way - Default values
var list = [1,2];
var x = list[0], y = list[1];
var z = list[2] || 'default z'; // This check is flimsy, you need to check for *undefined* to avoid *falsy* errors. for eg: false will pass to second part // Default values
var list = [1, 2];
var [x,y,z="default z"] = list;
console.log(x,y,z);

Clojure 中相同

;; Clojure
;; Default values
(let [[x,y,z :or [z 10]] [1 2]]
 (println x y z))

对象和嵌套结构

这就是真正的乐趣所在。通过简化赋值,对于接受配置和可选参数的函数非常强大。

// JS
// Object
var o = {“x”: 1, “y”: 2, “z”: 3};
var {x, y, z} = o;
console.log(x, y, z);
// Also works - var {x, y, z} = {x: 1, y: 2, z: 3};
// Also works - var x,y,z; ({x, y, z} = o);// Renaming
var o = {“x”: 1, “y”: 2, “z”: 3};
var {x: a, y: b, z: c} = o;
console.log(a, b, c);// Default values with renaming
var o = {“x”: 1, “y”: 2, “z”: 3};
var {x, y, z: c, p: d=10, q=20} = o;
console.log(a, b, c, d, q);// Usage in functions
function doSomethingAwesome({mandatoryParam, renameParam: changedParam, optionalParam=1, optionalRenameParam: changedOptionalParam=2}){
 console.log(mandatoryParam, changedParam, optionalParam, changedOptionalParam);
}
doSomethingAwesome({mandatoryParam: 10, renameParam: 20});// Nested objects
var o = {
 “a”: {
 “x”: 1,
 “y”: [2, 3]
 }
};// With renaming and default values
var {a: {x, y: [aa, bb, cc=20], z=10}} = o;
console.log(a, x, y, p, aa, bb, cc, z);

与 Javascript 相比,Clojure 有一些枪,如 :keys:strs 绑定形式,将析构捆绑在一起。警告——进入一个稍微复杂一点的领域

;; Clojure
;; Object — not so efficient when there is no renaming
(let [{x :x y :y} {:x 1 :y 2 :z 3}]
 (println x y))

;; Object with renaming
(let [{rx :x y :y} {:x 1 :y 2 :z 3}]
 (println rx y));; Object with keywords and strings, but no renaming
(let [{:keys [x y z] :as list} {:x 1 :y 2 :z 3}
 {:strs [xx yy zz] :as list-str} {“xx” 11 “yy” 22 “zz” 33}]
 (println x y z xx yy zz));; Object with defaults
(let [{:keys [x y z xx yy zz] :or {xx 10 yy 20 zz 30} :as list} {:x 1 :y 2 :z 3}]
 (println x y z xx yy zz))

;; Object defaults with renaming
(let [{rx :x y :y rz :z :or {rz 30}} {:x 1 :y 2}]
 (println rx y rz))

;; Usage in functions — not so efficient
(defn do-something-awesome [{
 mandatoryParam :mandatoryParam
 changedParam :renameParam
 optionalParam :optionalParam
 changedOptionalParam :optionalRenameParam
 :or {optionalParam 1 changedOptionalParam 2} }]
 (println mandatoryParam changedParam optionalParam changedOptionalParam))(do-something-awesome {:mandatoryParam 10 :renameParam 20});; Usage in functions — better
(defn do-something-awesome [{
 :keys [mandatoryParam optionalParam optionalRenameParam]
 changedParam :renameParam
 changedOptionalParam :optionalRenameParam
 :or {optionalParam 1 changedOptionalParam 2}
 }]
 (println mandatoryParam changedParam optionalParam changedOptionalParam))(do-something-awesome {:mandatoryParam 10 :renameParam 20});; Nested objects
(def o {
 :a {
 :x 1
 :y [2, 3]
 }
})
;; With default values
(let [{ {:keys [x y]} :a} o
 [y1,y2] y] ;; forced to add a line to break y to params
 (println x y y1 y2));; y1, y2 don’t get assigned, what’s wrong? a TODO for me to figure out
(let [{ {:keys [x [[y1,y2] :y]]} :a} o]
 (println x y y1 y2))

keys 绑定窗体和常规析构函数的用法是一种很好的用法,而不是只有一种。支持重命名;作为更高层次的绑定形式

现在是时候大开杀戒了。让我们看看上面哪个组合打破了 REPL。

JS Overkill——很难找到这种情况——使用内部析构进行重命名

// Overkill?
var o = {
 “a”: {
 “x”: 1,
 “y”: [2, 3]
 }
};
var {a: {x, y: p = [aa, bb, dd=20], z=10}} = o;
console.log(a, x, y, p, aa, bb, dd, z);
// Throws error, renaming with internal destructuring doesn’t work

Clojure Overkill 更容易被发现。试图在析构对象时析构对象内部的向量。

;; y1, y2 don't get assigned, what’s wrong? a TODO for me to figure out
(let [{ {:keys [x [[y1,y2] :y]]} :a} o]
 (println x y y1 y2))

析构使得代码更直观,更容易编写函数,阅读函数式编程。两者对比,让 Javascript 的函数起源更加清晰。一个新的问题是 Javascript 原型对象属于函数式编程范式吗?

不幸的是,对于 Javascript 用户来说,在所有基于浏览器的 JIT 上使用析构并不完全安全,但是如果你了解你的部署,就去做吧。

一定要让我知道你的想法和你将如何使用它们,并请改进我可能写错的任何东西。

参考文献

Javascript https://developer . Mozilla . org/en/docs/Web/Javascript/Reference/Operators/destructing assignment [https://developer . Mozilla . org/en-US/docs/Web/Javascript/Reference/Operators/Spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator)

Clojure 先看这个很有用——http://blog . brunobonacci . com/2014/11/16/clo jure-complete-guide-to-destructing/ http://clojure.org/guides/destructuring https://gist.github.com/john2x/e1dca953548bfdfb9844

页(page 的缩写)S: PHP 烂,Javascript 美,Java 一致,CSS 再美,客观 C 诡异,Python 敏感(读空白),C#/。网是变种人等等。全是个人观点。

页(page 的缩写)附言:我用来参考的要点

黑客中午是黑客如何开始他们的下午。我们是这个家庭的一员。我们现在接受投稿并乐意讨论广告&赞助机会。

如果你喜欢这个故事,我们推荐你阅读我们的最新科技故事趋势科技故事。直到下一次,不要把世界的现实想当然!


本站为非盈利网站,作品由网友提供上传,如无意中有侵犯您的版权,请联系删除