是否可以在没有外部输入的情况下使功能自我感知

rab*_*tco 4 javascript function

背景

我想要一个跟踪自己状态的函数:

var myObject = {

    myFunction: function () {

        var myself = this.myFunction;
        var firstTime = Boolean(!myself.lastRetry);

        if (firstTime) {

            myself.lastRetry = Date.now();
            return true;
        }

        // some more code

    }
}
Run Code Online (Sandbox Code Playgroud)

上述代码的问题在于,值this将取决于函数调用的站点.我希望函数能够在不使用的情况下引用自身:

  • myObject.myFunction
  • .bind()
  • .apply()
  • .call()

是否有可能提供一种独立于其呼叫站点的这种自我意识的功能,并且没有外部参考的任何帮助?

T.J*_*der 8

如果要将该状态存储在函数实例上,请为该函数指定名称,并在其中使用该名称:

var myObject = {

    myFunction: function theFunctionName() {
    //                   ^^^^^^^^^^^^^^^--------------------- name
        var firstTime = Boolean(!theFunctionName.lastRetry);
    //                           ^--------------------------- using it
        if (firstTime) {

            theFunctionName.lastRetry = Date.now();
    //      ^------------------------------------------------ using it
            return true;
        }

        // some more code

    }
};
Run Code Online (Sandbox Code Playgroud)

每当你想要递归地使用函数时,你也会这样做.当您以某种方式为函数命名时(将名称放在function之前和之后(),该名称在函数自己的代码中是范围内的.(如果它是一个函数表达式,它不在包含该函数的代码的范围内,但如果它是一个函数声明则是它.你的是一个表达式.)

这是一个命名函数表达式(之前你有一个匿名函数表达式).您可能听到有关NFE的警告,但各种JavaScript实现与它们之间的问题基本上都是过去的.(IE8仍然错误地处理它们:我的博客上的这篇文章更多.)

您可以考虑通过IIFE将该州保持在某个私密状态:

var myObject = (function(){
    var lastRetry = null;
    return {
        myFunction: function() {
            var firstTime = Boolean(!lastRetry);
            if (firstTime) {

                lastRetry = Date.now();
                return true;
            }

            // some more code

        }
    };
})();
Run Code Online (Sandbox Code Playgroud)

现在,外部匿名函数之外的任何东西都可以看到lastRetry.(如果你支持顽固的XP用户,你不必担心IE8.:-))


旁注:一元运算!总是返回一个布尔值,所以你的

var firstTime = Boolean(!theFunctionName.lastRetry);
Run Code Online (Sandbox Code Playgroud)

......完全等同于:

var firstTime = !theFunctionName.lastRetry;
Run Code Online (Sandbox Code Playgroud)

...但是有一个额外的不必要的函数调用.(不是它伤害任何东西.)