25

我正在寻找一种很好的技术来摆脱我想做的事情:设置一个全局变量。

第一次有人通过单击按钮运行一个函数时,它会触发一个初始函数,将一些东西变成可拖动的。稍后,如果他们第二次单击该按钮,我想确定该init函数是否已初始化,如果是,则不再调用它。我可以通过从函数中设置一个全局变量init然后从 click 函数中检查该变量来轻松地做到这一点,但我想知道如何在不设置全局变量的情况下做到这一点。我真的很想要一个这样做的例子。

4

6 回答 6

29

您可以向函数添加一个属性:

function init() {
    init.called = true;
}

init();

if(init.called) {
    //stuff
}
于 2012-07-02T19:29:59.363 回答
22

虽然@Levi 的回答应该可以正常工作,但我想提出另一种选择。一旦调用它,您将重写 init 函数以不执行任何操作。

var init = function () {
   // do the initializing

    init = function() {
        return false;
    }
};

第一次调用该函数时将执行初始化。然后它将立即覆盖自身以在下次调用时返回 false。第二次调用函数时,函数体将只包含return false。

更多阅读:http ://www.ericfeminella.com/blog/2011/11/19/function-overwriting-in-javascript/

于 2012-07-02T19:37:27.503 回答
2

你为什么不检查一下你的可拖动对象是否有一个类draggable

if ($('.mydiv').is('.draggable')) {
     //do something
}
于 2012-07-02T19:31:08.640 回答
2
Function.prototype.fired = false;

function myfunc() { 
    myfunc.fired = true; 
    // your stuff
};

console.log(myfunc.fired) // false

myfunc();

console.log(myfunc.fired) // true
于 2014-04-04T02:19:46.437 回答
1

你可以做的是从原型中解开 init 函数。

​var Obj = function () {
    this.init = function () {
        document.write("init called<br/>");
        this.init = null;
    }
}
var o = new Obj();
if (o.init) document.write("exists!<br/>");
o.init();
if (o.init) document.write("exists!<br/>");
o.init();

​ 第一个if将是 true 并打印exists!,但由于函数会自行删除,第二个if将失败。在我的示例中,我无条件地调用第二个 init 只是为了表明什么都不会发生,但当然你可以只在它存在时调用它:

if (o.init) o.init();

http://jsfiddle.net/coreyog/Wd3Q2/

于 2012-07-02T19:55:49.183 回答
1

正确的方法是使用 Javascript代理API 来捕获使用apply处理程序的函数调用。

const initFun = (args) => {
  console.log('args', args);
}
const init = new Proxy(initFun, {
  apply(target, thisArg, args){
    target.calls = target.calls ? target.calls + 1 : 1;
    return target.apply(thisArg, args);
  }
});

init('hi');
console.log(init.calls); // 1
init('hello');
console.log(init.calls); // 2

于 2020-06-10T05:32:28.623 回答