【问题标题】:Immediate function with another function call Javascript立即函数与另一个函数调用 Javascript
【发布时间】:2016-07-01 08:12:22
【问题描述】:

我正在阅读 John Resig 的 Javascript Ninja,记忆化一章中提到了这个概念,我无法弄清楚它是如何工作的。我在谷歌上找不到解释。所以,这里是书中的例子。

  Function.prototype.memoized = function(key){
    this._values = this._values || {};
    return this._values[key] !== undefined ?
      this._values[key] :
      this._values[key] = this.apply(this, arguments);
  };
Function.prototype.memoize = function(){
    var fn = this;                        
    return function(){                           
      return fn.memoized.apply( fn, arguments );
    };
  };
  var isPrime = (function(num) {
    var prime = num != 1;
    for (var i = 2; i < num; i++) {
      if (num % i == 0) {
        prime = false;
        break;
      }
    }
    return prime;
  }).memoize(); // I don't understand how this works

现在,我了解了这个示例中的闭包是如何工作的,并且我大致了解了原型,但是我不明白这个 (function expression).memoize() 部分是如何工作的?我看到 memoize 返回一个函数,并且该函数(我假设)被添加到 isPrime,但是这个 (function expression) 是如何被调用的,或者它如何作为 isPrime 方法的一部分?那么,当我调用isPrime(17)时,首先执行的是什么?

编辑: 好的,我现在对所有的命令感到困惑,所以这就是我现在的看法。

  • 首先:当(function(num){....}).memoize()被调用时,匿名函数表达式(function(num){...})在memoize函数中表示为this并赋值给fn。

  • 第二:在 memoize 中返回一个匿名函数,该函数通过闭包保存fn。返回的匿名函数分配给isPrime

  • 第三:当我们调用isPrime(17)时,实际上调用的是fn.memoized.apply(fn, attributes),而在memoized里面this(上下文)表示fn,它是对匿名函数(function(num{...} ))。而这部分:this.apply(this, arguments) 执行该匿名函数 (function(num) {...})

    这是有道理的,首先需要检查该数字是否被缓存,如果不是,则检查它是否为素数并将其放入缓存中。

【问题讨论】:

  • 函数表达式成为memoize方法内的this值。
  • 记住 () 里面的东西会被立即调用。很像 (isTrue === true) ? "":"" ; 这样的内联 if 语句,其中表达式 `(isTrue === true) ?在运行时进行评估。
  • 这意味着 (function(){return true}) 将在运行时调用,您不需要调用它。
  • 啊哈!所以它实际上在这部分被调用, this._values[key] = this.apply(this, arguments); ?
  • 不,当您设置 var isPrime = (function(){}) 时它会被调用。 this.apply() 是原生函数

标签: javascript closures


【解决方案1】:

会发生以下情况:

  • Function 原型使用​​ memoizedmemoize 两种方法扩展(但不建议扩展原生原型)
  • 在函数表达式(function(num)...被赋值给isPrime之前,函数原型的memoize被调用
  • memoize 内部,this 自动绑定到调用该方法的对象(本例中为函数对象)。所以this指的是匿名函数,后来被赋值给isPrime。最后返回一个 thunk return function(){... 以推迟执行。
  • 当最终调用此 thunk 时,它使用 apply 将任意数量的参数传递给 memoized(请注意,提供给 memoized 的第一个参数用作记忆缓存的键)

我认为这个实现很难看,因为它掩盖了这样一个事实,即不是原始匿名函数被分配给 isPrime,而是包装它的 thunk。

我不确定isPrime(或匿名函数表达式)是否是 IIFE,因为只是立即调用其原型的方法,而不是函数本身。

【讨论】:

  • 好的,我现在对所有的命令感到困惑,所以这就是我现在的看法。
  • @pord911 我认为这个 memoize ES5 实现真的很丑陋而且过于复杂。我想这只是为了学习。
  • 是的,但正如我所见,他是从专业代码中提取的,我猜那是原型框架?因此,最终可能会使用这种代码实现。好消息是,可以看到用 Javascript 实际可以做什么。
  • @pord911 我解释了为什么我认为这个实现不好。
猜你喜欢
  • 2012-06-14
  • 2023-03-24
  • 2019-04-24
  • 2015-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-22
  • 2021-12-10
相关资源
最近更新 更多