【问题标题】:Is it bad practice to instantiate variables inside of $(document).ready as opposed to globally declaring them?在 $(document).ready 中实例化变量而不是全局声明它们是不好的做法吗?
【发布时间】:2017-08-02 15:28:10
【问题描述】:

我试图避免在我的代码中使用全局变量,所以我试图通过在$(document).ready 中声明它们并将它们作为参数传递给$(document).ready 之外的函数来解决,更新它们,然后从这些函数返回更新后的值,以操作 $(document).ready 中的变量。

解决此问题的另一种方法是使用hidden 输入字段来存储变量,但我也听说这是不好的做法。

我想知道我是应该只使用全局变量,还是按照我目前的做法,还是使用隐藏的输入字段?

下面是我想要完成的一个简短示例。变量验证是我希望能够使用和更新的变量。

$(document).ready(function(){
    var validations = [];
    $('#inp').keypress(function(e){
        if(e.which == 13){
            e.preventDefault();
            scanValidation(validations, function(valid){
                validations = valid;
            });
        }
    });
}):

function scanValidation(valid, cb){
    var scanval = $('#inp').val();
    if(valid.includes(scanval)){
        //display error
    }
    else{
        var validarr = valid.slice();
        validarr.push(scanval);
        var myData=JSON.stringify({ "name":"user1", "validations":validarr});
        //Makes an ajax call to see if the sent array validarr is a valid request
        apiCall(myData,'scanValidation',function(decoded) {
            if (decoded.Status!="ERROR") {
                valid = validarr;
            }
            else {
                //display error
            }
            return(cb(valid));

        });
    }

}

【问题讨论】:

  • 使用正确范围的变量。范围在哪里取决于要求。您可能想查看 javascript 命名空间,因为听起来您的文档中有很多(阅读:太多)代码。
  • 您能否向我们展示一个示例,说明您在传递给闭包之外的函数时所做的事情?听起来您正在尝试缩小变量范围的正确方法,但只是为了确保。
  • 旁注,隐藏变量不是在 DOM 中存储数据的唯一方式。您还可以使用 data-* 字段在 DOM 中存储逻辑实体的相关信息。使用 jquery 的 data() 以这种方式存储信息将允许从任何可以访问该元素的方法访问它,并且由于它与元素相关联,因此它不是真正的全局。
  • 如果所有内容都在一个文件中,则可以将其全部包装在 IIFE 中,并且所有变量都不是全局变量,但如果在顶级范围内声明,则在该 IIFE 中的任何地方都可用。声明一个全局对象并分配属性而不是单个变量是另一种选择

标签: javascript jquery global-variables


【解决方案1】:

在下面立即执行的函数中声明的任何变量都不会在全局范围内。

(function () {

  var someVar = 'someValue';

  $(document).ready(function() {

  });

})();

【讨论】:

    【解决方案2】:

    $(document).ready 内部实例化变量而不是全局声明它们是不好的做法吗?

    不,一点也不!变量应始终在它们需要的范围内声明,别无他处。

    解决此问题的另一种方法是使用隐藏的输入字段来存储变量,但我也听说这是不好的做法。

    我从来没有听说过,但是是的,这听起来绝对是个坏习惯。这与全局变量相同,但出于某种奇怪的原因存储在 DOM 中的全局变量。

    我试图避免在我的代码中使用全局变量,所以我试图通过在$(document).ready 中声明它们并将它们作为参数传递给$(document).ready 之外的函数来解决问题,更新它们,然后从这些函数返回更新后的值,以操作 $(document).ready 中的变量。

    诚然,这有点奇怪。

    改善这一点的最简单方法是将函数声明也移动到 ready 处理程序中,然后直接访问那里的变量 - 额外的好处是没有 scanValidation 全局变量:

    $(document).ready(function() {
        var validations = [];
        function scanValidation() {
            var scanval = $('#inp').val();
            if (validations.includes(scanval)) {
                //display error
            } else {
                var validarr = validations.slice();
                validarr.push(scanval);
                var myData = JSON.stringify({"name": "user1", "validations": validarr});
                // Makes an ajax call to see if the sent array validarr is a valid request
                apiCall(myData, 'scanValidation', function(decoded) {
                    if (decoded.Status!="ERROR") {
                        validations = validarr;
                    } else {
                        //display error
                    }
                });
            }
        }
    
        $('#inp').keypress(function(e){
            if(e.which == 13){
                e.preventDefault();
                scanValidation();
            }
        });
    });
    

    如果你想让scanValidation 可重用,以便它可以从其他地方调用,也可以使用它自己的数组,我建议创建一个工厂函数来创建验证器,每个验证器都是自己的闭包大批。这样,数组就被声明在它所属的位置,这样函数的用户就不必为他们存储状态:

    function makeScanValidator(display) { // any other configuration
        var validations = [];
        // returns closure
        return function scanValidation(scanval) { // take it as an argument
            if (validations.includes(scanval)) {
                display(/* error */);
            } else {
                var validarr = validations.concat([scanval]);
                var myData = JSON.stringify({"name": "user1", "validations": validarr});
                apiCall(myData, 'scanValidation', function(decoded) {
                    if (decoded.Status!="ERROR") {
                        validations = validarr;
                    } else {
                        display(/* error */);
                    }
                });
            }
        }
    
    $(document).ready(function() {
        var validate = makeScanValidator(function display() { … });
        $('#inp').keypress(function(e){
            if(e.which == 13){
                e.preventDefault();
                validate(this.value);
            }
        });
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-23
      • 2012-08-18
      • 2011-08-13
      相关资源
      最近更新 更多