使用把手迭代 javascript 对象

发布于 2025-01-02 08:13:30 字数 1001 浏览 0 评论 0原文

我正在尝试向 Handlebars 注册助手,以允许迭代 JSON 对象。 这个要点看起来是一个合适的解决方案。我将其转换为以下 CoffeeScript。当我使用任何一个帮助程序时,似乎什么都没有发生(这对于普通 JavaScript 和 CoffeeScript 版本都适用)。有什么想法吗?

$ ->
  Handlebars.registerHelper "key_value", (obj, fn)->
    buffer = ""
    key 
    for key in obj 
      if obj.hasOwnProperty(key)
        buffer += fn({key: key, value: obj[key]})
    buffer

  Handlebars.registerHelper "each_with_key", (obj, fn)->
    context
    buffer = ""
    key 
    keyName = fn.hash.key
    for key in obj 
      if obj.hasOwnProperty(key)
        context = obj[key]
        if keyName
          context[keyName] = key 
          buffer += fn(context)
    buffer

在模板中:

{{#key_value categories}}
I'M ALIVE!!
{{/key_value}}

{{#each_with_key categories key="category_id"}}
I'M ALIVE!!
{{/each_with_key}}

我目前正在 Gemfile 中使用 gem 'handlebars-assets' 将车把添加到 Rails 应用程序中。

I am trying to register helpers with Handlebars to allow iterating over JSON objects. This gist looked like an appropriate solution. I converted that into the following CoffeeScript. Nothing seems to happen when I use either of the helpers (that holds true for both vanilla JavaScript and the CoffeeScript version). Any ideas?

$ ->
  Handlebars.registerHelper "key_value", (obj, fn)->
    buffer = ""
    key 
    for key in obj 
      if obj.hasOwnProperty(key)
        buffer += fn({key: key, value: obj[key]})
    buffer

  Handlebars.registerHelper "each_with_key", (obj, fn)->
    context
    buffer = ""
    key 
    keyName = fn.hash.key
    for key in obj 
      if obj.hasOwnProperty(key)
        context = obj[key]
        if keyName
          context[keyName] = key 
          buffer += fn(context)
    buffer

In the template:

{{#key_value categories}}
I'M ALIVE!!
{{/key_value}}

{{#each_with_key categories key="category_id"}}
I'M ALIVE!!
{{/each_with_key}}

I am currently using gem 'handlebars-assets' in the Gemfile to add handlebars to a rails app.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

吻风 2025-01-09 08:13:30

您的 JavaScript 到 CoffeeScript 的音译已损坏。您不使用 for ... in 来迭代 CoffeeScript 中的对象,而是使用 for k, v ...

使用 of 来表示对对象属性的理解,而不是对数组中的值的理解。

这个 CoffeeScript 循环:

for x in y
    ...

变成这个 JavaScript:

for (_i = 0, _len = y.length; _i < _len; _i++) {
  x = a[_i];
  ...
}

所以如果 y 是一个没有 length 属性的对象,那么 _len 将是 undefined 和 JavaScript for(;;) 循环根本不会迭代。

您还应该使用 own 而不是 hasOwnProperty

如果您只想迭代对象本身定义的键,请添加 hasOwnProperty 检查以避免可能从原型中迭代的属性,请使用 for own对象的键,值

但这更多是为了方便而不是正确性。

另外,CoffeeScript 循环是表达式,因此您通常会说 array = expr for own k, v in o 或等效形式:

array = for own k, v in o
    expr

if expr 超过一行或太多很长以便于可读理解。

CoffeeScript 中助手的正确且更惯用的版本看起来更像是这样的:

Handlebars.registerHelper "key_value", (obj, fn)->
    (fn(key: key, value: value) for own key, value of obj).join('')

Handlebars.registerHelper "each_with_key", (obj, fn)->
    key_name = fn.hash.key
    buffer   = for own key, value of obj
        value[key_name] = key
        fn(value)
    buffer.join('')

演示: http://jsfiddle.net/ambigously/LWTPv/

Your JavaScript to CoffeeScript transliteration is broken. You don't use for ... in to iterate over an object in CoffeeScript, you use for k, v of ...:

Use of to signal comprehension over the properties of an object instead of the values in an array.

This CoffeeScript loop:

for x in y
    ...

becomes this JavaScript:

for (_i = 0, _len = y.length; _i < _len; _i++) {
  x = a[_i];
  ...
}

So if y is an object without a length property, then _len will be undefined and the JavaScript for(;;) loop won't iterate at all.

You should also be using own instead of hasOwnProperty:

If you would like to iterate over just the keys that are defined on the object itself, by adding a hasOwnProperty check to avoid properties that may be interited from the prototype, use for own key, value of object.

but that's more for convenience than correctness.

Also, CoffeeScript loops are expressions so you'd usually say array = expr for own k, v in o or the equivalent form:

array = for own k, v in o
    expr

if expr is more than one line or too long to allow for a readable comprehension.

A correct and more idiomatic version of your helpers in CoffeeScript would look more like this:

Handlebars.registerHelper "key_value", (obj, fn)->
    (fn(key: key, value: value) for own key, value of obj).join('')

Handlebars.registerHelper "each_with_key", (obj, fn)->
    key_name = fn.hash.key
    buffer   = for own key, value of obj
        value[key_name] = key
        fn(value)
    buffer.join('')

Demo: http://jsfiddle.net/ambiguous/LWTPv/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文