对象克隆是一个棘手的问题,它有很多边缘情况。原因很简单。对象维持内部状态有很多技巧及衍生品,但是很容易被滥用。
克隆对象是你应用程序正在发展的指示器,并且你有一个复杂的对象,你想要作为一个不变的值,即在保持先前状态的同时进行操作。
如果这个对象在你的控制范围之内,那么你很幸运。如果要进行一些重构,可能会让你重新考虑对象的结构和行为来完全避免问题。
随着函数式编程技术的重新兴起,关于不可变数据结构进行了无数次的争论,以及它们如何提供你你所追求的内容。有些人可能会争辩说,可变状态是万恶之源。
我们鼓励使用 Facebook 的 ImmutableJS ,它提供了一整套不可变结构,免费使用。通过重新思考你的对象的内部运作,并将状态与行为分开,通过重新思考你的对象的内部工作和分离状态与行为,使每个函数销毁一个状态来产生一个新的状态 – 非常像 Haskell’s State monad 。这样你可以减少许多麻烦。
如果这个对象不在你的控制范围之内,那么你的运气不好。这可以通过创建复杂的计算来避免,在这些计算中,你可以自己解决循环引用并获得启迪。但是,当你在使用外部对象时,它们必须来自外部来源,然后你可能可以使用另一个外部库来更方便地克隆这个外部对象,并让你只关注最重要的事情,即你应用程序本身。
这样的库有很多,其中一个就是库是 pvorb/clone,它具有非常简单的API。 克隆对象只需要:
var clone = require('clone'); var a = {foo: {bar: 'baz'}}; var b = clone(a); a.foo.bar = 'foo'; console.log(a); // {foo: {bar: 'foo'}} console.log(b); // {foo: {bar: 'baz'}}
当然,还有许多库可以帮你做同样的事情,比如 Ramda,lodash.clonedeep
和 lodash.clone.
作为结束语,如果您认真处理不可变据结结构,您可能需要检查 ClojureScript 或 PureScript 。
我们既不鼓励也不批判使用自制的克隆机制。我们只是注意到在这一领域已经做了大量的工作,而且你可能比重新发明轮子更好。
原文链接:http://www.jstips.co/en/javascript/immutable-structures-and-cloning/
最新评论
写的挺好的
有没有兴趣翻译 impatient js? https://exploringjs.com/impatient-js/index.html
Flexbox playground is so great!
感谢总结。
awesome!
这个好像很早就看到类似的文章了
比其他的教程好太多了
柯理化讲的好模糊…没懂