繁体   English   中英

在JavaScript中处理范围的正确方法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM