无法实现模块模式

时间:2011-03-01 15:46:56

标签: javascript closures

我试图重现Douglas Crockford所着的“Javascript:The Good Parts”一书中的一些代码。我们的想法是使用闭包进行对象封装,避免使用Javascript固有的全局变量。

var serial_maker = function (  ) {

// Produce an object that produces unique strings. A
// unique string is made up of two parts: a prefix
// and a sequence number. The object comes with
// methods for setting the prefix and sequence
// number, and a gensym method that produces unique
// strings.

    var prefix = '';
    var seq = 0;
    return {
        set_prefix: function (p) {
            prefix = String(p);
        },
        set_seq: function (s) {
            seq = s;
        },
        gensym: function (  ) {
            var result = prefix + seq;
            seq += 1;
            return result;
        }
    };
}(  );

var seqer = serial_maker(  );
seqer.set_prefix = 'Q';
seqer.set_seq = 1000;
var unique = seqer.gensym(  );    // unique is "Q1000"

Chrome正在收集错误:

  

未捕获的TypeError:属性   对象的'serial_maker'[对象   DOMWindow]不是一个函数   (匿名函数)

我做错了什么?

编辑:我应该说这段代码完全是从书中复制并粘贴的......

3 个答案:

答案 0 :(得分:8)

您正在尝试将函数的结果作为函数执行,并为函数赋值。 尝试:

var seqer = serial_maker;
seqer.set_prefix('Q');
seqer.set_seq(1000);
var unique = seqer.gensym();

另见jsFiddle

答案 1 :(得分:1)

此代码示例中有两个错误:

  1. serial_maker的定义以()调用匿名函数完成。这就是下一行:

    var seqer = serial_maker();
    

    错误,因为serial_maker不是函数,而是匿名函数返回的对象。

  2. 修复上一个错误后,两行:

    seqer.set_prefix = 'Q';
    seqer.set_seq = 10000;
    

    应改为:

    seqer.set_prefix('Q');
    seqer.set_seq(10000);
    
  3. (资料来源:http://oreilly.com/catalog/errata.csp?isbn=9780596517748&order=date

答案 2 :(得分:1)

我目前正在阅读这本书,当我将其与书籍进行比较时,我会在您发布的代码中看到一对冗余的括号()。 你有:

        }
    };
}(  );

它应该是:

        }
    };
};

除此之外,需要将'Q'和1000包装在()中的附加答案。