【问题标题】:Caching the return results of a function from John Resig's Learning Advanced JavaScript缓存来自 John Resig 的 Learning Advanced JavaScript 的函数的返回结果
【发布时间】:2011-03-17 01:38:48
【问题描述】:

我对 John Resig 在http://ejohn.org/apps/learn/#19 中的练习 #19 中的这个函数有一些疑问

  1. 倒数第二行getElements.cache = {}; 的用途是什么,它是否将return results 存储在一个数组中?

  2. 如果我在 (1) 中的猜测是正确的,它是否只捕获 return results,因为在函数的“else”部分,getElements.cache[name] = results;

  3. 当我在教程中使用控制台中的代码时,我从“else”部分中删除了行getElements.cache[name] = results,但仍然得到了相同的结果,就像它在那里时一样——也就是说,它告诉我有76个元素。因此,如果不需要得到结果,这行 getElements.cache[name] = results 的目的是什么?

  4. 在函数的“else”部分中,getElements.cache[name] = results; 行的顺序与代码的if 部分相反,它显示@987654330 @

  5. 最后,cache 是 JavaScript 中的预定义函数吗?我在文档中找不到它。

function getElements( name ) { 
  var results; 

  if ( getElements.cache[name] ) { 
    results = getElements.cache[name]; 
  } else { 
    results = document.getElementsByTagName(name); 
    getElements.cache[name] = results; 
  } 

  return results; 
} 
getElements.cache = {}; 

log( "Elements found: ", getElements("pre").length );

【问题讨论】:

    标签: javascript


    【解决方案1】:

    a) 倒数第二行确定对象 getElements 上的属性“缓存”是一个对象。本质上是初始化该属性。

    b) 那就是缓存,把 getElements 想象成一个对象,缓存是一个保存结果的散列。

    c) 是的,你仍然会得到相同的结果,因为缓存只是在缓存,它不会改变答案,它只是可能会加快速度。

    d) 是的,一个是将结果存储到缓存中,另一个是从缓存中提取结果。

    e) 不,这是为“getElements”定义的自定义属性,可以定义任意数量的具有不同名称的属性。

    【讨论】:

    • 非常感谢。关于 (d) 哪个将结果存储到缓存中?哪个从缓存中提取结果?关于 (e),这个自定义属性是否在某处“幕后”定义?即我没有看到任何创建此属性的代码。
    • 带有“result = getElements.cache[name]”的 if 语句正在复制缓存中的值。关于(e),见(a)。这就是定义。
    • 为什么初始化该属性不是绝对必要的?(来自a))如果您不这样做,则不能使用getElements.cache[name],因为该函数还没有cache 属性。但我认为只使用getElements[name] 就可以省略缓存属性。
    • @Gnijuohz 这是个好问题。不确定我当时在想什么,但这确实需要初始化以使其成为一个数组。我已经相应地编辑了帖子。
    【解决方案2】:

    1.-倒数第二个的目的是什么 线getElements.cache = {};是吗 将返回结果存储在数组中?

    只是初始化对象

    2.- 如果我在 (1) 中的猜测是正确的,是吗? 只捕获返回结果,因为, 在函数的“其他”部分, getElements.cache[name] = results;?

    是的,它使用缓存方法来避免访问 DOM。

    3.- 当我使用代码中的 在教程中的控制台,我删除了 线getElements.cache[name] = results 从“其他”部分,但仍然得到 和以前一样的结果 那里——也就是说,它告诉我那里 是 76 个元素。因此,什么是 这条线的目的 getElements.cache[name] = results 如果 不需要得到结果吗?

    从某种意义上说,这并不是真正必要的,因为它只是使函数返回更快,因为访问对象比遍历 DOM 更快。

    4.- 这个事实有什么意义吗 那个,在“其他”部分 函数,行的顺序 getElements.cache[name] = results; 是 与 if 部分相反 代码,上面写着results = getElements.cache[name]

    在 else 部分,首先,results 变量被赋值为实际结果,然后结果被缓存。在 then 部分中,results 变量只是被分配了缓存值。无需重新缓存

    5.- 最后,是缓存一个预定义的 JavaScript 中的函数?我找不到 它在文档中。

    它不是预定义的。它被用作这个特定函数的属性(在 JavaScript 中,函数是第一类对象,可以将值存储在属性中。

    这里是注释的代码:

    function getElements( name ) { 
      var results; 
    
      if (getElements.cache[name]) { 
        results = getElements.cache[name]; // Use the cached value
      } else { 
        results = document.getElementsByTagName(name); // Get the desired value
        getElements.cache[name] = results; // cache the result
      } 
    
      return results; 
    } 
    
    getElements.cache = {}; // Initialize the cache
    

    【讨论】:

    • 谢谢。关于 3,如果 getElements.cache[name] = results 已被删除,则所需的值将存储在变量 results 中。当您提到“遍历 Dom”时,您是指需要从变量中提取所需值的事实吗?
    • 行“document.getElementsByTagName(name);”从作为树的 DOM(文档对象模型,即 HTML 的内部表示)获取信息,从中获取信息比仅读取对象的属性更昂贵。
    • 好的,非常感谢,但这又引发了另一个问题。但是由于“document.getElementsByTagName(name)”在代码中,那么t the function doing both. i.e. "accessing the object" (with the cache) AND "traversing the DOM" (with the getElementByID? If the purpose of the cache was to make it less expensive than traversing the Dom, why does the function do both? isnt 是不是更贵了?遗漏文件不是最便宜的事情。 getElementsByTag(name)?
    • 它只会做一次,第一次。它将从 DOM 中获取信息并将其存储在缓存中(属性分配并不昂贵。)第二次它会发现该值已经在缓存中并从那里读取它。我想您可以尝试分析它创建一个函数,在有和没有缓存的情况下对该函数进行 100K 调用,看看是否有区别。理论上应该;)
    • 好吧,Its clear now. I didnt 意识到缓存的(明显)目的是用于多次调用。非常感谢您的帮助。
    【解决方案3】:

    另一种缓存功能

    // Were going to get some things.
    var getSomeThings = function() {
        // Calling something expense to get the things.
        var things = somethingExpensive();
        // overwriting this function with a function that returns things
        getSomeThings = function() {
             return things;
        }
        // call the new function that returns things and return things.
        return getSomeThings();
    };
    

    第一次调用它时,您计算并返回它。第二个,第三个,......这被称为你只是返回的东西。

    另一个例子允许你用一个不同但类似想法的参数来缓存它。这意味着您要缓存一大堆东西,而不仅仅是一个。

    [编辑]

    这样做是创建一个名为getSomeThings 的变量。然后为它分配一个功能。当您调用该函数时,它可以将getSomeThings 本身作为变量访问,并且可以使用新函数对其进行设置。

    例如:

    function getSomethingExpensive() {
         ...
         return 42;
    }
    var b = function() {
         b = getSomethingExpensive();
    }    
    b();
    alert(b);
    

    【讨论】:

    • 非常感谢。您能否更详细地解释一下它是如何跳过第二次和第三次调用中的计算部分的。函数 getSomeThings =function() { 如何返回东西;实际上“覆盖”somethingExpensive() 函数?
    • @mjmitche 查看编辑。你没有覆盖 somethingExpensive 你覆盖 getSomeThings 本身所以它永远不会调用 somethingExpensive 超过一次。
    猜你喜欢
    • 2017-06-01
    • 2010-09-27
    • 2011-09-19
    • 2011-04-18
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 2013-02-09
    相关资源
    最近更新 更多