簡體   English   中英

JavaScript范圍和全局變量

[英]javascript scope and global variables

我試圖避免在對象中使用函數時使用全局變量。 我想在其他函數中調用一個函數,並使用第一個函數作用域中的變量。 例如:

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 buildView全局變量。 我認為使用this方法是正確的做法,因為我是從定義data的函數中調用buildView 如何做到這一點? 謝謝。

您可以沿以下方向傳遞信息:

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

}

無法訪問數據變量本身。 這在本地范圍內是您傳遞給getJSON的匿名函數(並且getJSON將其作為參數傳遞,這超出了您的控制范圍)。

您必須將值復制到某個地方。

在您的特定示例中,除了全局作用域之外,沒有在getDatabuildView之間共享任何作用域。 因此,如果要通過范圍傳遞值,則全局變量是您自己的(糟糕)選項。

您可以簡單地將其作為參數傳遞:

showForecast.buildView(data);

或者,您可以將其存儲為屬性:

showForecast.myData = data;

我喜歡溫尼的回答。

一種全面的方法是用它制作一個模塊:

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的范圍就限於該函數。 這就像一個私有變量。

當您嘗試避免全局時,應考慮使用名稱空間。 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

};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM