如何避免CoffeeScript方法变量被包装在对象文字中?

时间:2012-02-21 15:24:32

标签: javascript coffeescript scope

CoffeeScript包装在对象文字中的方法内声明的变量。

所以,这个:

@Templates =
    get: (templateName) ->
        result: ''              # DECLARED HERE
        $.ajax(
            'Views/Templates/' + templateName + '.html',
            type: 'GET'
            dataType: 'html'
            success: (data) ->
                result = data   # ASSIGNED HERE
            async: false
        )
        return result           # RETURNED HERE

成为这个:

(function() {

  this.Templates = {
    get: function(templateName) {
      ({
        result: ''                  //DECLARED IN AN OBJECT LITERAL - I DON'T WANT THIS
      });
      $.ajax('Views/Templates/' + templateName + '.html', {
        type: 'GET',
        dataType: 'html',
        success: function(data) {
          var result;               //DECLARED LOCAL TO THE CALLBACK - I DON'T WANT THIS
          return result = data;
        },
        async: false
      });
      return result;                //RETURNED HERE - UNASSIGNED
    }
  };

}).call(this);

但我需要的,这对我有用,就是:

(function() {

  this.Templates = {
    get: function(templateName) {
      var result = ''               //DECLARED HERE
      $.ajax('Views/Templates/' + templateName + '.html', {
        type: 'GET',
        dataType: 'html',
        success: function(data) {
          return result = data;     //ASSIGNED HERE
        },
        async: false
      });
      return result;                //RETURNED HERE
    }
  };

}).call(this);

我做错了什么?我该如何解决这个问题?

3 个答案:

答案 0 :(得分:4)

你所谓的闭包不是一个闭包(JavaScript中的闭包始终是函数)。它是用括号括起来的对象文字。

我不太喜欢CoffeeScript,但是如果你希望result成为get函数中的局部变量,我相信你想要改变

result: ''

result = ''

前者是对象初始化器格式(因此它被翻译成对象文字),后者是变量赋值。似乎在lexical scoping下的CoffeeScript网站上有所介绍。

答案 1 :(得分:2)

为什么使用:?它没有被封装在一个闭包中,你只是定义了一个匿名对象表达式。

这样做:

result = ''

那就是说,为什么要进行同步GET?这是非常不满意的,并且会使你的网站反应迟钝。

答案 2 :(得分:2)

通过result: ''声明对象的属性。您需要的是通过result = ''声明一个局部变量:

get: (templateName) ->
    result = ''              # DECLARED HERE
    $.ajax(
        'Views/Templates/' + templateName + '.html',
        type: 'GET'
        dataType: 'html'
        success: (data) ->
            result = data   # ASSIGNED HERE
        async: false
    )
    return result           # RETURNED HERE