不断的困惑:为什么我仍然使用JavaScript函数语句

news/2024/7/5 2:09:02

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/


http://lihuaxi.xjx100.cn/news/240407.html

相关文章

css样式分类

1.内联式(直接在标签里写属性,属性名为style) 2.内嵌式 (直接嵌入到head标签里面,以标签形式出现,标签名为style) 选择器:用来选择标签 1:用标签选择 2:用ID选择 关键符…

npm should be run outside of the Node.js REPL, in your normal shell

错误: npm should be run outside of the Node.js REPL, in your normal shell 在搭建vue环境时报错, 设置缓存文件夹 npm config set cache "D:\vueProject\nodejs\node_cache"和 设置全局模块存放路径 npm config set prefix “D:\vueProjec…

《数据科学R语言实践:面向计算推理与问题求解的案例研究法》一一2.1 引言...

本节书摘来自华章计算机《数据科学R语言实践:面向计算推理与问题求解的案例研究法》一书中的第2章,第2.1节,作者:[美] 德博拉诺兰(Deborah Nolan)  邓肯坦普朗(Duncan Temple Lang)  更多章…

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…

向下滚动页面导航悬浮

为什么80%的码农都做不了架构师?>>> 做两个导航,第二个隐藏 下拉到一定位置,显示第二个,position:fixed $(function(){$(window).scroll(function () {var top $(document).scrollTop();var m$(".nav")…

我国网络安全人才培养缺口巨大

近日在武汉举行的国家网络安全宣传周的相关论坛上,我国网络安全人才培养缺口巨大成为与会专家热议的话题。来自中央和地方相关部门、高校研究者、互联网企业代表均认为,我国网络安全人才输出仍距国家、企业需求有较大差距。 去年6月&#xff…

输入vue ui没反应

在cmd中输入 vue ui没有反应 输入 vue -h查看,发现是版本太低,根本没有ui 这是因为vue的版本太低导致的, 输入cnpm i -g vue/cli 升级脚手架即可 升级完成后,输入vue -h 最后输入vue ui即可

创业初体验

何为创业?为什么一开始就抛出这个问题。因为在“创业”这个词满天飞的今天,在政府对大众创业的倡导下,加之社会的鼓噪,创业仿佛成了一件人人可为之事,几乎每个咖啡馆都可以见到一拨拨的人在谈着自己的项目和梦想&#…