[英]Proper way to handle scope in JavaScript
我的代码示意性地遵循下面的模式。 重要的是在外部函数中声明了一个参数,该参数稍后在内部函数中使用。
function outer(){
var parameter = 3;
this.value = parameter;
$("#something").on("click", function(target){
target.value = parameter / 2;
});
}
实际上,内部函数是相当多的而且相当冗长,所以我希望将它们移出来以提高可读性,就像这样。
var parameter = 3;
function outer(){
this.value = parameter;
$("#something").on("click", inner);
}
function inner(target){
target.value = parameter / 2;
}
然而,我注意到的是,由于JavaScript的范围范式,我不得不将参数声明移出外部函数,因此使其成为全局,这对我来说似乎是一个缺点。 (实际上,有许多参数被使用,因此直接传递它们会使目的失败。)
我无法确定哪种方法缺点较少。 问题是,是否可以污染全球范围以获得可读性,或者是否绝对禁止。
重新修改你的问题:
问题是,是否可以污染全球范围以获得可读性,或者是否绝对禁止。
这绝对是禁忌。 全球命名空间已经远远受到污染。 并且几乎没有任何理由这样做:相反,您可以根据需要污染使用包含所有代码的范围(近全局,如果您愿意):
(function() {
// Our private scope
var lots, of, vars, here;
function outer() {
// ...
}
function inner() {
// ...
}
})();
这至少可以使你的变量真正成为全局变量。
但是,最好保持变量范围尽可能受限制。 很酷的是你可以根据需要重复上面的内容,为公共代码创建小范围,像matryoshka一样嵌套它们。
问题修订前的早期答案:
如果问题是“什么更好”,答案是:两者都没有。 他们每个人都有自己的位置,对不同的事情都有用。
如果您正在寻找第三种解决方案,您可以使用部分应用程序(有时称为currying,尽管纯粹主义者有问题)。 JavaScript没有内置的部分应用程序功能,不会弄乱this
,但您可以轻松添加一个:
(function() {
// Note use of micro-scope here. It's a micro-optimiziation to avoid
// looping up `slice` every time we need it. Mostly it's a justification
// for demonstrating a micro-scope. :-)
var slice = Array.prototype.slice;
Object.defineProperty(Function.prototype, "curry", { // purists: sorry ;-)
value: function() {
var f = this;
var args = slice.call(arguments, 0);
return function() {
return f.apply(this, args.concat(slice.call(arguments)));
};
}
});
})();
然后
function outer(){
var parameter = 3;
this.value = parameter;
$("#something").on("click", inner.curry(parameter));
}
function inner(parameter, target){
target.value = parameter / 2;
}
你提到过可能有很多这些; 如果是这样,您可能会考虑使用属性的对象,因此您只需要对象引用而不是许多离散变量。
例:
(function() { // Note use of micro-scope here. It's a micro-optimiziation to avoid // looping up `slice` every time we need it. Mostly it's a justification // for demonstrating a micro-scope. :-) var slice = Array.prototype.slice; Object.defineProperty(Function.prototype, "curry", { // purists: sorry ;-) value: function() { var f = this; var args = slice.call(arguments, 0); return function() { return f.apply(this, args.concat(slice.call(arguments))); }; } }); })(); function outer() { var parameter = 3; setTimeout(inner.curry(parameter)); } function inner(parameter) { console.log("Got parameter = " + parameter); } outer();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.