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
成为全局变量。我认为使用 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;
我喜欢Vinny的回答。
一种回合的方法是用它制作一个模块:
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
};
- 全局变量和全局对象的属性之间有什么区别吗
- delete关键字在全局变量上的不同行为
- Javascript 和 JQuery dom 全局变量范围
- 与javascript全局变量范围和更新混淆
- Javascript - 全局变量和全局范围内的变量是否不同(在 jsfiddle 中)
- 由全局范围内的 Web 应用程序声明的全局变量
- JavaScript 范围和全局变量
- javascript全局变量范围
- 具有动态创建元素的事件处理程序的全局变量范围
- 没有全局变量的变量范围和共享信息
- 全局变量的属性范围
- 如何在另一个Javascript范围内调用全局变量
- JavaScript沙箱:在给定范围内隐藏全局变量
- 是node.js服务器范围内的全局变量,还是只针对该会话或用户
- 如何在Angular2中触发一个应用范围的事件或者观察一个全局变量?
- 如何将 javascript 函数锁定到本地范围?我想阻止它使用全局变量
- Jquery 全局变量范围/错误值
- 全局变量在函数范围内是未定义的
- javascript vs jQuery自定义/全局变量范围
- 模块范围内的全局变量