Ошибка неиспользуемой переменной JSLint

#javascript #variables #validation #jslint

#javascript #переменные #проверка #jslint

Вопрос:

Я создал документ javascript и хочу сделать этот JSLint действительным.

http://pastebin.com/GvZLyNbV

 /*jslint browser: true, indent: 2 */
/*global ActiveXObject: true, window: true*/
(function (window) {
  "use strict";
  /**
   * ajax class
   * 
   * ez az objektum fogja kezelni az ajax kérelmeket. lényege hogy nagyon 
   * minimális legyen. nem akarom jobban magyarázni, eléggé bonyolult, mert a
   * különböző böngészők különbözően kezelik az ajax hívásokat.
   */
  var ajax = window.ajax = {};

  ajax.XHR = {
    getXHR: function () {
      var http;
      try {
        http = new XMLHttpRequest();
        this.getXHR = function () {
          return new XMLHttpRequest();
        };
        return http;
      } catch (e) { }

      try {
        http = new ActiveXObject("MSXML2.XMLHTTP.3.0");
        this.getXHR = function () {
          return new ActiveXObject("MSXML2.XMLHTTP.3.0");
        };
        return http;
      } catch (f) { }

      try {
        http = new ActiveXObject("MSXML2.XMLHTTP");
        this.getXHR = function () {
          return new ActiveXObject("MSXML2.XMLHTTP");
        };
        return http;
      } catch (g) { }

      try {
        http = new ActiveXObject("Microsoft.XMLHTTP");
        this.getXHR = function () {
          return new ActiveXObject("Microsoft.XMLHTTP");
        };
        return http;
      } catch (h) { }
    },

    call: function (method, uri, callback, postData) {
      var xhr = this.getXHR();

      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 amp;amp; xhr.status === 200) {
          if (typeof callback === "function") {
            callback(xhr);
          }
        }
      };

      xhr.open(method, uri, true);

      if (method === "POST") {
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        //xhr.setRequestHeader("Content-length", postData.length);
        //xhr.setRequestHeader("Connection", "close");
        xhr.send(postData);
      } else {
        xhr.send(null);
      }
      return xhr;
    }
  };



  /////////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////
  /**
   * periodic object
   * 
   * Ez az osztály kezeli a periodikus hívások egyesítését. Hozzá tudunk adni 
   * listenereket
   * @see ajax.ListenerObj
   * 
   * Az a lényege hogy az összes listenert átnézi és egyesíti a requesteket
   * így egy kérelemben egybe elküldi az összes requestet.
   * 
   * @todo Jobban kellene rendezni az osztályt, ne csak így a levegőben lógjon,
   * meg majd bele kell venni a benchmark osztályt is meg jobban kell időzíteni.
   * 
   */

  ajax.periodic = {};


  ajax.periodic.isListen = false;
  ajax.periodic.timer = null;
  ajax.periodic.listenDelay = 5000;
  ajax.periodic.url = "ajax.php";
  ajax.periodic.listeners = [];

  /**
   * Ezzel a függvénnyel indítjuk el a periodikus hívásokat
   */
  ajax.periodic.startListen = function () {
    window.clearTimeout(ajax.periodic.timer);
    ajax.periodic.isListen = true;
    ajax.periodic.listen();
  };

  /**
   * Ezzel a fügvénnyel állítjuk le a periodikus hívásokat 
   */
  ajax.periodic.stopListen = function () {
    window.clearTimeout(ajax.periodic.timer);
    ajax.periodic.isListen = false;
  };

  /**
   * Ezzel a fügvénnyel adhatunk új ListenerObj objektumot a periodic osztályhoz
   * 
   * @see ajax.ListenerObj
   */
  ajax.periodic.addListener = function (obj) {
    if (obj instanceof ajax.ListenerObj) {
      ajax.periodic.listeners.push(obj);
    }
  };

  /**
   * Ezzel a fügvénnyel törölhetünk egy ListenerObj objektumot a periodic
   * osztályból
   * 
   * @see ajax.ListenerObj 
   */
  ajax.periodic.removeListener = function (obj) {
    var i = ajax.periodic.listeners.indexOf(obj);
    if (i >= 0) {
      ajax.periodic.listeners.splice(i, 1);
    }
  };

  /**
   * Ezzel a fügvénnyel kérdezzük le az össze ListenerObj objektum paramját
   * 
   * @param method : Ez "GET" vagy "POST" lehet
   * @param escape : Ez az hogy encodolja-e a tartalmat (default true)
   */
  ajax.periodic.getListenersQueries = function (method, escape) {
    var allQueries = new ajax.QueryCollection(),
      i;
    escape = (escape === false) ? false : true;
    for (i = 0; i < ajax.periodic.listeners.length; i  = 1) {
      if (ajax.periodic.listeners[i].isListen()) {
        allQueries.mergeCollection(ajax.periodic.listeners[i].queries);
      }
    }

    return allQueries.queriesToString(method, escape);
  };

  /**
   * Ez a függvény meghíváskor elindul, és periodicc.delay időközönként
   * újrahívja magát. Az AJAX válaszban kapott adatot továbbítja a ListenerObj
   * objektumoknak.
   */
  ajax.periodic.listen = function () {
    if (!ajax.periodic.isListen) {
      return;
    }

    var startTime = (new Date()).getTime(),
      uri = ajax.periodic.url   "?"   ajax.periodic.getListenersQueries("get"),
      postData = ajax.periodic.getListenersQueries("post"),
      i;

    for (i = 0; i < ajax.periodic.listeners.length; i  = 1) {
      ajax.periodic.listeners[i].setRequest(true);
    }

    ajax.XHR.call("POST", uri, function (data, status) {
      var i, delay;

      for (i = 0; i < ajax.periodic.listeners.length; i  = 1) {
        if (ajax.periodic.listeners[i].isRequest() === true) {
          ajax.periodic.listeners[i].setRequest(false);
          ajax.periodic.listeners[i].parse(data);
        }
      }

      delay = (new Date()).getTime() - startTime;
      ajax.periodic.timer = window.setTimeout(ajax.periodic.listen, ((delay < ajax.periodic.listenDelay) ? ajax.periodic.listenDelay - delay : 0));
    }, postData);
  };

  /**
   * paraméterben megadott listener egyszer requesteli.
   */
  ajax.periodic.request = function (listener, func) {
    func = (typeof func === "function") ? func : function () {};

    ajax.XHR.call("POST", ajax.periodic.url   "?"   listener.queries.queriesToString("GET"), function (data, status) {
      func(data);
    }, ajax.listener.queries.queriesToString("POST"));
  };





  /////////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////

  /**
   * ajax.QueryCollection class
   * 
   * Ez az osztály a query paramétereket tárolja el.
   */
  ajax.QueryCollection = function () {
    var queryArray = [];

    this.queryArray = queryArray;


    /**
     * Query paraméter hozzáadása
     */
    this.addQuery = function (method, name, value) {
      if (!method || !name) {
        return this;
      }

      method = method.toString().toLowerCase();
      name = name.toString();
      value = (value === undefined) ? "" : value.toString();

      var i;
      for (i = 0; i < queryArray.length; i  = 1) {
        if (queryArray[i].method === method amp;amp; queryArray[i].name === name) {
          queryArray[i].value = value;
          return;
        }
      }
      //if not found then add a new
      queryArray.push({
        "method": method,
        "name": name,
        "value": value
      });
    };

    /**
     * Query paraméter törlése
     */
    this.removeQuery = function (method, name) {
      var i;
      for (i = 0; i < queryArray.length; i  = 1) {
        if (queryArray[i].method === method amp;amp; queryArray[i].name === name) {
          queryArray[i].splice(i, 1);
          return;
        }
      }
    };

    /**
     * Két ilyen osztály egyesítése
     */
    this.mergeCollection = function (obj) {
      if (!obj instanceof ajax.QueryCollection) {
        return;
      }
      var i;
      for (i = 0; i < obj.queryArray.length; i  = 1) {
        this.addQuery(obj.queryArray[i].method, obj.queryArray[i].name, obj.queryArray[i].value);
      }
    };

    /*
     * Az argumentumban található osztály querijainak törlése ebből az osztályból
     */
    this.splitCollection = function (obj) {
      if (!obj instanceof ajax.QueryCollection) {
        return;
      }
      var i;
      for (i = 0; i < obj.queryArray.length; i  = 1) {
        this.removeQuery(obj.queryArray[i].method, obj.queryArray[i].name);
      }
    };

    /*
     * Queryk egyesítése stringbe
     */
    this.queriesToString = function (method, escape) {
      var str = "",
        cnt = 0,
        i;

      escape = (escape === false) ? false : true;

      for (i = 0; i < queryArray.length; i  = 1) {
        if (queryArray[i].method === method) {
          if (cnt !== 0) {
            str  = "amp;";
          }

          cnt  = 1;

          str  = queryArray[i].name;

          if (queryArray[i].value !== "") {
            str  = "=";

            if (escape === true) {
              str  = encodeURIComponent(queryArray[i].value);
            }
            else {
              str  = queryArray[i].value;
            }
          }
        }
      }
      return str;
    };
  };

  /*
   * ajax.ListenerObj class
   * 
   * Ez az osztály arra való hogy segítségvel csinálhatok listener objektumokat
   * amiknek beállíthatok queriket.
   */
  ajax.ListenerObj = function () {

    var isListen = false,
      isRequest = false,
      parserFunc = function () {};

    this.queries = new ajax.QueryCollection();

    this.setListen = function (a) {
      isListen = (a) ? true : false;
    };
    this.isListen = function () {
      return isListen;
    };

    this.setRequest = function (a) {
      isRequest = (a) ? true : false;
    };

    this.isRequest = function () {
      return isRequest;
    };

    this.setParser = function (a) {
      if (typeof a === "function") {
        parserFunc = a;
      }
      return this;
    };

    this.parse = function (data) {
      parserFunc(data);
    };
  };

}(window));
  

