国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

前端開發利器Jsdoc:讓我們像寫Typescript一樣寫JavaScript

開發 前端
有沒有一種不用Typescript的解決方案呢?有,那就是今天的主角:Jsdoc;這可能是一個大家很少使用的開發利器;它是一個可以使你像寫Typescript一樣寫JavaScript;沒錯,Jsdoc主要就是用來給js添加類型信息的。

眾所周知的原因,由于JS的語言特性,任何開發工具都不能為JS提供足夠好的智能提示,正因為此,微軟創造的輪子:typescript,橫空出世!

那么,有沒有一種不用typescript的解決方案呢?有,那就是今天的主角:jsdoc;這可能是一個大家很少使用的開發利器;它是一個可以使你像寫typescript一樣寫JavaScript;沒錯,jsdoc主要就是用來給js添加類型信息的。

下面我們看一個簡單的函數,這個函數接收一個參數modalElement,由于編輯器不知道它是什么類型,所以在調用它的querySelector方法的時候,無法獲得編輯器的智能提示;同樣地,編輯器也無法給出btnClose的click方法的智能提示。

const closeModal = modalElement => {
if (modalElement) {
const btnClose = modalElement.querySelector('.el-dialog__close')
if (btnClose) {
btnClose.click()
return true
}
}
}

這時候,就該jsdoc出場了;它的語法需要寫在多行注釋中,因為它不屬于js語法的一部分;我們只需給modalElement和btnClose增加一個類型標注,編輯器就知道它們是什么類型,擁有什么能力了;

為函數參數指定類型,使用@param標記,語法:@param {類型} 參數名;為變量指定類型,使用@type標記,語法:@type {類型};代碼如下:

/** @param {HTMLDivElement} modalElement */
const closeModal = modalElement => {
if (modalElement) {
/** @type {HTMLLinkElement} */
const btnClose = modalElement.querySelector('.el-dialog__close')
if (btnClose) {
btnClose.click()
return true
}
}
}

現在,當我們把指針移入modalElement的時候,就不是一個簡單的any類型了,編輯器可以根據文檔注釋確定它是HTMLDivElement類型,我們在調用它的querySelector方法的時候就能得到編輯器的智能提示;當我們把指針移入click的時候,編輯器告訴我們,這個方法是從HTMLElement繼承來的。

@returns標注用于指定函數返回值數據類型;語法:@returns {類型};如下函數返回由HTMLDivElement構成的數組。

/** @returns {HTMLDivElement[]} */
const getAllModals = () => {
return Array.from(
document.body.querySelectorAll('.el-dialog__wrapper, .el-drawer__wrapper')
).filter(_ => {
return window.getComputedStyle(_, null).display !== 'none'
})
}

如下圖,當我們調用getAllModals函數返回值的reduce方法的時候,編輯器可以給出智能提示。

我們還可以使用@typedef標記自定義類型;語法:import('模塊路徑'),用于從模塊中導入TS類型定義;&符號用于合并2個類型;如下例子定義了一個名叫RouteConfig的類型,該類型在import('vue-router').RouteConfig的基礎上為meta字段增加了number類型的index字段。

/**
* @typedef {import('vue-router').RouteConfig & {meta: { index: number }}} RouteConfig
*/

如下例子定義了一個EntAccountInfo類型,包含2個字段:數值類型的id和字符串類型的password。

/**
* @typedef {{id: number, password: string}} EntAccountInfo
*/

如果我們的字段比較多,可以使用@property標記定義每個字段。

/**
* @typedef UserData 用戶數據
* @property {any} entid 租戶id
* @property {string} name 姓名
* @property {string} workNo 工號
* @property {string} userId 用戶id
* @property {string} username 登錄用戶名
*/

我們自定義的類型和內置類型用法完全一樣;請看下面例子,包含內置類型和我們上面創建的自定義類型;我們在給對象字段指定類型的時候,可以有2種寫法:寫在字段名前面或上面;大家覺得哪種風格優雅?

export const state = Vue.observable({
/** @type {string[]} */ keeps: [],
/** @type {RouteConfig[]} */ menus: [],
/** @type {EntAccountInfo} */ entInfo: {},
/** @type {UserData} */ userData: {},
})
export const state = Vue.observable({
/** @type {string[]} */
keeps: [],
/** @type {RouteConfig[]} */
menus: [],
/** @type {EntAccountInfo} */
entInfo: {},
/** @type {UserData} */
userData: {}
})

我們可以使用管道符為一個變量指定多個可能的類型,請看如下例子,當用戶調用該函數的時候,編輯器會提示該函數期望接收一個類型為日期或字符串或數值的參數time。

/** @param {Date | string | number} time */
export const getHalfYearAfterTime = time => {
const date = new Date(time)
date.setMonth(date.getMonth() + 6)
date.setDate(date.getDate() - 1)
return date
}

如果我們的函數有不限個數的參數,可以使用語法:@param {...類型} 參數名,指定參數類型;請看如下例子:

