javascript范围和全局变量

时间:2016-02-12 19:02:22

标签: javascript jquery scope this

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

transition: background-size 2s ease-in;
-moz-transition: background-size 2s ease-in;
-ms-transition: background-size 2s ease-in;
-o-transition: background-size 2s ease-in;
-webkit-transition: background-size 2s ease-in;

显然它不起作用。我想在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(); }) } } 内使用data而不使buildView成为全局变量。 我认为使用data将是正确的行动方案,因为我从定义this的函数调用buildView。 怎么能实现这一目标?感谢。

4 个答案:

答案 0 :(得分:2)

您可以传递信息:

@Stateless(name = "xyz")

答案 1 :(得分:1)

无法访问数据变量本身。这是本地作用于您传递给getJSON的匿名函数(并且getJSON将其作为参数传递,这超出了您的控制范围。)

您必须在某处复制值。

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

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

showForecast.buildView(data);

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

showForecast.myData = data;

答案 2 :(得分:1)

我喜欢温尼的回答。

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

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的范围仅限于该功能。它就像一个私有变量。

答案 3 :(得分:0)

As you are trying to avoid global, you should consider using namespaces. There is no such thing called namespace in Javascript. But you can define yourself using small utility method mentioned here.

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

A utility method which helps creating custom namespaces.

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;
};

Define name space

jQuery.namespace( 'jQuery.showForecast' );    

Define methods using revealing module pattern

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

Usage:

You can access only init method as it is exposed to outside.

jQuery.showForecast.init()

Define another namespace

jQuery.namespace( 'jQuery.showForecast.extended' );

jQuery.showForecast.extended = {
// Define some more

};