[英]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
將其作為參數傳遞,這超出了您的控制范圍)。
您必須將值復制到某個地方。
在您的特定示例中,除了全局作用域之外,沒有在getData
和buildView
之間共享任何作用域。 因此,如果要通過范圍傳遞值,則全局變量是您自己的(糟糕)選項。
您可以簡單地將其作為參數傳遞:
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.