/** @param  {...string} paths */
export const getApiUrl = (...paths) => joinPath(API_BASE, ...paths)

不限參數個數的函數,還有更高級的類型標注寫法;請看如下代碼,formRequest是一個axios的實例,我們想每次發起post請求的時候少寫10來個字符,定義了一個post函數,直接返回了對formRequest的post方法調用。

export const post = (...args) => formRequest.post(...args)

通過編輯器的提示,我們得知axios的post方法有3個不同類型的參數;而我們為了省事,使用了展開運算符,不管傳入多少個參數,全部仍給axios實例的post方法;那么,參數類型該如何標注呢?

我們可以使用中括號語法為每個參數指定字段名和類型,例子如下:

/** @param  {[url: string, data?: any, config?: RequestConfig]} args */
export const post = (...args) => formRequest.post(...args)

下圖是當指針移入post函數上時,編輯器給出的提示;是不是很酷?

如下是RequestConfig的類型定義,我們擴展了AxiosRequestConfig,為其增加了2個布爾類型字段;現在當我們調用post函數的時候,編輯器就會知道我們的第3個參數config包含這2個布爾類型字段。

/**
* @typedef {import('axios').AxiosRequestConfig & { needAuth: boolean, saveToken: boolean }} RequestConfig
*/

jsdoc還可以定義泛型類型,語法:@template 泛型名;請看如下例子,TreeNode是一個泛型類型,我們唯一能確定的是它有一個children字段;它具體還包含哪些字段,由泛型T決定。

/**
* @template T
* @typedef {T & {children: TreeNode[]}} TreeNode
*/

我們還可以在函數類型標注中使用泛型,請看如下例子,我們定義了一個泛型T,參數data為泛型T數組,返回值為泛型類型TreeNode<T>構成的數組。

/**
* @template T
* @param {T[]} data
* @param {{key: string, parentId: string}} config
* @returns {TreeNode<T>[]}
*/
export const toTree = (data, config) => {
const { key = 'id', parentId: pId = 'parentId' } = config || {}
const ids = data.map(_ => _[key])
/** @type {TreeNode<T>[]} */
const result = []
// ... ...
return result
}

以上就是我工作中最常用的jsdoc用法,還有很多用法沒有涉及到;篇幅有限,大家可以去官網查看文檔;希望該文章能助大家的JS技術更上一層樓,感謝閱讀!

責任編輯:姜華 來源: 今日頭條
相關推薦

2023-02-15 08:17:20

VSCodeTypeScrip

2023-05-23 13:59:41

RustPython程序

2023-08-09 09:03:25

Typescript工具Jsdoc

2022-10-12 08:05:04

PlantUML代碼運行環境

2013-01-29 10:07:13

建筑設計師寫程序程序員

2012-03-21 10:15:48

RIM越獄

2023-03-06 09:20:53

扁平化管理代碼

2015-02-05 13:27:02

移動開發模塊SDK

2025-09-12 00:00:00

DevToolsJavaScript調試術

2023-04-05 14:19:07

FlinkRedisNoSQL

2013-12-17 09:02:03

Python調試

2013-12-31 09:19:23

Python調試

2022-12-21 15:56:23

代碼文檔工具

2025-10-13 07:31:08

2017-11-07 10:09:39

Windows效率利器Everything

2017-03-15 16:17:20

學習命令計算機

2015-03-16 12:50:44

2013-08-22 10:17:51

Google大數據業務價值

2021-05-20 08:37:32

multiprocesPython線程

2012-06-08 13:47:32

Wndows 8Vista
點贊
收藏

51CTO技術棧公眾號

