SO上有很多方法可以确保只调用一次函数,但我找不到任何可以解决以下上下文和目标的方法。
上下文是对象文字中的一个函数,目标是将此实用程序放到Function.prototype
上,或者以某种方式使其更简洁。
目前我这样做:
var HugeLiteral={
subComponent:{
_name:'subComponent'
,_privateFnsEtc:function(){
}
,_init:function(){
// start of thing I would like to "Macro-ize"
if (arguments.callee.initialized) {console.error('already initialized');return;}
arguments.callee.initialized=true;
// End
//
// I would like to say something like
if (!arguments.callee._proceed()) {return;}// _proceed logs the error
//
// or alternatively
globalRunOnceCheckFn();// uses stack to get this function and do a throw
// or
maybeWrapCallingFunction(this);
//
codeToExecuteOnceHere();
//
// or this method which would tend to lock me into a single return point
this._init=this._init.guardFnOnFunctionPrototype;
}
}
,_init:function(){
// Here I could walk HugeLiteral and do whatever,
// but I am not sure I like wrapping the _inits.
}
};
我的主要要求是这样做的方法必须在函数内部运行,我知道我可以在外部包装函数以使其运行一次。
答案 0 :(得分:2)
var obj = {
foo: function() {
this.foo = function(){};
return 'once';
}
};
console.log(obj.foo()); // 'once'
console.log(obj.foo()); // undefined
答案 1 :(得分:0)
您可以使用IIFE闭包来存储变量,以跟踪它是否已经运行:
var obj = {
myFunc: (function() {
var alreadyRun = false;
return function(arg1, arg2) {
if (!alreadyRun) {
alreadyRun = true;
// rest of your code here
}
};
})();
};
或者,您可以创建一个辅助函数,使用法更清晰,并且可以更容易地在多个位置重用此概念:
// helper function that returns a function stub that can only be called once
function allowRunOnce(fn) {
var alreadyRun = false;
return function() {
if (!alreadyRun) {
alreadyRun = true;
return fn.apply(this, arguments);
}
}
}
var obj = {
myFunc: allowRunOnce(function(arg1, arg2) {
// code here for a method that can only be called once
});
};