Изучая JavaSCript при попытке улучшить этот инструмент, пожалуйста, прокомментируйте этот простой инструмент ведения журнала JavaScript.


1

Я просто пытался узнать и понять исходный код jQuery (пока с небольшим успехом X_X), чтобы улучшить свои навыки JavaScript. По мере того как я понимаю увеличение JavaScript, я придумал этот небольшой инструмент для ведения журнала/отладки. По состоянию на мой уровень JavaScript я размещаю здесь код для оценки и аудита. Поэтому я могу извлечь уроки из сделанных комментариев. Может ли кто-нибудь указать на потенциальные проблемы, улучшения? Я попытался инкапсулировать реализацию консоли и сопоставить ее с окном. $ 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."); 

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

  0

Какие браузеры? Из NS4 +? Мобильные телефоны? 15 дек. 092009-12-15 04:29:09

  0

Мне просто нужна оценка кода, потому что я не так хорошо разбираюсь в JavaScript. 15 дек. 092009-12-15 04:29:45

+1

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

  0

Если вы хотите быть уверены, что этот код работает кросс-браузер, почему бы просто не протестировать его в нескольких браузерах? На самом деле нет другого пути, который вы можете точно знать. 15 дек. 092009-12-15 05:49:02

  0

Возможно, было бы лучше задать новый вопрос, вместо того чтобы менять его после того, как уже были даны несколько ответов. 17 дек. 092009-12-17 04:29:39

  0

Да, но я вроде думаю, что это все еще связано с моим старым вопросом. 17 дек. 092009-12-17 05:34:41

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 (большинство из них я не понимаю), но я взял стиль ...^_^ 15 дек. 092009-12-15 04:34:11

  0

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

  0

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

+1

+1 это * много * более читаемо. 15 дек. 092009-12-15 04:41:02

  0

@harto: Я думаю, что в вашем втором примере цепочка методов нарушена. 15 дек. 092009-12-15 05:10:22

  0

@harto: возможно ли сделать печать конфиденциальной, если она сможет цеплять метод? 15 дек. 092009-12-15 05:14:15

  0

О да, крики. Я исправлю это 15 дек. 092009-12-15 05:30:47

  0

@Jeffrey - я не мог придумать очевидный способ выполнения цепочек методов, поэтому я просто открыл обе функции во втором примере. Вы могли бы сделать это, используя 'apply()' или что-то вроде этого 15 дек. 092009-12-15 05:37:26

  0

@hardo: и я думаю, вам нужно использовать return c вместо возврата. так как это будет загрязнять глобальную сферу, о которой я думаю, поскольку вы не используете новое ключевое слово? 15 дек. 092009-12-15 05:38:24

  0

@ Jeffrey-ehh ... когда вы вызываете 'Console.Print ('foo')', возвращаемый объект тот же, что и 'c' в функции. 'c' возвращается из анонимной функции, которая присваивается переменной' Console'. Возможно, это иллюстрирует, почему мой первый пример лучше :) 15 дек. 092009-12-15 05:46:53

  0

@hardo: на самом деле я думаю, что теперь я запутался, и я не уверен, могу ли я сказать разницу между var console = {}; и var console = (function() {}()) ;. 15 дек. 092009-12-15 06:51:27

  0

@Jeffrey - Я предлагаю прочитать ссылку в своем ответе - это может дать вам лучшую идею. Извините за смущение. Я бы просто придерживался первой формы, которую я предложил в своем ответе. 15 дек. 092009-12-15 08:15:24


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 - Я пропустил, что у него нет «вар». 15 дек. 092009-12-15 04:32:28

  0

Я исправил его. Я пропустил это ... 15 дек. 092009-12-15 04:32:54


0

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

+2

Вы бы разработали? 15 дек. 092009-12-15 04:45:03

  0

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