5个JavaScript功能,如果没有这些功能,我将无法编写代码



朋友们,美好的一天!

我向您介绍了Kent Dodds 文章“我无法编写的5个JavaScript功能”的翻译。

这是我的第一篇翻译,因此我很乐意提出任何意见。

5个JavaScript功能,如果没有这些功能,我将无法编写代码


在开始之前,让我先谈谈我正在编写的代码。 我几乎所有的代码都包含Javascript,以及一些HTML和CSS。 我同时编写了客户端和服务器JS。 我正在测试我的代码。 我创建并分发了开放源代码库,供全球成千上万的开发人员使用。 对于前端,我将React用于后端-Express或无服务器计算。

这里有5个JS功能,没有它们我将无法编写代码。 以随机顺序。 当然,“没有我不能写代码”是夸张的。 这些是我真正喜欢的功能,并且一直被我使用。

1.重组


我几乎在所有文件中都使用了此功能。 无论是React组件还是带有参数的函数都没有关系;重组是一件很酷的事情。

以下是一些示例:
const address = { city: 'Salt Lake City', state: 'UT', zip: 84115, coords: { lat: 40.776608, long: -111.920485, }, } // ,    : const city = address.city const state = address.state const zip = address.zip //  ,    : const {city, state, zip} = address 

这是React中的样子:
 //  : function UserName(props) { return ( <div> </div> ) } //   : function UserName() { return ( <div> </div> ) } //    : function UserName({name: {first, last}}) { return ( <div> </div> ) } 

此功能使您可以做一些有趣的事情:
 const info = { title: 'Once Upon a Time', protagonist: { name: 'Emma Swan', enemies: [ {name: 'Regina Mills', title: 'Evil Queen'}, {name: 'Cora Mills', title: 'Queen of Hearts'}, {name: 'Peter Pan', title: `The boy who wouldn't grow up`}, {name: 'Zelena', title: 'The Wicked Witch'}, ], }, } //       , //          const { title, protagonist: { name: name, enemies: [, , , {title: enemyTitle, name: enemyName}], }, } = info console.log(`${enemyTitle} (${enemyName}) is an enemy to ${name} in "$5 JavaScript Features I Couldn't Code Without"`) 

2.模块


这是我几乎在每个文件中使用的另一个功能。 在模块成为语言的一部分之前,我们必须使用奇怪的库和工具来处理大型项目。 有了模块(以及诸如Rollup或Webpack之类的构建器),我们就有了很好的机会与他人共享代码。

以下是几个示例:
 // a.js //  function add(a, b) { return a + b } const foo = 'bar' const theAnswer = 42 const theQuestion = 'who knows' //        ,  //     ""    export default add export {foo, theAnswer, theQuestion} // b.js //  // 1.   import './a' // 2.    import add from './a' // 3.  `theAnswer`  `theQuestion`  './a' import {theAnswer, theQuestion} from './a' // 4.  `theAnswer`     `fortyTwo` import {theAnswer as fourtyTwo} from './a' // 5.  `add` ( )  `theQuestion` import {default as add, theQuestion} from './a' // 6.  `add`  `theQuestion`      import add, {theQuestion} from './a' // 7.     " "   `allTheThings` import * as allTheThings from './a' 

如果您想了解更多有关模块的信息,可以观看我的youtube视频- “比您想了解的ES6模块更多的信息”。

3.默认设置


我一直喜欢并使用此功能。 这适用于函数参数和解构。 这是用于重组对象的方式:
 const bench = {type: 'Piano', adjustable: false} const {legs = 4} = bench // `The bench has ${legs} legs` // -> The bench has 4 legs // bench - , leg -  

请注意,基准对象不具有legs属性。 如果没有默认参数语法,则legs值将是不确定的。

您还可以将破坏性分配与该功能配合使用:
 const bench = {type: 'Piano', adjustable: false} const {legs: legCount = 4} = bench // `The bench has ${legCount} legs` // -> The bench has 4 legs 

这是参数列表中的外观:
 function getDisplayName(firstName = 'Unknown', lastName = 'Unknown') { return `${firstName} ${lastName}` } // getDisplayName() // -> Unknown Unknown // getDisplayName('Andrew') // -> Andrew Unknown // getDisplayName(undefined, 'Yang') // -> Unknown Yang // getDisplayName('Andrew', 'Yang') // -> Andrew Yang 

此功能还允许您做一些非常有趣的事情,因为仅在必要时才计算“ =”符号右边的值。 这意味着您可以使用它来检查所需的参数:
 function getCandy( kind = requiredParam('kind'), size = requiredParam('size'), upperKind = kind.toUpperCase(), callback = function noop() {}, ) { const result = {kind, size, upperKind} callback(result) return result } function requiredParam(argName) { throw new Error(`${requiredParam} is required`) } // getCandy('twix', 'king') // -> {kind: 'twix', size: 'king', upperKind: 'TWIX'} // getCandy('twix') // -> : 'size is required' 

有些人认为此代码过于复杂。 也许他们是对的。 但是了解它的工作原理非常酷!

哦,您注意到我们可以将先前的参数用作后续参数的默认参数的一部分(upperKind就是这种情况)? 太好了吧?

4.箭头功能


我经常使用箭头功能。 我喜欢函数表达式,但是,例如,如果我需要一个匿名回调函数(不想为它命名),或者想要获取隐式返回值,那么箭头函数就是我所需要的。

以下是一些使用箭头功能的示例:
 const divide = (a, b) => a / b const getFive = () => 5 const identity = i => i const asArray = (...args) => args // ,         // (       ), //     ,  : const tryInvoke = (obj, fn, ...args) => { try { return obj[fn](...args) } catch (e) { return undefined } } //  ,   ,       const getObject = favoriteCandy => () //  JSX ( JS  React)        const MyComponent = () => ( <div> Hello world! I am a function and I return <strong>JSX!</strong> </div> ) 

5.承诺和异步/等待


JS是单线程的,并建立在事件系统(调用堆栈)上。 我非常喜欢像什么是事件循环这样的话题 (带有俄语字幕)。 Promise和async / await是管理此问题的好工具。 我的大多数代码都是异步的,这些工具极大地简化了我的工作。 老实说,诺言是一个严肃的话题,需要一些习惯,但诺言却很棒。

我经常在测试和后端中使用异步/等待。 这是一个异步测试的示例:
 test('Can fill out a form across multiple pages', async () => { mockSubmitForm.mockResolvedValueOnce({success: true}) const testData = {food: 'test food', drink: 'test drink'} const {findByLabelText, findByText} = render(<App />) user.click(await findByText(/fill.*form/i)) user.type(await findByLabelText(/food/i), testData.food) user.click(await findByText(/next/i)) user.type(await findByLabelText(/drink/i), testData.drink) user.click(await findByText(/review/i)) expect(await findByLabelText(/food/i)).toHaveTextContent(testData.food) expect(await findByLabelText(/drink/i)).toHaveTextContent(testData.drink) user.click(await findByText(/confirm/i, {selector: 'button'})) expect(mockSubmitForm).toHaveBeenCalledWith(testData) expect(mockSubmitForm).toHaveBeenCalledTimes(1) user.click(await findByText(/home/i)) expect(await findByText(/welcome home/i)).toBeInTheDocument() }) 

这是在Express中使用async \ await的示例:
 async function getListItems(req, res) { const listItems = await listItemsDB.query({ownerId: req.user.id}) res.json({listItems: await expandBookDataMultiple(listItems)}) } 

奇怪的是,我不经常在我的React代码中使用async / await(至少直接使用)。 这是因为我尝试在组件之外执行大多数“异步逻辑”。 因此,例如,如果我在React中调用useEffect时做异步的事情,我会限制自己对异步函数的一次调用,因为我发现使用promise比较容易:
 React.useEffect(() => { getUser().then( user => setState({status: 'success', error: null, user}), error => setState({status: 'error', error, user: null}), ) }, []) 

我建议您阅读Anthony Chu的文章“在节点中异步/等待”。

结论


我经常使用许多其他功能,这些功能可能会包含在此列表中。 这些功能是我的最爱,我总是转向它们。 该语言还有一些新鲜的东西尚未进入我的肌肉记忆。 现在是时候成为JS开发人员了! 希望本文对您有所帮助! 祝你好运

Source: https://habr.com/ru/post/zh-CN483822/


All Articles