Когда я проверяю это с помощью JSLint, я получаю эту ошибку:

 Error:
Unused variable: status 182 'uri', status 203 'GET'
  

Я не понимаю, что я должен исправить. Используется uri переменная, которая 'GET' является строковой константой, а не переменной.

Итак, я в полном замешательстве.

Комментарии:

1. Сайты, подобные pastebin, могут быть полезным дополнением к вашему вопросу, но всегда включают соответствующий код в сам вопрос . Людям, пытающимся вам помочь, не нужно переходить на другой сайт, а внешние ссылки могут измениться / переместиться / исчезнуть, что сделает ваш вопрос совершенно бесполезным для кого-либо еще в будущем. Кроме того, в этом случае вы ссылаетесь на массивный пример кода. Вам нужно потратить некоторое время на устранение проблемы.

2. мой код имеет длину 369 строк. действительно ли это хорошая практика для включения в вопрос?

3. @omnosis : А) Да, и Б) Лучше сосредоточиться на проблеме, а не ожидать, что люди прочитают 369 строк вашего кода.

Ответ №1:

В вашем коде, начиная со строки 182, есть функция, в которую вы передаете, ajax.XHR.call которая объявляет переменную, status , которую вы никогда не используете:

 //                         |-- Function starts here
//                         V               V-- Variable (argument) `status`, never used
ajax.XHR.call("POST", uri, function (data, status) {
  var i, delay;

  for (i = 0; i < ajax.periodic.listeners.length; i  = 1) {
    if (ajax.periodic.listeners[i].isRequest() === true) {
      ajax.periodic.listeners[i].setRequest(false);
      ajax.periodic.listeners[i].parse(data);
    }
  }

  delay = (new Date()).getTime() - startTime;
  ajax.periodic.timer = window.setTimeout(ajax.periodic.listen, ((delay < ajax.periodic.listenDelay) ? ajax.periodic.listenDelay - delay : 0));
}, postData);
  

