0

我正在浏览玉模板引擎源代码,并试图弄清楚这个语句的含义。

我知道它会尝试实例化options.compiler,如果实例化失败Compiler,但下一部分让我感到困惑......这是说调用parser.parse并将返回的值声明为变量吗?如果是这样,为什么最右边的括号是选项?

var compiler = new (options.compiler || Compiler)(parser.parse(), options)
  , js = compiler.compile();

.
如果有帮助,这里有更多上下文

function parse(str, options){
  try {
    // Parse
    var parser = new Parser(str, options.filename, options);

    // Compile
    var compiler = new (options.compiler || Compiler)(parser.parse(), options)
      , js = compiler.compile();

Github - 第 960 行

4

3 回答 3

2

var compiler = new (options.compiler || Compiler)不尝试实例化 options.compiler. 它寻找构造函数的存在作为compiler的属性option。如果它没有找到它,它将Compiler用作构造函数。

然后它只是将这两个参数传递给正在使用的构造函数:第一个参数是 的返回值parser.parse(),第二个参数是options.


为了简化它,这可以重写如下:

var theConstructor = options.compiler || Compiler;
var parsedStuff = parser.parse();
var compiler = new theConstructor(parsedStuff, options);
于 2013-01-25T05:13:32.513 回答
1

让我们分解一下。

(options.compiler || Compiler)

这个表达式似乎是为了寻找一个“类”(好吧,从技术上讲,是一个构造函数,这是 JavaScript)。options 对象可用于指定它,否则它将回退到Compiler.

new (options.compiler || Compiler)(/* ... */)

好的,现在这更有意义了。我们正在调用一个构造函数。只是“类”是动态选择的。

new (options.compiler || Compiler)(parser.parse(), options)

当我们传入构造函数时,我们传入了两个参数。第一个是调用对象parse方法的结果parser,第二个是前面的选项对象。

var compiler = new (options.compiler || Compiler)(parser.parse(), options)

那个邪恶的混乱存储在compiler变量中。

var compiler = new (options.compiler || Compiler)(parser.parse(), options), js = compiler.compile();

您可以在同一var语句中声明和分配多个变量,这样会进一步混淆。但最后一部分本身很容易理解。

该声明可以并且可能应该分解为多行……但事实就是如此。

于 2013-01-25T05:24:02.680 回答
0

它看起来很有趣,因为要调用的构造函数本身就是一个表达式。

不,它并没有完全计算parser.parse()为声明的本地值,compiler,而是从返回的对象创建一个新对象并从中初始化 compiler

而且,最右边的括号只是因为代码知道返回的任何构造函数......它都需要两个参数。

于 2013-01-25T05:15:30.657 回答