为啥 js 语言里面 那么喜欢嵌套,匿名

2023-05-01 16:34:42 +08:00
 yagamil

作为一个后端,算法的开发者,平时会写点简单的页面。

不过看着 js,vue 的一些语法,感觉可读性非常差,函数喜欢用匿名的,在一个函数传参里面,把函数作为参数传入,导致的是,这个函数的参数 入参 非常冗长,不用 IDE ,根本不清楚这个匿名函数在哪里结束,因为里面可能还嵌套里其他参数。

好好定义一个函数名,设置一个好的名称,好好写,不行么?

还有链式调用有点泛滥。

这样做的原因是做什么?

5288 次点击
所在节点    程序员
50 条回复
nomagick
2023-05-01 18:32:45 +08:00
1. 你说得太对了
2. 不光是 vue, react 的可读性一样差,这是前端行业目前的结构性问题
3. 这个问题不是 javascript 的问题,甚至语言层面上有 typescript 解决了基本上所有问题
4. 根本上来讲是人的问题,而且是领路人的问题。
lower
2023-05-01 18:34:00 +08:00
前端如果不是写库或框架,只处理页面事件和后台交互的话,逻辑可能一般都比较短、也很分散,还可能经常业务会变化……
链式调用 不是因为回调地狱问题而搞得语法糖么?
ppooqq
2023-05-01 18:48:12 +08:00
js 就是一个缝缝补补过来的语音
liberty1900
2023-05-01 18:57:00 +08:00
这标题就有引导性。语言只是规范,规范里可从没强制要使用匿名函数和嵌套
TWorldIsNButThis
2023-05-01 19:03:56 +08:00
@Trello flutter 的嵌套是什么概念
没有 jsx 的 react 那种吗
anguiao
2023-05-01 19:06:41 +08:00
如果一个函数没有长到难以理解的话,为什么一定要拆分出来呢?
只用一次的函数,更没有必要专门起个名字。放在上下文里面,自然就知道它是用来干什么的。
banricho
2023-05-01 19:10:25 +08:00

不是……难道不是应该先问有没有再问为什么吗?
我咋就没遇到这个情况,你看的啥代码?
nbhaohao
2023-05-01 19:20:40 +08:00
因为在 JS 里, 函数是第一公民?
liuzhifei
2023-05-01 19:32:01 +08:00
用 react
janus77
2023-05-01 21:01:31 +08:00
他不是面向对象的
GeruzoniAnsasu
2023-05-01 21:20:05 +08:00
感觉楼上都没说到点子上。

「喜欢用匿名函数」的原因是,你正在使用的 function 要求传入一个 transformer , 由于这个 transformer 往往是定域的局部逻辑,因此基本上不会复用。不会复用,也就不用非得为它赋予一个公共名字,不需要命名自然就不命名了。

然后,为什么 js 写的代码更容易见到「传入 transformer 」这样的约定,本质上是因为前端的代码究其根本就是一系列状态转换函数。我们可以把 fetch 后端数据到渲染成 html 这个流程抽象为有一个 函数 F ,对后端传来的 json O 应用 F() 得到我们想要的 html:document = F(O) = "<html>...</html>"

这时候应该就很容易理解这与函数式编程的理念和思维方法不谋而合,我们逐渐把 F 细分,F(O) = Apply(O, Render1, Render2, ...) = Apply(O, (o)=>{renderComponent1(o.part1),renderComponent2(o.part2)},Render2, ...) ,然后把其中的某个部分,比如 renderComponent1 挖空逻辑变为接口,它自然就要求实现者实现具体的逻辑了:

type O = {part1:any}

function renderComponent1(o:O,impl:(o:O)=>HTMLElement) { // 要求传入一个把 O 转换为 DOM 的函数
document.appendChild(impl(o))
}

//你实际要写的
export function impl(o:O):HTMLElement{
const e = new HTMLDivElement()
e.innerText = o.part1
return e
// return ( <div>{o.part1}</div> )
}

这时候应该可以理解为什么传递函数作为参数是必要且常见的写法了。

不过这时候还有另一个问题,为什么非得是匿名函数不能是 function
—— 一句话来说,只有匿名函数(箭头函数)才可以完美 capture 上下文,这与 js 的语言债有关,作为半吊子就不展开了,可以自行翻阅关于 this 的前端八股文。
codehz
2023-05-01 21:29:35 +08:00
@GeruzoniAnsasu 最后那点其实不太对(
既然都 fp 了,还用啥 this 啊🤔️,没有 this 那用啥都差不多
还不是主要为了少打几个字(
chihiro2014
2023-05-01 21:32:40 +08:00
js 和 ts 的对象生命周期很迷
autoxbc
2023-05-01 22:32:12 +08:00
感觉回答的都不对,具名和匿名没有本质区别,只是排版上具名是扁平结构,匿名是嵌套结构。而很多炫技偏好的人,或者其他语言母语者,总是迷信把代码写成一行最酷,造成横向上嵌套过多

个人遵循一个编码习惯,对于括号和花括号嵌套,横向最多两层,第三层必须展开

// 这种写法不可接受,callback 部分有三层嵌套
initFn( callee , () => target.observeNode( () => callee.callback() ) ) ;

// 展开后会变成这样,读起来就没有负担
initFn( callee , () => {
target.observeNode( () => callee.callback() );
} ) ;
n18255447846
2023-05-01 22:42:45 +08:00
@humbass 我也是正学 c ,,函数不能嵌套有点难受,还不能动态分配内存。不过 c 可以传个函数指针进去
yagamil
2023-05-02 00:02:00 +08:00
@nomagick 我也觉得是,python 等语言也有回调,但人家会把回调抽出来,写成函数,即使不复用。

难到因为不复用,只用一次,就不能好好给一个规范的名字? 你们试过改过一个别人写的函数,超过几百行的吗?

当然一次性的项目,怎么写都没问题,只要你后面保证不会再看的话。。。
fox0001
2023-05-02 06:37:55 +08:00
@Trello #12 Flutter ,深有体会,特别需要依赖 IDE 才能更好地阅读…不过,主要代码作者可以优化一下。
dvsilch
2023-05-02 09:35:12 +08:00
用 lambda 通常是因为需要用到的变量生命周期只在某个函数作用域内...尤其是各种事件回调限定了入参,就只能自己考虑怎么 capture 上下文了
uni
2023-05-02 13:10:18 +08:00
问题的关键不在于匿名函数吧,而在于没有用 ts 好好定义类型吧
虽然有点偏激,但是类型是否清晰是我判断这个代码是不是带脑子的标准
uni
2023-05-02 13:11:20 +08:00
至于看函数是否结束,对我来说仅仅是代码格式化和括号高亮颜色的问题……

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/936734

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX