JavaScript中什么是“一流函數(shù)”
什么是“一流函數(shù)”?
維基百科的定義:
在計算機科學(xué)中,如果一種編程語言將函數(shù)視為一等公民,那么它就被稱為具有一等函數(shù)。這意味著該語言支持將函數(shù)作為參數(shù)傳遞給其他函數(shù),將它們作為其他函數(shù)的值返回,并將它們分配給變量或?qū)⑺鼈兇鎯υ跀?shù)據(jù)結(jié)構(gòu)中。
例如,在 JavaScript 中,我們可以將一個函數(shù)分配給一個變量。
var sum = function(a, b) {
return a + b;
}
var total = sum(10, 1);
如果我們是第一次閱讀,這個定義會有點混亂。然而,事實是我們在不知情的情況下使用了它。
AddEventListener — 學(xué)習(xí) JavaScript 的第一課
過去,引入 JavaScript 是為了向網(wǎng)站添加動態(tài)行為。例如,我們希望在用戶單擊按鈕時更改文本。當(dāng)有人學(xué)習(xí) JavaScript 時,這是第一行代碼。
<html>
<body>
<p id="text">The text will change when you click on the button</p>
<button type="button" id="btn">Click me!</button>
<script>
let btn = document.getElementById("btn");
let text = document.getElementById("text");
btn.addEventListener("click", function() {
text.innerHTML = "New text!"
});
</script>
</body>
</html>
在第 9 行,我們將函數(shù)作為參數(shù)傳遞給 addEventListener 方法。該功能與按鈕的“單擊”事件相關(guān)聯(lián)。當(dāng)事件被觸發(fā)時,該函數(shù)將運行。
讓我們好奇——第 1 部分
要了解該功能的作用,讓我們考慮一下它不可用的語言。無論使用何種編程語言,添加動態(tài)行為在 UI 開發(fā)中都很常見。如果我們不能將函數(shù)作為參數(shù)傳遞怎么辦?我期待您在留言區(qū)與我們分享您的看法。
發(fā)送 HTTP 請求——JavaScript 中的常見任務(wù)
我以Axios為例。它是最流行的用于發(fā)送 HTTP 請求的 JavaScript 庫之一。在一個項目中,我們可能需要添加一些常用的配置。
例如,要將 JWT 發(fā)送到服務(wù)器,我們希望將標(biāo)頭 Authorization 添加到所有請求。因此,我們需要一個函數(shù)來抓取 JWT 并將其添加到標(biāo)題中。
可以使用攔截器來完成。
// Add jwt to all requests using interceptors
axios.interceptors.request.use(function (config) {
const jwt = globalStore.getJWT(); // assume the token is saved in a global store.
config.headers["Authorization"] = `Bearer ${jwt}`;
return config;
}, null, { synchronous: true });
同樣,我們傳遞 2 個函數(shù)作為 use 方法的參數(shù)。第一個函數(shù)在請求的標(biāo)頭中設(shè)置令牌。
如果出現(xiàn)錯誤,則第二個函數(shù)將運行(為簡單起見,我們沒有在此處定義它)。Axios在處理一個請求時,會一一運行所有的攔截器,將用戶的配置轉(zhuǎn)化為完整配置。
然后它將請求發(fā)送到服務(wù)器。
Axios 處理攔截器的方式很好地說明了 JavaScript 中的一流函數(shù)。
// ------------------------------- inside inteceptor's use method ------------------------//
InterceptorManager.prototype.use = function use(fulfilled, rejected, options) {
this.handlers.push({
fulfilled: fulfilled,
rejected: rejected,
synchronous: options ? options.synchronous : false,
runWhen: options ? options.runWhen : null
});
return this.handlers.length - 1;
};
// -------------------------------- process interceptors ---------------------------------//
// filter out skipped interceptors
var requestInterceptorChain = [];
var synchronousRequestInterceptors = true;
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {
return;
}
synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;
requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);
});
// ------------------------------- execute synchronous interceptors ---------------------//
var newConfig = config;
while (requestInterceptorChain.length) {
var onFulfilled = requestInterceptorChain.shift();
var onRejected = requestInterceptorChain.shift();
try {
newConfig = onFulfilled(newConfig);
} catch (error) {
onRejected(error);
break;
}
}
在第 23 行,我們在 usemethod 中傳遞的已完成和被拒絕的函數(shù)被添加到 requestInterceptorChain。我們將函數(shù)存儲在數(shù)組中。
然后 Axios 將運行它們中的每一個。在 while 循環(huán)中,您可以看到函數(shù)被分配給要調(diào)用的變量。
讓我們好奇——第 2 部分
發(fā)送 HTTP 請求不限于前端開發(fā)。在開發(fā)后端部分時,我們可能需要向外部服務(wù)器發(fā)送請求。您能否向我們解釋一下如何以您的首選語言處理 HTTP 請求配置?歡迎在留言區(qū)分享您的想法。
在 Node.js 中處理 HTTP 請求
使用 Node.js,我們可以使用 JavaScript 開發(fā)后端部分。后端開發(fā)是關(guān)于處理 HTTP 請求,即:接收它們,解析它們,找到正確的答案,并響應(yīng)客戶端。Node.js 最常用的框架之一是 Express.js。
該框架使用中間件來完成上述任務(wù)。以下是 Express 官方頁面中中間件的定義:
中間件函數(shù)是可以訪問請求對象 (req)、響應(yīng)對象 (res) 和應(yīng)用程序請求-響應(yīng)循環(huán)中的下一個中間件函數(shù)的函數(shù)。
您可以在下面看到中間件的示例。
var express = require('express');
var app = express();
app.use('/users', function (req, res, next) {
// assume only authenticated users can access to /users route
if(!req.user) {
// non authenticated users
res.json({status : "failed", message: "Please login!"});
return;
}
// if users is authenticated, go to the next middleware
next();
});
中間件函數(shù)在 use 方法中傳遞。反過來,它接受另一個函數(shù) next 作為參數(shù)。最后調(diào)用 next 函數(shù),將控制權(quán)傳遞給堆棧中的以下中間件。
Express 因其簡單性而廣受歡迎并被廣泛使用?!耙粋€ Express 應(yīng)用程序本質(zhì)上是一系列中間件函數(shù)調(diào)用?!?盡管看起來微不足道,但 Express 的中間件可以幫助我們完成 Web 服務(wù)器的所有任務(wù):記錄請求、壓縮響應(yīng)、設(shè)置 cookie、防止 XSS 攻擊……僅舉幾例。
讓我們再次好奇!
HTTP 請求在其他后端框架中是如何處理的?您能將它與 Express 中間件進行比較嗎?每種方法的優(yōu)點/缺點是什么?你看,有很多問題要研究!
最后但并非最不重要的——JavaScript 中的回調(diào)地獄
如您所知,JavaScript 是單線程的。但它提供了一種有效的機制來處理長時間運行的任務(wù)。我們可以立即開始下一個任務(wù),而不是等待任務(wù)完成,并定義前一個任務(wù)完成后我們需要做什么。這就是回調(diào)函數(shù)的來源——定義在長時間運行的任務(wù)后應(yīng)該運行什么。
import { readFile } from 'fs';
readFile('/etc/passwd', (err, data) => {
if (err) throw err;
console.log(data);
});
回調(diào)函數(shù)為我們提供了一個強大的工具來處理 I/O 綁定的應(yīng)用程序。然而,任何好事如果被濫用都會變壞。您可以查看下面的示例。
fs.readdir(source, function (err, files) {
if (err) {
console.log('Error finding files: ' + err)
} else {
files.forEach(function (filename, fileIndex) {
console.log(filename)
gm(source + filename).size(function (err, values) {
if (err) {
console.log('Error identifying file size: ' + err)
} else {
console.log(filename + ' : ' + values)
aspect = (values.width / values.height)
widths.forEach(function (width, widthIndex) {
height = Math.round(width / aspect)
console.log('resizing ' + filename + 'to ' + height + 'x' + height)
this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(err) {
if (err) console.log('Error writing file: ' + err)
})
}.bind(this))
}
})
})
}
})
多個回調(diào)函數(shù)和 if/else 語句使代碼難以理解。如果我們添加更多邏輯,它在未來可能變得不可維護。由于這個問題,引入了更新的功能。Promise 似乎可以幫助我們編寫一個更簡潔的程序。Async/await 關(guān)鍵字允許我們編寫看起來像同步代碼的異步代碼。
本文鏈接:http://jmtianhui.com/news/details-12-798.html
版權(quán)聲明:
1:本站所有內(nèi)容均由互聯(lián)網(wǎng)收集整理、上傳,并且以計算機技術(shù)研究交流為目的,僅供大家參考、學(xué)習(xí),不存在任何商業(yè)目的與商業(yè)用途,如描述有誤或者學(xué)術(shù)不對之處歡迎及時提出,不甚感謝。
2、 如涉及版權(quán)問題,請聯(lián)系我們4724325@qq.com第一時間處理;
我們從以下三個方面,對比純靜態(tài)和偽靜態(tài)兩種靜態(tài)頁面生成方式,逐一展開分析。
用JS的正則表達式如何判斷輸入框內(nèi)為中文或者是英文數(shù)字,或者是三者混編
css制作扇形
純CSS3文字Loading動畫特效
PhpStorm 2022.1 EAP 3 在 PHPDoc 和屬性中添加了對多行和嵌套數(shù)組形狀的完全支持:在這種情況下,可以使用數(shù)組形狀注釋定義數(shù)組結(jié)構(gòu),以獲得鍵的代碼補全并推斷值的類型。
PHP作為Web界第一大語言近年來熱度不夠,但是這幾年的進步和成長卻沒有中斷。在2022伊始,我們來一起學(xué)習(xí)一下目前PHP的現(xiàn)狀以及最新版本帶來的特性。
Linux程序前臺后臺切換:在Linux終端運行命令的時候,在命令末尾加上 & 符號,就可以讓程序在后臺運行Ubuntu$">root@Ubuntu$ ./tcpserv01 &
Python 的正則表達式支持 多行模式,將每行文字分別匹配。然而各種操作系統(tǒng)里,換行符的表示法各不相同,會導(dǎo)致 Python 不能正確使用多行模式。