
朋友们,美好的一天!
我向您介绍了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, }, }
这是React中的样子:
此功能使您可以做一些有趣的事情:
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'}, ], }, }
2.模块
这是我几乎在每个文件中使用的另一个功能。 在模块成为语言的一部分之前,我们必须使用奇怪的库和工具来处理大型项目。 有了模块(以及诸如Rollup或Webpack之类的构建器),我们就有了很好的机会与他人共享代码。
以下是几个示例:
如果您想了解更多有关模块的信息,可以观看我的youtube视频-
“比您想了解的ES6模块更多的信息”。3.默认设置
我一直喜欢并使用此功能。 这适用于函数参数和解构。 这是用于重组对象的方式:
const bench = {type: 'Piano', adjustable: false} const {legs = 4} = bench
请注意,基准对象不具有legs属性。 如果没有默认参数语法,则legs值将是不确定的。
您还可以将破坏性分配与该功能配合使用:
const bench = {type: 'Piano', adjustable: false} const {legs: legCount = 4} = bench
这是参数列表中的外观:
function getDisplayName(firstName = 'Unknown', lastName = 'Unknown') { return `${firstName} ${lastName}` }
此功能还允许您做一些非常有趣的事情,因为仅在必要时才计算“ =”符号右边的值。 这意味着您可以使用它来检查所需的参数:
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`) }
有些人认为此代码过于复杂。 也许他们是对的。 但是了解它的工作原理非常酷!
哦,您注意到我们可以将先前的参数用作后续参数的默认参数的一部分(upperKind就是这种情况)? 太好了吧?
4.箭头功能
我经常使用箭头功能。 我喜欢函数表达式,但是,例如,如果我需要一个匿名回调函数(不想为它命名),或者想要获取隐式返回值,那么箭头函数就是我所需要的。
以下是一些使用箭头功能的示例:
const divide = (a, b) => a / b const getFive = () => 5 const identity = i => i const asArray = (...args) => args
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开发人员了! 希望本文对您有所帮助! 祝你好运