1

这是我无法理解的 javascript 函数的简要模式。如下所示: https ://github.com/g13n/ua.js/blob/master/src/ua.js 。

注意:这是根据 HugoT 对我原始问题的回答的编辑版本。

function D(arg) {
   return function () { 
       return arg > 10; //arg is captured in this function's closure 
   }
};

object = {
    x: D(11),
    y: D(9),
    z: D(12)
};

那么这个结构是如何工作的呢?我可以看到返回的是一个对象。但我不能把这些东西放在一起。这是闭包模式吗?谁能解释一下流程?

4

2 回答 2

3

是的,这是一个闭包模式。传递给 D 的任何参数都在从 D 返回的函数的闭包中捕获。但是,您编写的内容与您链接的代码中的内容不同。

这是您链接的简化代码的重要部分

function D(arg) {
   return function () { 
       return arg > 10; //arg is captured in this function's closure 
   }
};

object = {
    x: D(11),
    y: D(9),
    z: D(12)
};

值 11、9 和 12 将在函数object.xobject.y中捕获object.z

因此object.x()将返回 true 而object.y将返回 false 因为9 > 10是 false。object.z()将返回 true 因为12 > 10

于 2013-10-20T12:14:48.587 回答
3

让我们分解一下ua.js,看看发生了什么。洋葱的最外层是一个匿名函数:

var UA = (function (window, navigator) 
{ 
   /* anonymous function contents */  
}(window, navigator));

所以 UA 被设置为这个匿名函数的返回值。那么匿名函数有什么作用呢?它设置了一个变量ua

var ua = (window.navigator && navigator.userAgent) || "";

它定义了一个函数,该函数detect返回一个匿名函数,该函数针对 ua 测试 ua 的内容pattern

function detect(pattern) {
    return function () {
        return (pattern).test(ua);
    };
}

请注意,调用detect(/something/)不会返回 的值(/something/).test(ua)。它只是返回一个将按需执行测试的闭包。

现在我们点击外部匿名函数的返回值,它看起来像这样(我已经删除了评论):

return { isChrome: detect(/webkit\W.*(chrome|chromium)\W/i),
         isFirefox: detect(/mozilla.*\Wfirefox\W/i),
         isGecko: detect(/mozilla(?!.*webkit).*\Wgecko\W/i),
         ...
         whoami: function () {
           return ua;
         } }

这将返回一个Object包含许多函数(isChrome等)的实例,这些函数是调用创建的闭包detect()。这意味着这些(pattern).test(ua)检查的执行被推迟到有人实际调用UA.isChrome()等等。

您可以想象另一种方法,其中所有测试都预先执行,并且 UA 成为包含一组标志的对象。这会产生(可能相当小)执行模式匹配的开销,而您作为开发人员并不感兴趣。

于 2013-10-20T12:37:36.567 回答