确定这个javascript函数的模式

时间:2013-10-20 12:09:01

标签: javascript closures

这是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)
};

那么这个结构如何运作? 我可以看到返回是一个对象。 但我不能把事情放在一起。 这是封闭模式吗? 任何人都可以解释这个流程吗?

2 个答案:

答案 0 :(得分: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.yobject.z中捕获。

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

12 > 10将返回true

答案 1 :(得分:3)

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

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

因此UA设置为此匿名函数的返回值。那么匿名函数有什么作用呢?它设置变量ua

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

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

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成为包含一组标志的Object。这可能是执行模式匹配的(可能相当小的)开销,而开发人员对此不感兴趣。