成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

JS 代碼越來越難讀了 ...

開發 前端
今天來給大家介紹 JavaScript 代碼的一個新運算符:管道運算符 |>。

對一個值執行連續操作

當我們在 JavaScript 中對一個值執行連續操作(例如函數調用)時,目前有兩種基本方式:

  • 將值作為參數傳遞給具體操作(如果有多個操作,則嵌套操作),例如:three(two(one(value)));
  • 將函數作為值上的方法調用(如果有多個方法,則為鏈式調用),例如:value.one().two().three()。

在 2020 年 JS 狀態調查中,“你認為 JavaScript 目前缺少什么?“ 問題中,希望擁有管道操作符 答案排行第四名。

看來大家當前對 JS 中連續操作的寫法還是不太滿意啊。

首先,如果是嵌套寫法的話,簡單的嵌套還好,但是當嵌套變得很深的時候就有點難以閱讀了。嵌套的執行流程是從右到左移動的,而不是我們正常閱讀代碼從左到右的方向。另外,我們在很多括號之間找到一個位置添加一些參數也比較困難。比如下面的代碼:

console.log(
chalk.dim(
`$ ${Object.keys(envars)
.map(envar =>
`${envar}=${envars[envar]}`)
.join(' ')
}`,
'node',
args.join(' ')));

對于鏈式調用,只有我們把方法指定為值的實例方法時才能用,這讓它具有很大的局限性。當然,如果你的庫設計的很好(比如 jQuery) 還是挺好用的。

管道式編程

Unix 操作系統有一個管道機制,可以把前一個操作的值傳給后一個操作。這個機制非常有用,使得簡單的操作可以組合成為復雜的操作。許多語言都有管道的實現,舉個簡單的例子:

function capitalize (str) {
return str[0].toUpperCase() + str.substring(1);
}
function hello (str) {
return str + ' Hello!';
}

上面是兩個簡單的函數,想要嵌套執行,傳統寫法和管道寫法分別如下:

// 傳統的寫法
exclaim(hello('conardli'))
// "Conardli Hello!"
// 管道的寫法
'conardli'
|> capitalize
|> hello
// "Conardli Hello!"

兩個互相競爭的提案

關于管道運算符,目前在 ES 中有兩個相互競爭的提案:

Microsoft 提出的 F# :是一種函數式編程語言,其核心基于 OCaml,這個運算符可以很方便的寫出柯里化風格的代碼。

Meta 提出的 Hack:大致是 PHP 的靜態類型版本。這個管道運算符專注于柯里化函數以外的語言特性。

目前來看,Meta 提出的 Hack 應該更收社區的歡迎,Microsoft 提出的 F# 已經多次被 TC39 打回去了。不過不用擔心,F# 的優勢后續也可能會引入 Hack 中。

下面我們分別來看看兩個提案的用法吧。

Hack 管道運算符

下面是一個 Hack 管道運算符 |> 的簡單示例:

'ConardLi' |> console.log(%)  // ConardLi

管道運算符 |> 的左側是一個表達式,它被計算并成為特殊變量 % 的值。我們可以在右側使用該變量。返回右側的執行結果。前面的例子等價于:

console.log('ConardLi') // ConardLi

下面還有一些和其他寫法配合的例子:

value |> someFunction(1, %, 3) // function calls
value |> %.someMethod() // method call
value |> % + 1 // operator
value |> [%, 'b', 'c'] // Array literal
value |> {someProp: %} // object literal
value |> await % // awaiting a Promise
value |> (yield %) // yielding a generator value

下面我們再來看個更復雜點的例子,一個嵌套函數調用:

const y = h(g(f(x)));

Hack pipe 操作符可以讓我們更好地表達這段代碼的意思:

const y = x |> f(%) |> g(%) |> h(%);

這段代碼更符合我們常規的編碼思想,代碼從左到右依次執行:f、g、h

F# 管道運算符

F# 管道運算符與 Hack 管道運算符大致相似。但是,它沒有特殊變量 %。相反,運算符右側的函數并會直接應用于其左側。因此,以下兩個表達式是等價的:

'ConardLi' |> console.log
console.log('ConardLi')

因此 F# 管道運算符更適合單參數的函數,下面三個函數是等價的:

const y = h(g(f(x))); // no pipe
const y = x |> f(%) |> g(%) |> h(%); // Hack pipe
const y = x |> f |> g |> h; // F# pipe

在這種情況下,Hack pipe 比 F# pipe 更冗長。

但是,如果是多參數的情況下,F# pipe 的寫法就要復雜一點了:

5 |> add2(1, %) // Hack pipe
5 |> $ => add2(1, $) // F# pipe

可以看到,F# pipe 還要多寫一個匿名函數,這顯然相對與 Hack pipe 來講缺失了一些靈活性。這可能也是大家更傾向于 Hack pipe 的原因。

管道運算符的一些實際用例

嵌套函數調用的扁平寫法

JavaScript 標準庫創建的所有迭代器都有一個共同的原型。這個原型是不能直接訪問的,但我們可以像這樣檢索它:

const IteratorPrototype =
Object.getPrototypeOf(
Object.getPrototypeOf(
[][Symbol.iterator]()
)
)
;

使用管道運算符,代碼會更容易理解一些:

const IteratorPrototype =
[][Symbol.iterator]()
|> Object.getPrototypeOf(%)
|> Object.getPrototypeOf(%)
;

后期處理

看看下面的代碼:

function myFunc() {
// ···
return conardLi.someMethod();
}

如果現在我們想在函數返回前對返回值做一些其他的操作,我們應該怎么辦呢?

在以前我們肯定要定義一個臨時變量或者在函數外側再包一個函數,使用管道運算符,我們可以這樣做:

function myFunc() {
// ···
return theResult |> (console.log(%), %); // (A)
}

在下面的代碼中,我們后處理的值是一個函數 — 我們可以向它添加一個屬性:

const testPlus = () => {
assert.equal(3+4, 7);
} |> Object.assign(%, {
name: 'Test the plus operator',
});

前面的代碼等價于:

const testPlus = () => {
assert.equal(3+4, 7);
}
Object.assign(testPlus, {
name: 'Testing +',
});

我們也可以像這樣使用管道運算符:

const testPlus = () => {
assert.equal(3+4, 7);
}
|> (%.name = 'Test the plus operator', %)
;

鏈式函數調用

我們可以用 Array 的一些方法例如 .filter()和 .map() 實現鏈式調用,但是這僅僅是內置在數組里的一些方法,我們沒辦法通過庫引入更多的 Array 方法。

使用管道運算符,我們可以像數組本身的方法一樣實現一些其他方法的鏈式調用:

import {Iterable} from '@rauschma/iterable/sync';
const {filter, map} = Iterable;
const resultSet = inputSet
|> filter(%, x => x >= 0)
|> map(%, x => x * 2)
|> new Set(%)
;

最后再回來看看標題的代碼:

const regexOperators =
['*', '+', '[', ']']
.map(ch => escapeForRegExp(ch))
.join('')
|> '[' + % + ']'
|> new RegExp(%)
;

實際上就等價于

let _ref;
const regexOperators =
(
(_ref = ['*', '+', '[', ']']
.map(ch => escapeForRegExp(ch))
.join('')),
new RegExp(`[${_ref}]`)
);

和引入中間變量相比,管道運算符是不是更易于閱讀且簡潔呢。

參考

??    https://github.com/tc39/proposal-pipeline-operator ??

??    https://2ality.com/2022/01/pipe-operator.html ??

責任編輯:龐桂玉 來源: 大前端技術之路
相關推薦

2022-05-17 09:17:45

JS 代碼越來越難讀

2021-04-15 13:48:08

視頻監控視頻分析智能安防

2017-12-26 15:34:55

2024-02-21 09:44:33

Rust前端

2017-10-27 12:28:14

云端遷移云計算

2021-08-03 11:09:41

智能手機功能技術

2018-08-23 07:24:40

MEC多接入邊緣計算網絡邊緣

2010-07-08 09:03:20

openSUSE 11Fedora

2021-05-18 15:12:06

開源軟件云服務

2019-10-28 15:10:31

懶人剪輯運動相機移動應用

2020-09-02 09:25:23

遷移公共云數據

2021-04-02 13:00:51

大數據數據采集

2023-02-21 09:29:57

ChatGPT人工智能

2011-12-01 09:33:17

Google微軟

2019-12-26 09:42:54

互聯網免費收費

2018-05-29 12:00:51

前端工作互聯網

2020-08-13 09:49:43

WAF應用安全網絡安全

2013-09-22 11:04:31

Google應用UI設計Android Des

2021-09-18 09:52:07

AI 數據人工智能

2021-12-21 10:33:22

APIWeb安全
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 狠狠躁天天躁夜夜躁婷婷老牛影视 | 亚洲网站在线观看 | 波多野结衣在线观看一区二区三区 | 国产精品久久久久久久久久久久午夜片 | 欧美精品一区二区三区在线播放 | 在线激情视频 | 仙人掌旅馆在线观看 | 久久精品视频在线观看 | 亚洲视频二区 | 国产精品久久久久久久久久尿 | 粉嫩在线 | 亚洲色图插插插 | 国产精品成人一区二区三区夜夜夜 | 日韩av成人 | 日本黄色免费大片 | 999热精品视频 | 亚洲免费在线视频 | 国产精品免费av | 午夜影院在线观看 | 日本精品999 | 日韩成人在线视频 | 中文在线亚洲 | 91精品国产91久久久久久丝袜 | 欧美成人激情视频 | 久久精品国产久精国产 | 日本网站免费在线观看 | 亚洲国产精品一区二区三区 | 波多野结衣先锋影音 | 看片wwwwwwwwwww | 精品久久久久一区二区国产 | 欧美影院 | 亚洲综合国产 | 一区二区三区在线播放 | 在线观看你懂的网站 | 一级片av | 日本福利视频免费观看 | 黄网免费看 | 欧洲精品久久久久毛片完整版 | 久久精品69| 中文字幕亚洲精品 | 欧美不卡 |