Я занимался исследованием шаблонов наследования JavaScript, осознавая, что существует множество различных подходов и разошлись во мнениях, какой шаблон или метод лучше. Не существует общепринятого пуленепробиваемого паттерна, который охватывал бы каждый возможный сценарий, вероятно потому, что все зависит от того, чего вы пытаетесь достичь.
Мне нужен шаблон, который может принимать и расширять несколько объектов. Обычно очень часто можно увидеть один объект, который расширяет другой объект extends (объект1, объект2), но мне нужен шаблон, который принимает несколько объектов, таких как расширение (объект1, объект2, объект3). Поэтому я решил сделать один.
Я использовал Дугласа Крокфорда — логику наследования прототипа , временная функция -> Object.prototype -> новый объект плюс цикл внутри каждого объекта для копирования всех методов.
Первый шаблон принимает только объекты:
function extend() { var i = arguments.length; function F() {} while (i--) { for (var m in arguments[i]) { F.prototype[m] = arguments[i][m]; } } return new F(); }
Я также сделал второй шаблон на случай, если вы захотите использовать функцию для хранения методов. Маловероятно, что вы будете использовать функцию только для хранения методов, но в любом случае здесь есть шаблон.
function extendAll() { var i = arguments.length; function F() {} function N() {} while (i--) { for (var method in arguments[i]) { F.prototype[method] = arguments[i][method]; } if (typeof arguments[i] !== "object") { N.prototype = new arguments[i](); for (var m in N.prototype) { F.prototype[m] = N.prototype[m]; } } } return new F(); }
Из предварительных тестов этот шаблон должен работать даже в IE 5.5.
Иногда может быть удобно объединить объекты или разделить один объект на более мелкие единицы для увеличения модульности. Многие современные JS Frameworks имеют один объект, который содержит все, и разделение этого объекта на более мелкие логические компоненты (объекты) может быть полезным.
Два месяца назад я создал небольшой JS-фреймворк picoCSS для создания приложений webkit. Я перепишу picoCSS, чтобы продемонстрировать функциональность этого шаблона. Многие JS-фреймворки имеют такие модули, как: механизм выбора, css, анимация, другие методы DOM, ajax, события … Цель этого шаблона — объединить только те объекты (модули), которые нам нужны.
Вот оригинал picoCSS, просмотренный с помощью Auto Auto Documentation, Все хранится внутри объекта с. Цель состоит в том, чтобы затормозить picoCSS несколькими объектами, такими как селектор, события, анимация …
И picoCSS после:
var selector = { select: function (selector) { this.value = Array.prototype.slice.call(document.querySelectorAll(selector)); return this; } }; var loop = { each: [].forEach, map: [].map }; var css = { css: function (v) { this.value = this.each.call(this.value, function (i) { i.style.cssText = v; }); return this; }, att: function (a, v) { this.value = this.each.call(this.value, function (i) { i.setAttribute(a, v); }); return this; } }; var animation = { animate: function (time, scale, rotate, rotateX, rotateY, translateX, translateY, skewX, skewY) { this.value = [].forEach.call(this.value, function (i) { i.style.cssText = '-webkit-transition: all ' + time + 's ease-in-out; -webkit-transform: scale(' + scale + ') rotate(' + rotate + 'deg) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg) translate(' + translateX + 'px, ' + translateY + 'px) skew(' + skewX + 'deg, ' + skewY + 'deg)'; }); return this; } }; var events = { on: function (type, fn) { this.value = this.each.call(this.value, function (i) { i.addEventListener(type, fn, false); }); return this; } };
Теперь мы можем перестроить picoCSS следующим образом: var p = extend (selector, css, loop, events);
Таким образом, мы загрузили только те объекты и методы, которые нам нужны. Этот конкретный случай деления объекта не имеет большого смысла, потому что у нас есть очень маленькая библиотека. Но в других крупных проектах разделение логики может быть очень полезным не только для увеличения модульности, но и для уменьшения потребления памяти. Мы можем даже создавать разные файлы для каждого объекта и загружать только те файлы, которые мы используем. Естественно, мы должны быть осторожны, чтобы не делать много HTTP-запросов.
Вот несколько тестов, которые я сделал.
Ваши комментарии и предложения по улучшению этой модели приветствуются.
С http://www.vcarrer.com/2011/06/multiple-object-extend-pattern-in.html