3 回答
TA貢獻(xiàn)1818條經(jīng)驗 獲得超3個贊
我認(rèn)為您并不完全理解代碼中使用的每個編程概念。
除此之外,您的原始代碼還包含一個拼寫錯誤:它應(yīng)該像在其他地方一樣閱讀。a.firstNum++;firsNum
讓我們將代碼分解為單獨的關(guān)注點。
遞歸
遞歸意味著函數(shù)調(diào)用自身。遞歸是計算、迭代或遍歷數(shù)據(jù)的一種方法。另一個是使用類似 或 的循環(huán)進(jìn)行迭代。whilefor
讓我們看一下這個簡化的示例:
function recurse(counter) {
console.log(counter);
recurse(counter + 1);
}
recurse(0);
這將無限期地調(diào)用,因為沒有什么可以阻止它調(diào)用自己。遞歸和迭代需要一些停止條件來破壞遞歸。recurse()
如果要在某個值處停止,則必須僅在滿足該條件之前調(diào)用該函數(shù):
function recurse(counter) {
console.log(counter);
if (counter < 42) {
recurse(counter + 1);
}
}
recurse(0);
這只會遞歸和遞增,直到達(dá)到 42。
您甚至可以使用函數(shù)本身傳遞停止條件:
function recurse(counter, maxValue) {
console.log(counter);
if (counter < maxValue) {
recurse(counter + 1, maxValue); // maxValue gets passed along
}
}
recurse(0, 42);
要使遞歸函數(shù)停止在某個值,您必須添加這樣的條件:
function fun(a) {
a.firstNum++;
a.sum += a.firstNum;
if (a.sum < a.maxNum) {
fun(a);
}
}
然后,您必須確保對象指定條件:
let object = {
maxNum: 3, // stop condition added
firsNum: 1,
sum: 0,
};
雖然這本身并不能解決問題。請繼續(xù)閱讀。
回調(diào)
回調(diào)是作為函數(shù)參數(shù)、對象屬性或數(shù)組元素傳遞給其他函數(shù)的函數(shù)。
通過回調(diào),您可以決定在運行時調(diào)用哪個函數(shù),而無需使用 或 語句實現(xiàn)分支行為,并且在編寫本文時需要某些函數(shù)名稱。ifswitch
function someCallback() { /* ... */ }
function callTheCallback(callback) {
callback(); // Execute the parameter as a function
}
callTheCallback(someCallback);
let someCallbackReference = someCallback;
// Call the same function but indirectly via a variable
callTheCallback(someCallbackReference);
在上面的示例中,可以間接地從其他對象發(fā)起。someCallback
您甚至可以直接指定函數(shù)表達(dá)式作為回調(diào):
callTheCallback(function() {
// ...
});
對于回調(diào),掌握傳遞函數(shù)調(diào)用結(jié)果和函數(shù)本身之間的區(qū)別至關(guān)重要:
callTheCallback(someCallback); // Callback function passed
callTheCallback(someCallback()); // Result of a function call passed
請注意,如果返回值本身是一個函數(shù),則傳遞函數(shù)調(diào)用的結(jié)果可能是完全有效的。這在編程中也不少見。
回調(diào)通常用于控制反轉(zhuǎn) (IoC) 和異步編程。
回調(diào)函數(shù)示例:
Filtering arrays: Array.prototype.filter() (IoC synchronous)
事件:窗口.onload(異步)
在您的情況下,作為第三個參數(shù)回調(diào)傳遞給 。fun()add()
現(xiàn)在您已經(jīng)知道如何使用遞歸和回調(diào),代碼中仍然存在語義錯誤...
語義錯誤
與語法錯誤(錯誤的代碼語法)相反,語義錯誤是具有代碼含義的錯誤。
接口add()
分析您的函數(shù) API:
function add(a, b, callback) {
return /* some value - callback() call removed for simplicity */;
}
add()接受三個參數(shù)并返回一個值。第三個參數(shù)名為“回調(diào)”,因此應(yīng)為函數(shù)。
盡管您不使用返回值(這不一定是錯誤),但您的調(diào)用看起來很合理。add()
add(1, object.firsNum, fun);
實施add()
由于 沒有記錄的參數(shù),因此您的意圖是模棱兩可的。add()
名稱以及有兩個參數(shù)和 的事實導(dǎo)致一個假設(shè),即應(yīng)將這兩個值相加。你做得很好:ab
return callback(a + b);
但!您作為回調(diào)函數(shù)傳遞的內(nèi)容 - 即 - 需要不同的參數(shù),而不是數(shù)字。 需要一個對象。fun()fun()
正確記錄后,它看起來像這樣:
/**
* Recursively sum values until a maximum value is reached.
*
* @param {Object} a object containing the sum, the increment and the max value
* @param {Number} a.firsNum start value
* @param {Number} a.maxNum the maxium value up to which to add "firsNum" to "sum"
* @param {Number} a.sum the summed value, shall be 0 initially
* @returns {undefined} nothing is returned
*/
function fun(a) {
// ...
}
上面的注釋樣式稱為 JsDoc:https://jsdoc.app
請注意,要為函數(shù)、變量和參數(shù)使用正確的名稱。專有名稱有助于在編寫顯式文檔注釋時記錄代碼。
修復(fù)錯誤
由于對你真正想要實現(xiàn)的目標(biāo)的有限了解,人們只能推測。我假設(shè) ,雖然它的名稱和參數(shù)看起來很合理,但實現(xiàn)錯誤。您的問題可以通過正確調(diào)用回調(diào)()來解決:add()fun()
function add(obj, callback) {
return callback(obj);
}
和:
add(object, fun);
由于我們需要對象,因此現(xiàn)在期望它作為單個參數(shù)。add()
好吧,現(xiàn)在這不再有太大意義了。 可以直接從內(nèi)部調(diào)用,而不是通過回調(diào)引用調(diào)用,并且具有令人困惑的名稱。fun()init()add()
我不會進(jìn)一步推測你的意圖是什么,以及如何實施替代解決方案來解決這個問題。
TA貢獻(xiàn)1824條經(jīng)驗 獲得超5個贊
您的代碼
function init() {
let object = {
firsNum: 1,
sum: 0,
};
add(1, object.firsNum, fun);
console.log(object.sum);
}
function fun(a) {
a.firstNum++;
a.sum += a.firsNum;
fun(a);
}
function add(a, b, callback) {
return callback(a + b);
}
init();
初始化
定義一個屬性為 和 的對象,然后調(diào)用 、傳遞 1、1 和 。firsNumsumaddfun
樂趣
接收參數(shù)。參數(shù)的增量,并將其添加到 。然后它調(diào)用自己。firstNumsum
加
獲取三個參數(shù):和 。呼叫并傳遞給它。abcallbackcallbacka + b
流程
init被調(diào)用,然后調(diào)用并將 1 傳遞給 、 1 傳遞給 和 。因此,添加調(diào)用 ,即 和 由于兩者和都是 1, = 2,則傳遞給 。 增量 ,這似乎是一個錯誤,因為是一個數(shù)字,那么其他一些奇怪的值被添加到。只需刪除內(nèi)部樂趣即可擺脫遞歸,但這不是代碼中唯一的錯誤。另外,請確保 里面有一個語句。addabfuncallbackcallbackfunaba + bfunfuna.firstNumasumfun(a);returnfun
TA貢獻(xiàn)2016條經(jīng)驗 獲得超9個贊
剛剛注釋掉了遞歸代碼
function init() {
let object = {
firsNum: 1,
sum: 0,
};
add(1, object.firsNum, fun);
console.log(object.sum);
}
function fun(a) {
a.firstNum++;
a.sum += a.firsNum;
//fun(a);
}
function add(a, b, callback) {
return callback(a + b);
}
init();
添加回答
舉報
