Пример хорошего кода
Решил повысить свои уровень и разобраться, как пишут код крутые мальчики и девочки. Для этого взял кусочек из Бутстрапа (его же крутые мальчики и девочки пишут :)) и попытался разобраться.
Выкладываю урезанный фрагмент со своими комментариями. Ответьте пожалуйста, на вопросы /* ? */ до которых не догнал. Возможно кто-то объяснит смысл построения кода именно таким образом или подскажет лучший способ. $('#example').tooltip(options) // Создаем объект tooltip для объекта с id="example". И начинается самое интересное. Ниже фрагмент из Бутстраповского плагина, вызывающего всплывающие подсказки !function ($) { /*? !function ($) {}(window.jQuery); что за конструкция ?*/ "use strict"; // jshint ;_; — это не мой комментарий. Что они хотели этим сказать? // Strict Mode накладывает слой ограничений на JavaScript, он отгораживает вас от опасных частей языка (те части, которые есть исторически, но лучше чтобы их не было) и позволяет снизить вероятность ошибки. // А еще Strict Mode не оборачивает функцию в объект, из-за чего выполнение происходит быстрее /*? Strict Mode распространяется на объекты созданные в функции? Если да, то результат выполнения методов на строках ["".metod()] тоже будет оптимизироваться ?*/ /* TOOLTIP PUBLIC CLASS DEFINITION * =============================== */ var Tooltip = function (element, options) { /*? зачем передавать в конструктор параметр element если он передается из цепочки jQuery [$('#example')] ?*/ this.init('tooltip', element, options) } Tooltip.prototype = { constructor: Tooltip // переопределяем стандартное свойство constructor. Иначе затрется /*? нужно ли это? может проще всегда создавать через new ?*/ , init: function (type, element, options) { this.type = type this.$element = $(element) /*? начинать переменные, в которых объекты jQuery, с $ хороший стиль ?*/ this.options = this.getOptions(options) /*? теперь в нашем объекте и defaults и options. Может лучше defaults перезаписать значениями из options ?*/ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) /*? 'click.' + this.type = 'click.tooltip' Это что такое ?*/ /*? Как-то через proxy не очень красиво. Может лучше что-то вроде этого $.bind("click", function(e) {this = e.target}) ?*/ } , getOptions: function (options) { options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data()) // Тут мы ищем наш метод [tooltip] в объекте jQuery и передаем из него дефолтные параметры, попутно обновляя их парметрами из options и this.$element.data() // {} отвечает за то, чтобы дефолтные параметры не изменились в прототипе + чтобы были заменены только те, что есть в options и т.п. // В итоге в переменной options у нас все неуказанные параметры равны дефолтным if (options.delay && typeof options.delay == 'number') { /*? Проверка №1 Зачем проверять options.delay? Зачем, вообще, обе проверки, если потом еще одна будет ?*/ options.delay = { show: options.delay , hide: options.delay } } return options } , enter: function (e) { var self = $(e.currentTarget)[this.type](this._options).data(this.type) /*? _options, зачем называть с подчеркивания ?*/ if (!self.options.delay || !self.options.delay.show) return self.show() /*? Проверка №2. Зачем проверять self.options.delay ?*/ } , toggle: function () { /*? Опять же, не проще делать toggle: function (this) ?*/ this[this.tip().hasClass('in') ? 'hide' : 'show']() } , destroy: function () { this.hide().$element.off('.' + this.type).removeData(this.type) } } /* TOOLTIP PLUGIN DEFINITION * ========================= */ $.fn.tooltip = function ( option ) { /*? Самый непонятный блок ?*/ return this.each(function () { var $this = $(this) , data = $this.data('tooltip') , options = typeof option == 'object' && option /*? Зачем столько проверок? Без них что-то развалиться ?*/ if (!data) $this.data('tooltip', (data = new Tooltip(this, options))) /* ? Тут же сделали через new и зачем нужны были все эти Constructor ?*/ if (typeof option == 'string') data[option]() /* ? хм... ? */ }) } $.fn.tooltip.Constructor = Tooltip /*? Заменяем стандартный конструктор на наш. Зачем ?*/ $.fn.tooltip.defaults = { selector: false , delay: 0 } }(window.jQuery); |
Часовой пояс GMT +3, время: 23:39. |