不断的困惑:为什么我仍然使用JavaScript函数语句
Back in the late 90’s — when I learned JavaScript — we were taught to write the “Hello World” function using a function statement. Like this…
上世纪90年代后期(当我学习JavaScript时),我们被教导使用函数语句编写“ Hello World”函数。 像这样…
function helloWorld() {return ‘Hello World!’;
}
These days it seems all the cool kids are writing the “Hello World” function like this…
如今,似乎所有很酷的孩子都在编写“ Hello World”功能,就像这样……
const helloWorld = () => 'Hello World!';
This is a function expression in ES2015 JavaScript and it’s sexy as hell. It’s beautiful to look at. It’s all one line. So terse. So lovely.
这是ES2015 JavaScript中的一个函数表达式 ,它像地狱般性感。 看起来很美。 全部都是一行。 太简洁了 好可爱。
It uses an arrow function which is one of the most popular features of ES2015.
它使用箭头功能,这是ES2015最受欢迎的功能之一 。
When I first saw this I was like:
当我第一次看到这个时,我就像:
So, after almost 20 years of JavaScript and after using ES2015 on a number of projects, here is how I would write the “Hello World” function today:
因此,经过将近20年JavaScript编写以及在多个项目上使用ES2015之后,下面是我今天编写“ Hello World”函数的方式:
function helloWorld() {return ‘Hello World!’;
}
Now that I have shown you the new way, I’m sure you can barely stand to look at the old school code above.
既然我已经向您展示了新的方式,那么我相信您几乎无法忍受查看上面的旧学校代码。
Three whole lines for just a simple little function! All those extra characters!
三行,仅需一个简单的小功能! 所有这些额外的字符!
I know what you’re thinking…
我知道你在想什么...
I love arrow functions, I really do. But when I need to declare a top level function in my code, I still use a good old-fashioned function statement.
我喜欢箭头功能,确实如此。 但是,当我需要在代码中声明一个顶级函数时,我仍然使用一个很好的老式函数语句。
This quote by “Uncle Bob” Martin explains why:
马丁·鲍勃叔叔的这段话解释了为什么:
“…the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code.
“……阅读与写作所花费的时间之比远远超过10:1。作为编写新代码的努力之一,我们一直在阅读旧代码。
“…the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code.
“……阅读与写作所花费的时间之比远远超过10:1。作为编写新代码的努力之一,我们一直在阅读旧代码。
Because this ratio is so high, we want the reading of code to be easy even if it makes the writing harder.”
因为这个比例太高了,所以我们希望代码的读取变得容易,即使这会使编写变得更加困难。”
Because this ratio is so high, we want the reading of code to be easy even if it makes the writing harder.”
因为这个比例太高了,所以我们希望代码的读取变得容易,即使这会使编写变得更加困难。”
— Robert C. Martin
-罗伯特·马丁
Function statements have two clear advantages over function expressions:
函数语句比函数表达式有两个明显的优点:
优势1:意图明确 (Advantage 1: Clarity of intent)
When scanning through thousands of lines of code a day, it’s useful to be able to figure out the programmer’s intent as quickly and easily as possible.
每天扫描成千上万行代码时,尽可能快速,轻松地找出程序员的意图很有用。
Take a look at this:
看看这个:
const maxNumberOfItemsInCart = ...;
You read all those characters and you still don’t know if the ellipsis represents a function or some other value. It could be:
您阅读了所有这些字符,但仍然不知道省略号是否代表函数或其他值。 它可能是:
const maxNumberOfItemsInCart = 100;
…or it could just as easily be:
…或者可能很容易:
const maxNumberOfItemsInCart = (statusPoints) => statusPoints * 10;
If you use a function statement, there is no such ambiguity.
如果使用函数语句,则不会有任何歧义。
Look at:
看着:
const maxNumberOfItemsInCart = 100;
…versus:
…与:
function maxNumberOfItemsInCart(statusPoints) {return statusPoints * 10;
}
The intent is crystal clear right from the start of the line.
从行的开头就可以清楚地看到意图。
But maybe you’re using a code editor that has some color-coding clues. Maybe you’re a speed reader. Maybe you just don’t think it’s that a big a deal.
但是也许您正在使用具有一些颜色编码提示的代码编辑器。 也许您是速读读者。 也许您只是认为这没什么大不了的。
I hear you. The terseness is still looking pretty sexy.
我听到你了 简洁仍然看起来很性感。
In fact, if this were my only reason, I might have found a way to convince myself that it’s a worthwhile tradeoff.
实际上,如果这是我唯一的原因,我可能已经找到一种方法使自己相信这是一个值得权衡的方法。
But it’s not my only reason…
但这不是我唯一的理由...
优势2:声明顺序==执行顺序 (Advantage 2: Order of declaration == order of execution)
Ideally, I want to declare my code more or less in the order that I expect it will get executed.
理想情况下,我希望按照我期望代码将被执行的顺序或多或少地声明我的代码。
This is the showstopper for me: any value declared using the const keyword is inaccessible until execution reaches it.
这对我来说是最重要的事情:使用const关键字声明的任何值都无法访问,直到执行为止。
Fair warning: I’m about to go all, “Professor JavaScript” on you. The only thing you need to understand in all the jargon below is that you cannot use a const until you’ve declared it.
合理的警告:我将全力以赴,“ Professor JavaScript”教授。 在下面的所有术语中, 您唯一需要了解的是, 在声明它之前,不能使用const 。
The following code will throw an error:
以下代码将引发错误:
sayHelloTo(‘Bill’);const sayHelloTo = (name) => `Hello ${name}`;
This is because, when the JavaScript engine reads the code, it will bind “sayHelloTo”, but it won’t initialize it.
这是因为,当JavaScript引擎读取代码时,它将绑定 “ sayHelloTo”,但不会初始化它。
All declarations in JavaScript are bound early, but they are initialized differently.
JavaScript中的所有声明都绑定得很早,但是它们的初始化方式有所不同。
In other words, JavaScript binds the declaration of “sayHelloTo” — reads it first and creates a space in memory to hold its value — but it doesn’t set “sayHelloTo” to anything until it reaches it during execution.
换句话说,JavaScript 绑定了“ sayHelloTo”的声明-首先读取它,并在内存中创建一个空间来保存其值 -但它不会将 “ sayHelloTo” 设置为任何东西,直到在执行期间到达它为止。
The time between “sayHelloTo” being bound and “sayHelloTo” being initialized is called the temporal dead zone (TDZ).
绑定“ sayHelloTo”和初始化“ sayHelloTo”之间的时间称为时间死区 (TDZ)。
If you’re using ES2015 directly in the browser (as opposed to transpiling down to ES5 with something like Babel), the following code actually throws an error too:
如果您直接在浏览器中使用ES2015(而不是像Babel这样转换为ES5),则以下代码实际上也会引发错误:
if(thing) { console.log(thing);
}
const thing = 'awesome thing';
The code above, written using “var” instead of “const”, would not throw an error because vars get initialized as undefined when they are bound, whereas consts are not initialized at all at bind time. But I digress…
上面的代码使用“ var”而不是“ const”编写, 不会引发错误,因为绑定时var被初始化为未定义 ,而在绑定时根本未初始化const。 但是我离题了……
Function statements do not suffer from this TDZ problem. The following is perfectly valid:
函数语句不受此TDZ问题的困扰。 以下内容完全正确:
sayHelloTo(‘Bill’);function sayHelloTo(name) {return `Hello ${name}`;
}
This is because function statements get initialized as soon as they are bound — before any code is executed.
这是因为函数语句一旦绑定就被初始化- 在执行任何代码之前 。
So, no matter when you declare the function, it will be available to its lexical scope as soon as the code starts executing.
因此,无论何时声明该函数,只要代码开始执行,它将在其词法范围内可用。
What I’ve just described above forces us to write code that looks upside down. We have to start with the lowest level function and work our way up.
我上面刚刚描述的内容迫使我们编写看起来颠倒的代码。 我们必须从最低级别的功能开始,然后逐步提高。
My brain doesn’t work that way. I want the context before the details.
我的大脑不能那样工作。 我想先了解一下背景信息。
Most code is written by humans. So it makes sense that most people’s order of understanding roughly follows most code’s order of execution.
大多数代码是由人类编写的。 因此,大多数人的理解顺序大致遵循大多数代码的执行顺序是有道理的。
In fact, wouldn’t it be nice if we could provide a little summary of our API at the top of our code? With function statements, we totally can.
实际上,如果我们可以在代码顶部提供一些有关API的摘要,那不是很好吗? 有了函数语句,我们完全可以做到。
Check out this (somewhat contrived) shopping cart module…
看看这个(有点虚构的)购物车模块…
export {createCart,addItemToCart,removeItemFromCart,cartSubTotal,cartTotal,saveCart,clearCart,
}function createCart(customerId) {...}function isValidCustomer(customerId) {...}function addItemToCart(item, cart) {...}function isValidCart(cart) {...}function isValidItem(item) {...}...
With function expressions it would look something like…
使用函数表达式,它看起来像……
...const _isValidCustomer = (customerId) => ...const _isValidCart = (cart) => ...const _isValidItem = (item) => ...const createCart = (customerId) => ...const addItemToCart = (item, cart) => ......
export {createCart,addItemToCart,removeItemFromCart,cartSubTotal,cartTotal,saveCart,clearCart,
}
Imagine this as a larger module with many small internal functions. Which would you prefer?
可以将其想象为一个具有许多内部小功能的大型模块。 你更喜欢哪个?
There are those who will argue that using something before you’ve declared it is unnatural, and can have unintended consequences. There are even extremely smart people who have said such things.
有些人会争辩说在您声明某物之前使用某物是不自然的,并且会产生意想不到的后果。 甚至有非常聪明的人都说过这样的话。
It is definitely an opinion — not a fact — that one way is better than the other.
绝对有一种观点(不是事实)是一种观点要优于另一种观点。
But if you ask me: Code is communication. Good code tells a story.
但是,如果您问我: 代码就是沟通。 好的代码讲述了一个故事。
I’ll let the compilers and the transpilers, the minifiers and the uglyfiers, deal with optimizing code for the machines.
我将让编译器和编译器,压缩程序和丑陋的程序处理机器的优化代码。
I want to optimize my code for human understanding.
我想优化代码以使人理解 。
但是那些箭头功能呢? (What about those arrow functions, though?)
Yes. Still sexy and still awesome.
是。 仍然性感又很棒。
I typically use arrow functions to pass a small function as a value to a higher order function. I use arrow functions with promises, with map, with filter, with reduce. They are the bees knees, my friends!
我通常使用箭头函数将小函数作为值传递给高阶函数。 我在promise,map,filter,reduce中使用箭头函数。 他们是蜜蜂的膝盖,我的朋友们!
Some examples:
一些例子:
const goodSingers = singers.filter((singer) => singer.name !== 'Justin Bieber');function tonyMontana() {return getTheMoney().then((money) => money.getThePower()).then((power) => power.getTheWomen());
}
I used a few other new JavaScript features in this article. If you want to learn more about the latest JavaScript standard (ES2015) and all the cool features it has to offer, you should get my quick start guide for free.
我在本文中使用了其他一些新JavaScript功能。 如果您想更多地了解最新JavaScript标准(ES2015)及其所提供的所有炫酷功能, 则应免费获得我的快速入门指南 。
My goal is always to help as many developers as possible, if you found this article useful, please hit the ❤ (recommend) button so that others will see it. Thanks!
我的目标始终是为尽可能多的开发人员提供帮助,如果您发现本文有用,请点击❤(推荐)按钮,以便其他人看到。 谢谢!
翻译自: https://www.freecodecamp.org/news/constant-confusion-why-i-still-use-javascript-function-statements-984ece0b72fd/
相关文章:

