【问题标题】:Javascript Closure and DOM BuilderJavascript 闭包和 DOM 构建器
【发布时间】:2010-12-12 01:50:06
【问题描述】:

我正在制作一个我已经成功工作的 DOM 构建器,但现在我正在尝试分配一些速记函数,以便 div() -> e("div")

这是我的代码:

//assign these objects to a namespace, defaults to window
(function(parent) {

/**
* Creates string of element
* @param tag The element to add
* @param options An object of attributes to add
* @param child ... n Child elements to nest
* @return HTML string to use with innerHTML
*/
var e = function(tag, options) {
    var html = '<'+tag;
    var children = Array.prototype.slice.apply(arguments, [(typeof options === "string") ? 1 : 2]);

    if(options && typeof options !== "string") {
        for(var option in options) {
            html += ' '+option+'="'+options[option]+'"';
        }
    }

    html += '>';
    for(var child in children) {
        html += children[child];
    }
    html += '</'+tag+'>';
    return html;
}

//array of tags as shorthand for e(<tag>) THIS PART NOT WORKING
var tags = "div span strong cite em li ul ol table th tr td input form textarea".split(" "), i=0;
for(; i < tags.length; i++) {
    (function(el) { //create closure to keep EL in scope
        parent[el] = function() {
            var args = Array.prototype.slice.call(arguments);
            console.log(args);
            args[0] = el; //make the first argument the shorthand tag
            return e.apply(e,args);
        };
    })(tags[i]);
}

//assign e to parent
parent.e = e;
})(window);

当前发生的情况是,每次我调用其中一个速记函数时,args 数组都会被修改,我假设需要发生的是某个地方的闭包,因此我创建的 args 数组在每次调用时都不会受到影响。这是单元测试的输出:

div( div( span("Content")), span()) 预期:&lt;div&gt;&lt;div&gt;&lt;span&gt;Content&lt;/span&gt;&lt;/div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; 结果:&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;

div( div( span( e("b", e("b", e("b")))), span())) 预期:&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt; 结果:&lt;div&gt;&lt;/div&gt;

【问题讨论】:

    标签: javascript dom closures


    【解决方案1】:

    虽然这并不能直接回答你的问题,

    for(var el in tags) {
    

    并不完全正确。 tags 是一个数组,而不是一个对象,所以它的属性不能用for (... in ...) 枚举。试试

    for(var el = 0; el < tags.length; el++) {
    

    这会对解释器对您的代码的理解...以及您的算法的正确执行产生巨大的影响。

    【讨论】:

    • @Louis - 在最新版本的 JavaScript 中也有一个 for each。它用于枚举对象值,如果您不关心顺序,可以与数组一起使用。在 Firefox 中尝试for each(var v in {a:1, b:2, c:3}) console.log(v);
    【解决方案2】:

    金发时刻,当我打算使用 args.unshift(el); 时,我正在覆盖第一个元素

    【讨论】:

      【解决方案3】:

      @MvanGeest - 在阵列上执行for..in 在技术上是允许的。数组仍然是 javascript 中的对象。如果使用for..in 循环进行迭代,则数组的索引将是键。在这种情况下显然不是使用数组的重点,但我想我会澄清一下。

      @Anurag - IE8 不支持 forEach 方法(不确定是否为 9),因此在将来的晚些时候使用它可能不是一种可靠的方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-31
        • 1970-01-01
        • 2010-10-27
        • 1970-01-01
        • 1970-01-01
        • 2020-04-13
        • 2010-09-25
        • 2011-07-25
        相关资源
        最近更新 更多