2009-12-15 2 views
1

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

(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."); 

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

+0

Какие браузеры? Из NS4 +? Мобильные телефоны? –

+0

Мне просто нужна оценка кода, потому что я не так хорошо разбираюсь в JavaScript. – Jeff

+1

Ближе всего я могу найти, чтобы обратиться к вашей строке 'innerHTML + =': http://stackoverflow.com/questions/1387433/fastest-way-to-append-html-content-to-a-div-using-javascript/1387475 # 1387475 –

ответ

4

Кажется, он будет работать нормально. Тем не менее, я считаю, что использование анонимных функций немного запутанно. Поскольку 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 свойства.

+0

В чем разница по сравнению с вашим стилем? Я просто читал исходный код jQuery (большинство из них я не понимаю), но я взял стиль ...^_^ – Jeff

+0

@Jeffrey: разница harto делает без всякой функции '(function() {})() 'cruft. Читателям кода легче понять, что такое структура объектов 'Console'. –

+0

Обычно я использовал бы только анонимный стиль функции, если бы захотел инкапсулировать/скрыть некоторые данные - я нахожу буквенное обозначение объекта (то есть 'var foo = {...}') немного понятным. – harto

2

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

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

var $c = this.Console; 

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

Помимо этого, может быть, вы можете работать на именовании, как правило, в JavaScript вы называете почти все в camelCase, и только constructor functions в PascalCase, это просто комментарий, я лично стараюсь придерживаться этой конвенции, но до вы и ваша команда.

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

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

+0

+1 - Я пропустил, что у него нет «вар». –

+0

Я исправил его. Я пропустил это ... – Jeff

0

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

+2

Вы бы разработали? – Jeff

+0

В основном, они предоставляют API, который имеет методы «log», «info», «warn», «error» и т. Д., Чтобы обозначать разные типы сообщений. Не важно, что вы делаете их по-разному, но если я использую для запуска моего кода в FF, у меня могут быть такие типы операторов журналов. Кроме того, если я работаю в FF, я ожидаю получить эти сообщения в Firebug. Однако, если я нахожусь в IE 6, было бы здорово получить эти сообщения в той или иной форме или моде. Вот где ваш код может добавить в утилиту ведения журнала, если window.console не определено. – Bialecki

Смежные вопросы