我编辑了这个问题,因此更有意义
我有一个需要几个参数的函数 - 让我们称之为fc()
。我通过其他函数将该函数作为参数传递(让我们称之为fa()
和fb()
)。 fc()
经过的每个函数都会向fc()
添加一个参数。如何将fc()
传递给每个函数而不必单独传递fc()
的参数?以下是我希望它的工作方式。
function fa(fc){
fc.myvar=something
fb(fc)
}
function fb(fc){
fc.myothervar=something
fc()
}
function fc(){
doessomething with myvar and myothervar
}
以下是我现在的表现。当我添加参数时,它会变得混乱,因为我必须将它们添加到前面的函数中。 fb()
和fc()
在其他地方使用,我正在失去一些灵活性。
function fa(fc){
myvar=something
fb(fc,myvar)
}
function fb(fc,myvar){
myothervar=something
fc(myvar,myothervar)
}
function fc(myvar,myothervar){
doessomething with myvar and myothervar
}
感谢您的帮助
编辑3 - 代码
我使用JimmyP的解决方案更新了我的代码。我对Jason Bunting的非黑客解决方案感兴趣。请记住,这些函数中的每一个也都是从其他函数和事件中调用的。
从HTML页面
<input type="text" class="right" dynamicSelect="../selectLists/otherchargetype.aspx,null,calcSalesTax"/>
加载部分时设置事件处理程序
function setDynamicSelectElements(oSet) {
/**************************************************************************************
* Sets the event handlers for inputs with dynamic selects
**************************************************************************************/
if (oSet.dynamicSelect) {
var ySelectArgs = oSet.dynamicSelect.split(',');
with (oSet) {
onkeyup = function() { findListItem(this); };
onclick = function() { selectList(ySelectArgs[0], ySelectArgs[1], ySelectArgs[2]) }
}
}
}
onclick
事件构建列表
function selectList(sListName, sQuery, fnFollowing) {
/**************************************************************************************
* Build a dynamic select list and set each of the events for the table elements
**************************************************************************************/
if (fnFollowing) {
fnFollowing = eval(fnFollowing)//sent text function name, eval to a function
configureSelectList.clickEvent = fnFollowing
}
var oDiv = setDiv(sListName, sQuery, 'dynamicSelect', configureSelectList); //create the div in the right place
var oSelected = event.srcElement;
if (oSelected.value) findListItem(oSelected)//highlight the selected item
}
创建列表
function setDiv(sPageName, sQuery, sClassName, fnBeforeAppend) {
/**************************************************************************************
* Creates a div and places a page in it.
**************************************************************************************/
var oSelected = event.srcElement;
var sCursor = oSelected.style.cursor; //remember this for later
var coords = getElementCoords(oSelected);
var iBorder = makeNumeric(getStyle(oSelected, 'border-width'))
var oParent = oSelected.parentNode
if (!oParent.id) oParent.id = sAutoGenIdPrefix + randomNumber()//create an ID
var oDiv = document.getElementById(oParent.id + sWindowIdSuffix)//see if the div already exists
if (!oDiv) {//if not create it and set an id we can use to find it later
oDiv = document.createElement('DIV')
oDiv.id = oParent.id + sWindowIdSuffix//give the child an id so we can reference it later
oSelected.style.cursor = 'wait'//until the thing is loaded
oDiv.className = sClassName
oDiv.style.pixelLeft = coords.x + (iBorder * 2)
oDiv.style.pixelTop = (coords.y + coords.h + (iBorder * 2))
XmlHttpPage(sPageName, oDiv, sQuery)
if (fnBeforeAppend) {
fnBeforeAppend(oDiv)
}
oParent.appendChild(oDiv)
oSelected.style.cursor = ''//until the thing is loaded//once it's loaded, set the cursor back
oDiv.style.cursor = ''
}
return oDiv;
}
列表的位置和大小
function configureSelectList(oDiv, fnOnClick) {
/**************************************************************************************
* Build a dynamic select list and set each of the events for the table elements
* Created in one place and moved to another so that sizing based on the cell width can
* occur without being affected by stylesheet cascades
**************************************************************************************/
if(!fnOnClick) fnOnClick=configureSelectList.clickEvent
if (!oDiv) oDiv = configureSelectList.Container;
var oTable = getDecendant('TABLE', oDiv)
document.getElementsByTagName('TABLE')[0].rows[0].cells[0].appendChild(oDiv)//append to the doc so we are style free, then move it later
if (oTable) {
for (iRow = 0; iRow < oTable.rows.length; iRow++) {
var oRow = oTable.rows[iRow]
oRow.onmouseover = function() { highlightSelection(this) };
oRow.onmouseout = function() { highlightSelection(this) };
oRow.style.cursor = 'hand';
oRow.onclick = function() { closeSelectList(0); fnOnClick ? fnOnClick() : null };
oRow.cells[0].style.whiteSpace = 'nowrap'
}
} else {
//show some kind of error
}
oDiv.style.width = (oTable.offsetWidth + 20) + "px"; //no horiz scroll bars please
oTable.mouseout = function() { closeSelectList(500) };
if (oDiv.firstChild.offsetHeight < oDiv.offsetHeight) oDiv.style.height = oDiv.firstChild.offsetHeight//make sure the list is not too big for a few of items
}
答案 0 :(得分:2)
好的,那么 - 从哪里开始? :)这是部分功能开始,你将需要这个(现在和将来,如果你花了很多时间黑客攻击JavaScript):
function partial(func /*, 0..n args */) {
var args = Array.prototype.slice.call(arguments, 1);
return function() {
var allArguments = args.concat(Array.prototype.slice.call(arguments));
return func.apply(this, allArguments);
};
}
我看到很多关于你的代码的事情让我感到畏缩,但由于我没有时间去批判它,而你没有要求它,如果你想摆脱自己,我会建议如下您正在使用的黑客攻击,以及其他一些事情:
在此功能中,您可以更改此行:
onclick = function() { selectList(ySelectArgs[0], ySelectArgs[1], ySelectArgs[2]) }
对此:
onclick = function() { selectList.apply(null, ySelectArgs); }
在这个函数中,你可以摆脱使用eval的代码 - 除非你有充分的理由这样做,否则不要使用eval,这是非常危险的(请仔细阅读):
if (fnFollowing) {
fnFollowing = eval(fnFollowing)
configureSelectList.clickEvent = fnFollowing
}
然后使用它:
if(fnFollowing) {
fnFollowing = window[fnFollowing]; //this will find the function in the global scope
}
然后,更改此行:
var oDiv = setDiv(sListName, sQuery, 'dynamicSelect', configureSelectList);
对此:
var oDiv = setDiv(sListName, sQuery, 'dynamicSelect', partial(configureSelectListAlternate, fnFollowing));
现在,在我提供的代码中,我有“configureSelectListAlternate” - 这是一个与“configureSelectList”相同但具有相反顺序的参数的函数 - 如果你可以将参数的顺序反转为“configureSelectList” “相反,这样做,否则这是我的版本:
function configureSelectListAlternate(fnOnClick, oDiv) {
configureSelectList(oDiv, fnOnClick);
}
在此功能中,您可以删除此行:
if(!fnOnClick) fnOnClick=configureSelectList.clickEvent
不再需要了。现在,我看到一些我不明白的东西:
if (!oDiv) oDiv = configureSelectList.Container;
我没有看到你在任何其他代码中挂起该Container属性。除非你需要这一行,否则你应该能够摆脱它。
setDiv()函数可以保持不变。
不是太令人兴奋,但你明白了 - 你的代码真的可以使用一些清理 - 你是否有充分的理由避免使用像jQuery或MochiKit这样的库?它会让你的生活更轻松......
答案 1 :(得分:1)
函数的属性不可用作本地范围中的变量。您必须将它们作为属性访问。因此,在'fc'中你可以通过以下两种方式之一访问'myvar':
// #1
arguments.callee.myvar;
// #2
fc.myvar;
要么好......
答案 2 :(得分:0)
也许您正在寻找Partial Function Application,或者可能正在讨论?
以下是a blog post on the difference的引用:
当部分应用程序接受一个函数并从中构建一个函数,该函数接受较少的参数,currying构建函数,这些函数通过函数组合获取多个参数,每个参数都采用一个参数。
如果可能,如果您可以简化示例和/或提供实际的JS代码而不是伪代码,它将帮助我们。
答案 3 :(得分:0)
尝试继承 - 通过将您的任何对象作为参数传递,您可以访问其中的任何变量,例如:
function Obj (iString) { // Base object
this.string = iString;
}
var myObj = new Obj ("text");
function InheritedObj (objInstance) { // Object with Obj vars
this.subObj = objInstance;
}
var myInheritedObj = new InheritedObj (myObj);
var myVar = myInheritedObj.subObj.string;
document.write (myVar);
subObj将采用myObj的形式,因此您可以访问其中的变量。