Изучение JavaSCript при попытке улучшить этот инструмент, поэтому, пожалуйста, прокомментируйте этот простой инструмент ведения журнала JavaScript - PullRequest
1 голос
/ 15 декабря 2009

Я просто пытался изучить и понять исходный код jQuery (пока без особого успеха X_X), чтобы улучшить свои навыки JavaScript. По мере того, как мое понимание JavaScript увеличивается, я пришел к этому небольшому инструменту регистрации / отладки. Что касается моего уровня JavaScript, я публикую здесь код для людей, чтобы судить и проверять. Так что потенциально я могу извлечь уроки из сделанных комментариев. Может кто-нибудь указать на возможные проблемы, улучшения? Я попытался инкапсулировать консольную реализацию и отобразить ее в window. $ Console (единственное место, которое мешает глобальной области видимости).

(function() {
    var proxy = {}, //use private proxy object to prevent binding to global (window) object
        _id = "",
        _warning = false;
        results = {};

    if (this.$console) { //check if $console exists in global (window)
        warning("$console is conflicting with existing object and could not be mapped.");
    }
    else {
        this.$console = proxy; //if undefined we then map proxy to global (window) object
    }

    proxy.init = function(id) { //map the display ol html element on the page
        _id = id;
        results = document.getElementById(id);
        return this;
    }

    proxy.log = function(msg) {
        append(msg);
        return this;
    };

    proxy.assert = function(pass, msg) {
        var html = (pass) ? "<b style=\"color: green;\">Pass</b>, " + msg
                    : "<b style=\"color: red;\">Fail</b>, " + msg ;
        append(html);
        return this;
    }

    proxy.error = function(msg) {
        var html = "<b style=\"color: red;\">Error</b>, " + msg + "";
        append(html);
        return this;
    }

    function append(msg) {
        if (results != null) {
            results.appendChild(getChild("li", msg));
        }
        else {
            warning("Message could not be appended to element with \"Id: " + _id + "\".");
        }
        return this;
    };

    function getChild(type, html) {
        var child = document.createElement(type);
        child.innerHTML = html;
        return child;
    }

    function warning(msg) {
        if (!_warning) {
            _warning = true;
            alert(msg);
        }
    }

    return proxy;
}());

Использование

$console.init("console").log("hello world");
$console.assert(true, "This is a pass.");

ps: поскольку я сделал несколько изменений в коде, вопрос сильно отличается от того, что было изначально.

Ответы [ 3 ]

4 голосов
/ 15 декабря 2009

Кажется, что это будет работать хорошо. Я нахожу, что использование анонимных функций немного сбивает с толку. Поскольку Console не имеет личных данных, почему бы не определить их так:

var Console = {

    instance: document.getElementById('console'),

    Print: function (msg) {
        this.instance.innerHTML += msg;
        return this;
    },

    Log: function (msg) {
        this.Print("<br/>").Print(msg);
    }
};

Я также удалил анонимную функцию, использованную в присваивании instance, поскольку она, похоже, ничего не делает.

Редактировать

Метод оценки анонимной функции обычно используется для скрытия объявленных переменных. См. http://yuiblog.com/blog/2007/06/12/module-pattern/ для обсуждения.

Если, например, вы хотите скрыть свойство instance, вы можете добиться этого с помощью анонимной функции следующим образом:

var Console = (function () {

    // object containing public members to be returned
    var c = {};

    // not visible outside anonymous function
    var instance = document.getElementById('console');

    // a 'public' property
    c.Print = function (msg) {
        instance.innerHTML += msg;
        return this;
    };

    // a 'public' property
    c.Log = function (msg) {
        this.Print("<br/>").Print(msg);
    };

    return c;
}());

Полученный объект Console предоставляет только свойства Print и Log.

2 голосов
/ 15 декабря 2009

Единственная проблема, которую я вижу на данный момент, это то, что вы на самом деле выставляете два глобала, window.Console, что хорошо, так как вы хотите выставить его там, и $c.

Это потому, что вы не используете оператор var в присваивании, должно быть:

 var $c = this.Console;

Если вы не используете его, $c будет глобальным.

Кроме того, может быть, вы захотите поработать над соглашениями об именах, обычно в JavaScript вы называете почти все в camelCase, и только функции конструктора в PascalCase, это просто комментарий, я лично старайтесь придерживаться этого соглашения, но это зависит от вас и вашей команды.

Редактировать: о конкатенации, выполненной с использованием свойства innerHTML, если вы будете обрабатывать большие объемы данных в своем div, я бы порекомендовал вам использовать DOM-манипуляции вместо замены всего innerHTML каждый раз.

Под манипуляциями с DOM я обращаюсь к созданию сообщений журнала как вложенных элементов DOM вашего div, используя document.createElement и element.appendChild.

0 голосов
/ 15 декабря 2009

Я бы попробовал использовать тот же API, что и Firebug, и панель инструментов разработчика IE, чтобы вы могли хорошо деградировать. Одна сборка в этом направлении будет состоять в том, что если window.console уже существует, не выполняйте свой код. Таким образом, вы получите собственный отладчик, когда он будет доступен, иначе вы получите свою реализацию.

...