Tif文件合并类
using System; using System.Collections; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq;namespace Common {/// <summary>/// Title Tif文件合并类/// Author:ward/// </…

ubuntu /boot 空间清理
本文引用自 blog.csdn.net/yypony/article/details/17260153方法: 1: 在终端下察看已经安装的旧的内核: ctrlaltt——>进入终端——>输入命令:dpkg --get-selections|grep linux给 /boot文件目录分配空间的时候,…

Swift default参数
swift 支持默认参数,在声明方法的时候,可以给某个参数制定一个默认的使用值,当没有传入值的时候,使用默认的参数,当传入值存在的时候,使用对应的传入值 import UIKitvar str "Hello, playground&quo…

vs2017 open从v_宣布#Open2017,这是面向开发人员的除夕直播流
vs2017 open从vHere are a few reasons to stay home this New Year’s Eve:这是除夕之夜留在家里的一些理由: It’s the worst day of the year for fatal drunk driving deaths 这是致命的酒后驾车致死的一年中最糟糕的一天 It’s crowded 拥挤 It’s freaking c…

Laravel Predis Error while reading line from the server.
问题 Laravel说明文档中的 Redis 发布与订阅案例,命令行运行php artisan redis:subscribe 到60s自动断开并报错 [Predis\Connection\ConnectionException]Error while reading line from the server. [tcp://127.0.0.1:6379]解决 在config/database.php配置文件中&a…

android 带边框的圆角按钮
新建buttonstyle.xml 代码如下 <?xml version"1.0" encoding"UTF-8"?> <layer-list xmlns:android"http://schemas.android.com/apk/res/android"> <!-- 连框颜色值 --><item> <shape> <solid andr…

Swift 字面量表达
字面量是一个很强大的特性,对于缩短代码很有帮助 // // 1 字面量就是 简洁明了指出自己的类型并且为变量赋值的的值 // tom false 称之为字面量 let dog:String "tom"; let ok false;// Array 和 Dictionary 赋值的时候也是使用的字面量 let animals:Ar…

韩国文档的编码方式_像韩国学生学习英语一样学习编码
韩国文档的编码方式by Stephen Mayeux斯蒂芬马约(Stephen Mayeux) 像韩国学生学习英语一样学习编码 (Learn to code like a Korean student learns English) If this is the first you’ve heard of me, then there’s only one thing you need to know: I am an ESL Teacher …

mysql乱码解决
在 /etc/my.cnf加上下面二句: skip-character-set-client-handshakecharacter-set-server utf8转载于:https://www.cnblogs.com/sweetXiaoma/p/6170979.html

LoaderManager使用具体解释(三)---实现Loaders
这篇文字将介绍Loader<D>类,而且介绍自己定义Loader的实现。这是本系列的第三篇文章。一:Loaders之前世界二:了解LoaderManager三:实现Loaders四:实例:AppListLoader重中之重,假设你还没有…

Swift 条件编译,编译标记
1 swift 中的条件编译跟OC中的形式是相同的 #if DEBUGself.navigationView.backgroundColor Color_ff3b30;#elseself.navigationView.backgroundColor Color_main;#endif条件可以接受 os(MacOS) ,参数iOS tvOS等平台 arch(),参数为平台架构组合 arm64 ,i386 swift(),参数为版…

代码简介:向圣诞老人和他的精灵学习Google Analytics(分析)
Here are three stories we published this week that are worth your time:这是我们本周发布的三个值得您关注的故事: Learn Google Analytics from Santa and his elves: 12 minute read 向圣诞老人和他的精灵学习Google Analytics(分析): 阅读12分钟…

生物信息大数据数据库(NCBI、EBI、UCSC、TCGA)
想系统的学习生信数据库可以先看一下北大的公开课,有一章专门讲的数据库与软件: 1-生物信息学:导论与方法 北大\10 生物信息数据库及软件资源 一个优秀的生信开发者能够解决如下问题: 如何鉴定一个重要的且没有被解决的生物学问题…

Dispatch 执行ABC任务,执行完成之后刷新UI,指定任务D
在swift中分组管理异步任务的方式 1 group enter 和 leave 进行同步管理 func method1() {// 创建一个组 ,要是在一个控制器中去规划请求顺序,则这个组要是全局的组let group DispatchGroup();let queue DispatchQueue.global();//let imgsArr [&qu…

关于页游垂直同步的若干问题
这个问题要从人眼感觉抖动的原因来分析第一种情况是常说的屏幕撕裂,就是垂直同 步的事情,可以简单理解为显存的数据更新跟屏幕的绘制刷新缺少同步,一次屏幕刷新的结果可能是多次显存更新的片段集合,这种情况只能使用更接近垂直同步…

javascript函数式_JavaScript中的函数式编程—结合实际示例(第1部分)
javascript函数式by rajaraodv通过rajaraodv JavaScript中的函数式编程—结合实际示例(第1部分) (Functional Programming In JavaScript — With Practical Examples (Part 1)) Functional Programming(FP) can change the way you program for the better. But it’s hard t…
简介子窗口控件(api)
子窗口控件 壹佰软件开发小组 整理编译 回忆第七章的CHECKER程序。这些程序显示了矩形网格。当您在一个矩形中按下鼠标按键时,该程序就画一个x;如果您再按一次鼠标按键,那么x就消失。虽然这个程序的CHECKER1和CHECKER2版本只使用一个主窗口…

【MongoDB学习之一】初始MongoDB
环境 MongoDB4.0 win7_x64 CentOS6.5_x64 一、MongoDB简介 (1)MongoDB使用C开发。 (2)MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。 (3)MongoDB 将数据存储为一个文档。MongoDB是一个基于分布式文件存储的数据库。 (4)MongoDB使用BSON作为数据存储…

swift 和 oc中检测textfield是否输入数字
iOS 开发中用来检测输入框是否输入的是纯数字 Swift 版本 // 代理方法func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {//判断输入的是否是数字 否则无效var cs CharacterSet();// 获取除…

开源项目贡献者_如何吸引新的贡献者加入您的开源项目
开源项目贡献者by Shubheksha通过Shubheksha 如何吸引新的贡献者加入您的开源项目 (How to attract new contributors to your open source project) It’s hard to attract contributors to your FOSS project — especially contributors who are new to open source.很难吸…

滑动轮播图实现最后一张图片无缝衔接第一张图片
原理:使用insertBefore和insertAfter方法调整图片顺序。 测试:firefox/chrome/IE11正常 已知不足:每次播放均使用了一次insertBefore和insertAfter,可考虑在最后一张图的时候将前几张图片整体后移。以后有空再优化。 1、HTML结构 …

一个完整的Installshield安装程序实例—艾泽拉斯之海洋女神出品(三) --高级设置一...
一个完整的Installshield安装程序实例—艾泽拉斯之海洋女神出品(三) --高级设置一 原文:一个完整的Installshield安装程序实例—艾泽拉斯之海洋女神出品(三) --高级设置一上一篇:一个完整的安装程序实例—艾泽拉斯之海…

数据结构,堆和栈和队列的概念
数据结构,堆和栈和队列的概念 1 什么是数据结构 数据结构是计算机存储,组织数据的反复改。数据结构是指相互之间存在的一种或多种特定关系的数据元素集合。 2 数据结构的逻辑结构 1 集合结构,元素都是孤立存在的 2 线性结构 ,…

电子白板 矢量 编码_当涉及白板编码采访时,请记住准备
电子白板 矢量 编码by Andy Tiffany通过安迪蒂芙尼(Andy Tiffany) 当涉及白板编码采访时,请记住准备 (When it comes to whiteboard coding interviews, remember to PREP) PREP is a mnemonic I created to help you remember the steps involved in solving whit…

机器学习实战笔记(Python实现)-03-朴素贝叶斯
--------------------------------------------------------------------------------------- 本系列文章为《机器学习实战》学习笔记,内容整理自书本,网络以及自己的理解,如有错误欢迎指正。 源码在Python3.5上测试均通过,代码及…

SQLite.swift的简单使用
使用cocoapod 来进行引入 pod ‘SQLite.swift’ // // SQLiteTool.swift // CreateLectureForSwift // // Created by coder on 2019/6/25. // Copyright © 2019 AlexanderYeah. All rights reserved. // import Foundation import SQLite // id let id Expression(“…

Cypress USB开发文档列表(积累中)
CyUSB.chm(pdf) \Cypress\Cypress Suite USB 3.4.7\Driver Cypress CyUSB.sys Programmers Reference 内容: CyUsb.sys、CyUsb.inf 驱动程序介绍,如何绑定设备到驱动程序,以IOCTL Interface、CYIOCTL.Hd的解释为主要内容的编程指导,主…

对象冒充_使用您的精神探照灯进行冒充冒名顶替综合症
对象冒充by Jaime J. Rios由Jaime J. Rios “Stop that imposter! Seize them!”“停止冒名顶替者! 抓住他们!” I first spotted my imposter two years ago. It happened when I began learning how to code.两年前,我第一次发现了冒名顶…

grep 函数
linux grep命令1.作用Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。 2.格式gr…

iOS weak 自动置为nil的实现
1 weak 自动置为nil的实现 runtime 维护了一个Weak表,weak_table_t 用于存储指向某一个对象的所有Weak指针。Weak表其实是一个哈希表, key是所指对象的地址,value是weak指针的地址的数组。 在对象回收的时候,就会在weak表中进…