Вы можете избавиться от ошибки, удалив аргумент из подписи функции. Или вы можете проигнорировать это, потому что очень важно помнить, что JSLint — это все о стиле кодирования Дугласа Крокфорда, который может быть или не быть тем, что вы считаете подходящим для вашего собственного стиля кодирования. Вы также можете посмотреть на JSHint, который дает вам больше контроля над параметрами.

Комментарии:

1. Удаление параметра работает в этом сценарии, но не всегда. Не игнорируйте предупреждение, оно поднимает отличный вопрос. Почему я должен называть параметры, которые я не собираюсь использовать? Возможно, если бы они использовали jQuery, они бы переосмыслили идею наличия такого количества параметров в своих сигнатурах обратного вызова, возможно, они бы заключили их в объект. Обратный вызов ajax.error имеет 3 параметра перед единственным, который я хочу, ‘exception’. Я никогда не думал об этом до предупреждения, теперь я буду думать об этом для каждой функции, которую я пишу, и я думаю, что я остался лучшим разработчиком для этого.

2. @JasonKostempski: Да, я бы никогда не указал на jQuery как на отличный пример дизайна API. 🙂 (И я бы не стал особо надеяться, что было бы лучше, если бы дизайнеры использовали инструменты lint [что вполне могло быть].) Но почти у всех вариантов дизайна есть свои плюсы и минусы, и не всегда очевидно, на какие из них обратить внимание. Хороший момент в том, что вы действительно думаете о пользователях вашего API при его разработке, и хвала тому, что вы являетесь инженером, который явно всегда пытается улучшить.

Ответ №2:

Неиспользуемая переменная: статус 182 ‘uri’, статус 203 ‘GET’

Означает, что у вас есть неиспользуемая переменная status в строках 182 и 203.

Комментарии:

1. Извините. Но моя проблема в том, что я использую uri . В этом проблема.

2. проблема не в uri или GET, а в «статусе». ваша неиспользуемая переменная — «статус».

3. пфф. я просто запутался. попытался выяснить проблему с uri. Я не знаю, почему JSLint написал это.