动态声明变量

时间:2013-02-06 15:54:17

标签: javascript prototypal-inheritance

这个项目只是为了我自己的满意,所以我并不是真的在寻找其他库来实现这个目标。我正在尝试创建一个HTML元素库:

var ElementLibrary = function() {};
(function() {
    var _concatArray = [,'Element'];
    var _varArray = [
        'html',
        'head', 'title', 'base', 'link', 'meta', 'style',
        'script',
        'body', 'section', 'nav', 'article', 'aside', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hgroup', 'header', 'footer', 'address', 'main',
        'p', 'hr', 'pre', 'blockquote', 'ol', 'ul', 'li', 'dl', 'dt', 'dd', 'figure', 'figcaption', 'div',
        'a', 'em', 'strong', 'small', 's', 'cite', 'q', 'dfn', 'abbr', 'data', 'time', 'code', 'var', 'samp', 'kbd', 'sub', 'sup', 'i', 'b', 'u', 'mark', 'ruby', 'rt', 'rp', 'bdi', 'bdo', 'span', 'br', 'wbr',
        'ins', 'del',
        'img', 'iframe', 'embed', 'object', 'param', 'video', 'audio', 'source', 'track', 'canvas', 'map', 'area', 'svg', 'math',
        'table', 'caption', 'colgroup', 'col', 'tbody', 'thead', 'tfoot', 'tr', 'td', 'th',
        'form', 'fieldset', 'legend', 'label', 'input', 'button', 'select', 'datalist', 'optgroup', 'option', 'textarea', 'keygen', 'output', 'progress', 'meter',
        'details', 'summary', 'command', 'menu'
    ];
    var _l = _varArray.length;
    for (var i = 0; i < _l; i++) {
        _concatArray[0] = _varArray[i];
        ElementLibrary.prototype[_concatArray.join('')] = document.createElement(_varArray[i]);
        ElementLibrary.prototype[_varArray[i]] = function() {
            return this[_concatArray.join('')].cloneNode(false);
        };
    }
})();

我最初开始写它的方式最终会超过400行,所以我想以更紧凑的方式做到这一点。好消息,它部分有效。如果我这样做:

var el = new ElementLibrary();
el.pElement // <---that is correctly a paragraph element

然而,这并非真正的预期用途。我想从单个原型属性中获得一个浅层克隆,如:

var el = new ElementLibrary();
el.p() // <---this is where I run into trouble

如果我调用我的任何ElementLibrary函数,它只返回我的数组中的最后一个元素(在这种情况下是菜单)。为什么当所有属性都被正确声明时,每个函数只返回最后一个元素?

编辑:我添加了fiddle并将_concatArray业务拉出来。

解决方案:

var ElementLibrary = function() {};
(function() {
    var _varArray = [
        'html',
        'head', 'title', 'base', 'link', 'meta', 'style',
        'script',
        'body', 'section', 'nav', 'article', 'aside', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hgroup', 'header', 'footer', 'address', 'main',
        'p', 'hr', 'pre', 'blockquote', 'ol', 'ul', 'li', 'dl', 'dt', 'dd', 'figure', 'figcaption', 'div',
        'a', 'em', 'strong', 'small', 's', 'cite', 'q', 'dfn', 'abbr', 'data', 'time', 'code', 'var', 'samp', 'kbd', 'sub', 'sup', 'i', 'b', 'u', 'mark', 'ruby', 'rt', 'rp', 'bdi', 'bdo', 'span', 'br', 'wbr',
        'ins', 'del',
        'img', 'iframe', 'embed', 'object', 'param', 'video', 'audio', 'source', 'track', 'canvas', 'map', 'area', 'svg', 'math',
        'table', 'caption', 'colgroup', 'col', 'tbody', 'thead', 'tfoot', 'tr', 'td', 'th',
        'form', 'fieldset', 'legend', 'label', 'input', 'button', 'select', 'datalist', 'optgroup', 'option', 'textarea', 'keygen', 'output', 'progress', 'meter',
        'details', 'summary', 'command', 'menu'
    ];
    var _l = _varArray.length;
    for (var i = 0; i < _l; i++) {
        var _temp = _varArray[i];
        var _tempElement = _temp + 'Element';
        (function(t, te) {
            ElementLibrary.prototype[te] = document.createElement(t);
            ElementLibrary.prototype[t] = function() {
                return this[te].cloneNode(false);
            };
        })(_temp, _tempElement);
    }
})();

var el = new ElementLibrary();
alert(el.p());

1 个答案:

答案 0 :(得分:0)

您在该循环中创建的函数不会引用“冻结”版本的“_concatArray”。它们都共享对同一个数组的引用。

将它们包裹在另一个功能中:

ElementLibrary.prototype[_varArray[i]] = (function(ca) {
  return function() {
    return this[ca.join('')].cloneNode(false);
  };
})(_concatArray);