【问题标题】:javascript scope and global variablesjavascript范围和全局变量
【发布时间】:2016-02-12 19:02:21
【问题描述】:

在对象中使用函数时,我试图避免使用全局变量。 我想在其他函数中调用一个函数并使用第一个函数范围内的变量。 例如:

var showForecast = {
  'init': function () {
    this.getData();
  },
  'buildView': function(){
    var code = "Hey, you're from " + this.data.city;
    $('body').append(code);
  },
  'getData': function () {
    $.getJSON('http://ipinfo.io/', function (data) {
      console.log(data);
      showForecast.buildView();
    })
  }
}

显然它不起作用。我想在 buildView 中使用 data 而不使 data 成为全局变量。 我认为使用this 是正确的做法,因为我从定义data 的函数中调用buildView。 如何做到这一点?谢谢。

【问题讨论】:

  • @Oriol — buildView 从回调中调用,因此异步无关紧要。
  • 好的,我误解了代码。

标签: javascript jquery scope this


【解决方案1】:

您可以传递信息:

var showForecast = {
'init': function () {
    this.getData();
},
'buildView': function(data){
    var code = 'Hey, you\'re from ' + data.city;
    $('body').append(code);
},
'getData': function () {
    $.getJSON('http://ipinfo.io/', function (data) {
        console.log(data);
        showForecast.buildView(data);
    })
}

}

【讨论】:

    【解决方案2】:

    无法访问数据变量本身。这在本地限定为您传递给 getJSON 的匿名函数(getJSON 将其作为参数传递,这是您无法控制的)。

    您必须将值复制到某处。

    在您的特定示例中,除了全局范围之外,getDatabuildView 之间没有共享范围。因此,如果您想通过作用域传递值,那么全局是您自己的(可怕的)选项。

    您可以简单地将其作为参数传递:

    showForecast.buildView(data);
    

    或者您可以将其存储为属性:

    showForecast.myData = data;
    

    【讨论】:

      【解决方案3】:

      我喜欢文尼的回答。

      一种循环方式是用它制作一个模块:

      var showForecast = function(){
          var data;
          var init = function () {
              this.getData();
          };
          var buildView = function(){
              var code = 'Hey, you\'re from ' + this.data.city;
              $('body').append(code);
          };
          var getData = function () {
              $.getJSON('http://ipinfo.io/', function (data) {
                  console.log(data);
                  this.data = data;
                  showForecast.buildView();
              })
          };
          return {
              'init': init,
              'buildView': buildView,
              'getData': getData
          };
      }();
      

      这样var data 的范围仅限于函数。它就像一个私有变量。

      【讨论】:

        【解决方案4】:

        当您试图避免全局时,您应该考虑使用命名空间。 Javascript 中没有称为命名空间的东西。但是你可以使用这里提到的小工具方法来定义自己。

        http://www.zachleat.com/web/namespacing-outside-of-the-yahoo-namespace/

        帮助创建自定义命名空间的实用方法。

        jQuery.namespace = function() {
            var a=arguments, o=null, i, j, d;
            for (i=0; i<a.length; i=i+1) {
                d=a[i].split(".");
                o=window;
                for (j=0; j<d.length; j=j+1) {
                    o[d[j]]=o[d[j]] || {};
                    o=o[d[j]];
                }
            }
            return o;
        };
        

        定义名称空间

        jQuery.namespace( 'jQuery.showForecast' );    
        

        使用显示模块模式定义方法

        https://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript

         jQuery.showForecast = (function() {
        
          var data;
        
          var init = function() { 
            getData();
          }
        
          var buildView = function() {
            var code = "Hey, you're from " + data.city;
            $('body').append(code);
          }
        
          var getData = function() {        
            $.getJSON('http://ipinfo.io/', function(_data) {
              console.log(data);
              data = _data;
              buildView();
            })
        
          }
        
          return {
            init: init
          };
        
        })(); // Execute it immediately
        

        用法:

        您只能访问 init 方法,因为它暴露在外部。

        jQuery.showForecast.init()
        

        定义另一个命名空间

        jQuery.namespace( 'jQuery.showForecast.extended' );
        
        jQuery.showForecast.extended = {
        // Define some more
        
        };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-09-30
          • 2013-05-26
          • 2010-10-07
          • 1970-01-01
          • 2012-07-17
          • 2013-01-24
          • 2012-11-05
          • 1970-01-01
          相关资源
          最近更新 更多