Coffeescript || =类比?

时间:2012-03-05 19:18:21

标签: ruby-on-rails coffeescript

我主要是Rails开发人员,因此在为我公司的Hubot实例添加一个小脚本时,我希望能够完成以下任务:

robot.brain.data.contacts ||= {}

或者,如果它尚不存在,则仅生成此新哈希。我的想法是希望通过脚本动态添加联系人数组,这样我就不必修改Hubot的源代码了,我显然不想覆盖我添加的任何联系人。

问题:是否有像Rails || =这样的快速小构造,我可以在Coffeescript中使用它来实现上述目标?

干杯。

6 个答案:

答案 0 :(得分:63)

您可以使用?=进行条件分配:

speed ?= 75

?是CoffeeScript中的“存在运算符”,因此它将测试存在性(不是真实性):

if (typeof speed === "undefined" || speed === null) speed = 75;

在您的情况下,生成的JS有点不同,因为您正在测试对象属性,而不仅仅是变量,因此robot.brain.data.contacts ?= {}会产生以下结果:

var _base, _ref;
if ((_ref = (_base = robot.brain.data).contacts) != null) {
  _ref;
} else {
  _base.contacts = {};
};

更多信息:http://jashkenas.github.com/coffee-script/

答案 1 :(得分:12)

我个人使用or=代替?=,主要是因为当我在Ruby中使用它时,我称之为||=(或等于)。

robot.brain.data.contacts or= {}

不同之处在于or=不是robot.brain.data.contactsnull短路,而?= null测试robot.brain.data.contacts并且只设置{} null如果不是robot

See the compiled difference.

正如另一篇文章所述,这两种方法都没有检查robot.brainrobot.brain.dataor=的存在,但Ruby等价物也没有。

修改

此外,在CoffeeScript ||=和{{1}}中编译为相同的JS。

答案 2 :(得分:7)

?=会指定一个变量nullundefined

speed ?= 25

一样使用它

答案 3 :(得分:4)

它被称为Coffeescript中的存在主义运算符,?=http://coffeescript.org/。引用如下:

  

存在运算符

     

检查变量是否存在有点困难   JavaScript的。如果(变量)接近,但是为零,则为空   string和false。 CoffeeScript的存在运算符?返回true   除非变量为null或未定义,这使得它类似于   Ruby没有?

     

它也可以用于比|| =更安全的条件赋值   提供,用于处理数字或字符串的情况。

答案 4 :(得分:1)

CoffeeScript的Coco方言http://github.com/satyr/coco支持数组和对象自动生成操作符@@@

robot@brain@data@contacts.foo = 1

编译 - 授予,毛茸茸的 -

var _ref, _ref2;
((_ref = (_ref2 = robot.brain || (robot.brain = {})).data || (_ref2.data = {})).contacts || (_ref.contacts = {})).foo = 1;

确保了robot.brainbrain.datadata.contacts实际存在的每个步骤。

当然你可能只想要实际的条件赋值运算符(根据上面的答案,它也存在于CoffeeScript中):

robot.brain.data.contacts ?= {}

编译为

var _ref;
(_ref = robot.brain.data).contacts == null && (_ref.contacts = {});

答案 5 :(得分:0)

a ||= b表示如果a存在,则什么也不做。如果a不存在,则使其等于b

示例1:

a = undefined;
console.log(a ||= "some_string") //prints some_string

示例2:

a = 10
console.log(a ||= "some_string") //prints 10