尤物tv国产一区| 国产精品17p| 欧美日韩一区中文字幕| 六月丁香激情网| 日韩精品一卡二卡三卡四卡无卡| 中文字幕制服丝袜在线| 成人在线视频亚洲| 在线观看久久久久久| 欧美wwwsss9999| 日韩欧美99| 日韩欧美色电影| 国产一区二区三区综合| 国产福利一区视频| 亚洲国产精品推荐| 国产精品99一区二区| 亚洲欧洲成视频免费观看| 国产丝袜一区二区三区免费视频 | 久久五月情影视| 久久国产一二区| 欧美一区二区激情| 中文字幕久久午夜不卡| 亚洲精品.com| 国产成人精品免费视频| 看电视剧不卡顿的网站| 天天干天天玩天天操| 极品美女销魂一区二区三区| 国内精品视频一区| 日韩精品免费专区| 亚洲五月天综合| 欧美日韩亚洲一区二区| 丰满诱人av在线播放| 国产精品高潮视频| 日本电影在线观看网站| 91嫩草国产在线观看| 黄色一级在线视频| 欧美精品www在线观看| 亚洲免费av在线| 中文字幕人成人乱码| 最美情侣韩剧在线播放| 欧美成人在线免费视频| 国产一区二区三区三区在线观看| 国产精品久久久久av电视剧| 啊v视频在线一区二区三区| 午夜精品视频| 亚洲一区二区三区加勒比| 99精品视频一区二区| 欧美aa一级| 色综合久久88色综合天天| 精品美女在线视频| 大地资源第二页在线观看高清版| 亚洲一区二区3| 日韩一区不卡| 加勒比海盗1在线观看免费国语版| 国产日韩欧美a| 菠萝菠萝蜜在线视频免费观看 | 免费资源在线观看| 一本大道综合伊人精品热热| 91在线不卡| 欧美欧美欧美欧美首页| 美女黄网久久| 白虎精品一区| 日韩一区在线看| 老司机性视频| 在线观看日韩视频| 日韩av网站免费在线| 一区在线电影| 精品久久久久久亚洲综合网 | 精品91久久| 亚洲成人黄色网址| av电影免费在线看| 欧美黄色性视频| 日本欧美在线观看| 色播色播色播色播色播在线| 国产精品久久久久久久天堂第1集 国产精品久久久久久久免费大片 国产精品久久久久久久久婷婷 | www.激情成人| 最新黄色av网站| 韩日av一区二区| 成年人在线视频| 国产精品高潮呻吟视频| 欧美一区二区视频在线观看2020| 99爱在线视频| 狠狠色狠色综合曰曰| av免费在线播放网站| 黄色免费网站在线观看| 国产精品 欧美在线| 中文字幕五月欧美| 国产成人福利av| 国产一二三区在线| 欧美一区欧美二区| 成人免费毛片app| 最新日韩一区| 69堂精品视频| 涩爱av色老久久精品偷偷鲁 | 伊人75在线| 亚洲午夜精品视频| 亚洲午夜精品一区二区国产| 国产不卡一区二区视频| 欧美男男青年gay1069videost| 成人豆花视频| 亚洲一二区在线 | 天堂在线亚洲| 中文欧美在线视频| 亚洲国产日本| 亚洲国产精品久久久| 日韩一区二区三区高清在线观看| 欧美tk丨vk视频| 日韩一区电影| 波多野结衣天堂| 亚洲欧美在线看| 久久久精品性| 欧美精品久久久久久久久久丰满| 韩国福利视频一区| 99re66热这里只有精品3直播 | 香蕉久久精品日日躁夜夜躁| 337p日本欧洲亚洲大胆精品| 日韩av片网站| 精品亚洲va在线va天堂资源站| 国产伦理一区| 精品国产百合女同互慰| 欧美777四色影| igao视频网在线视频| 99精品视频免费在线观看| 久久av导航| 拔插拔插海外华人免费| 精品1区2区3区| 免费精品一区| 色播五月综合| 久久只精品国产| 国产成人av影视| 亚洲成av人片在线观看香蕉| 亚洲精品麻豆| 欧美色图婷婷| xxxxx日韩| 69日小视频在线观看| 欧美成人h版在线观看| 国产精品剧情在线亚洲| 九热爱视频精品视频| 久久精品最新地址| 国产精品91一区二区| 91在线中字| 正在播放久久| 日韩在线视频免费观看| 日韩片之四级片| 国产精品久久久久99| 国产91视频一区| 欧美三级理论片| 精品视频一区二区三区四区| 中文字幕一区日韩电影| 亚洲福利一二三区| 亚洲理论在线| 青青国产精品| 成人免费网址在线| 久久成人资源| 亚洲最大成人在线| 久久久久999| 日韩中文字幕精品视频| 中文字幕精品—区二区四季| 欧美午夜精品一区二区三区电影| 金瓶狂野欧美性猛交xxxx| 北条麻妃av高潮尖叫在线观看| 91啪国产在线| 欧美极品美女电影一区| 日韩精品一区二区三区在线观看 | 国产亚洲一区| aaa大片在线观看| 97国产在线| 男人的天堂avav| 日韩欧美三级一区二区| 国产精品一区二区不卡视频| 国产精品扒开腿做爽爽爽视频| 国产视频亚洲精品| 91精品国产综合久久精品app| 国产亚洲xxx| 欧美日韩久久不卡| 在线免费一区三区| 精品人在线二区三区| 久久精品久久久久久| 日韩一区和二区| 成人av在线网| 久久久91精品国产一区二区精品| www国产精品av| 欧美日韩一级黄| 欧美亚洲爱爱另类综合| 黄色漫画在线免费观看| 中文字幕日韩一区二区三区| 91在线精品播放| 亚洲欧美日韩一区在线| 日韩免费观看高清完整版| 超碰日本道色综合久久综合| 国产精品午夜一区二区欲梦| 精品电影一区二区三区| 欧美一二三区在线观看| 欧美一级黄色片| 热99精品只有里视频精品| 伊人久久久久久久久久久久久| 日本久久久久久| 久草热视频在线观看| 电影天堂最新网址| 妞干网在线免费视频| 999sesese|