Performance Coffeescript中的自定义集合和易变性

Performance Coffeescript中的自定义集合和易变性,performance,collections,immutability,coffeescript,Performance,Collections,Immutability,Coffeescript,我正在阅读有关CoffeeScript的文章,并且仍在尝试定位语言、可以做什么、最佳实践是什么等;我更习惯于强类型语言(AS3、Java、Scala),所以我的两个问题可能会让你笑一笑:) 问题1:自定义集合 你觉得定制系列怎么样?JS/CS是这方面最弱的语言之一;例如,没有Array.remove,您必须使用繁琐的splice()方法。一些函数库(如下划线)通过提供将数组/对象作为第一个参数的函数来扩充API,但如果我选择写: list fancyFunction 3, 4 而不是 fanc

我正在阅读有关CoffeeScript的文章,并且仍在尝试定位语言、可以做什么、最佳实践是什么等;我更习惯于强类型语言(AS3、Java、Scala),所以我的两个问题可能会让你笑一笑:)

问题1:自定义集合

你觉得定制系列怎么样?JS/CS是这方面最弱的语言之一;例如,没有Array.remove,您必须使用繁琐的splice()方法。一些函数库(如下划线)通过提供将数组/对象作为第一个参数的函数来扩充API,但如果我选择写:

list fancyFunction 3, 4
而不是

fancyFunction list 3, 4
假设我创建了一个列表类;有可能吗?如果有,这个类能够使用CS的理解语法的必要条件是什么?最坏的情况是,我想列表可能有一个toArray()方法,通常的CS操作可以对返回的值执行,但我希望有更好的解决方案

理想情况下,我希望能够定义丰富的自定义集合,但不会以失去理解等为代价

问题2:可变性

一般来说,人们对CS/JS中的可变性非常小心有什么感觉

当我在网上阅读各种代码时,我的印象是一切都是可变的,人们通常认为最好不要麻烦,而是减少代码行

例如,可变与不变的基本点类:(希望我没有做错什么)

易变的

class Point
  constructor: (@x, @y) ->
不变的

class Point
  constructor: (x, y) ->
    @x = -> x
    @y = -> y

没有那么复杂,但语法有点奇怪。另一个需要考虑的问题是,JS并不是人类已知的最快的东西,仅仅为了成为一个纯粹主义者而在循环中创建大量对象可能会适得其反,性能方面也是如此。不过,我没有将创建新点对象的成本与更改点对象成员的成本作为基准

想象一下,一个大型应用程序中有许多模块通过瘦API进行通信。你不想传递不可变的对象吗?或者你会进行防御性复制

注意:我并不是试图将CS转换成我所知道的语言;相反,我想知道在其他语言中重用一些被视为理所当然的概念是否有意义


谢谢

我认为简单的答案是JavaScript是多功能的,但它是不安全的。没有静态类型,也没有什么是不可变的(除非,如您的示例中所示,通过在不同的范围中隔离)。例如,一些人试图与这种松散性作斗争,谷歌对他们的代码进行了大量的注释,即JavaDoc风格。但主流JavaScript程序员却没有。它们很少在getter后面隐藏实例变量,或者在您使用字符串调用它们的API时抛出异常,而它们需要布尔值。这部分是出于实际原因,JS是我所知道的唯一一种语言,人们通常在这里谈论代码的字节大小,但它也反映了该语言周围的文化,在那里文档和测试的价值远远高于手边的东西

所以,简而言之,我会坚持

constructor: (@x, @y) ->
写一些好的测试。毕竟,您不能防止对API的每一种可能的滥用。最好通过良好的文档和测试来明确它的正确用法

顺便说一句,下划线确实提供了另一种语法,可以让您按照所需的顺序编写代码:

_(list).remove ...

或者您可以扩展[Array]原型。请参阅一些很好的示例。

“JS不是人类已知的最快的东西”>您可能会感到惊讶。由于浏览器战争,JS已经成为世界上速度最快的语言之一。创建对象/函数的开销也可以忽略不计:最后,作为一般规则,我决定采用以下方法:1)使用一个简单的垫片库2)为更丰富的操作创建更丰富的类型(如带有foldL方法的列表等)3)不要过多地考虑封装/不可变性;这似乎是JS中的标准,如果开发人员不是猪,那么它可能工作得很好。