惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Scott Helme
Scott Helme
有赞技术团队
有赞技术团队
阮一峰的网络日志
阮一峰的网络日志
雷峰网
雷峰网
D
Docker
Stack Overflow Blog
Stack Overflow Blog
Hugging Face - Blog
Hugging Face - Blog
爱范儿
爱范儿
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
MyScale Blog
MyScale Blog
A
About on SuperTechFans
博客园 - 【当耐特】
U
Unit 42
H
Help Net Security
博客园 - 三生石上(FineUI控件)
V2EX - 技术
V2EX - 技术
T
Tor Project blog
博客园 - 叶小钗
G
Google Developers Blog
S
Securelist
Security Latest
Security Latest
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Threat Research - Cisco Blogs
aimingoo的专栏
aimingoo的专栏
C
Cybersecurity and Infrastructure Security Agency CISA
博客园_首页
V
Vulnerabilities – Threatpost
P
Palo Alto Networks Blog
T
The Exploit Database - CXSecurity.com
The Register - Security
The Register - Security
Recorded Future
Recorded Future
NISL@THU
NISL@THU
量子位
L
LangChain Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
Cyber Attacks, Cyber Crime and Cyber Security
C
CERT Recently Published Vulnerability Notes
The Hacker News
The Hacker News
D
DataBreaches.Net
小众软件
小众软件
罗磊的独立博客
Forbes - Security
Forbes - Security
The Last Watchdog
The Last Watchdog
Jina AI
Jina AI
I
InfoQ
S
Schneier on Security
Recent Announcements
Recent Announcements
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
S
Secure Thoughts

Surmon.me

一人有限集团 你就是不敢 创造力是温柔的谎言 人类正在退出人类 AI 代替不了这样的你 脉冲点火背后的架构设计 基于 Cloudflare 生态的 AI Agent 实现 NodePress 支持用户登录了 从统计学习到通用智能 2025 投资报告:走慢的路 无依之地 会杀人的菩萨 无我不是共识 文化的积重与偏见 当下即安 科学的尽头是态度 无我不是 Egoless 信仰不因恐惧而存在 世间无解的矛与盾 先别急着做些什么 佛不需要你的皈依 真理的幻觉 两扇大门 造心里的浮屠 自胜者强 逻辑与智慧 真的相 快乐的秘密 只需愿意 是名体验 最深沉的梦 森林里倒下的树 现象与相 庸人自扰 React 与 Vue 的完美融合 开心就好吗 与原生家庭和解 两支毒箭 怎么自净其意 一尘不染 一片白云 让风穿膛而过 喝下去,然后闭嘴 活在当下 当纠结发生时 唯「我」独尊 一场把戏(时间) 一场把戏(二元对立) “我” 和 “我” 谁是众生? 船里没有人 玫瑰不需要说话 没有人能渡任何人 你我为轮,使之不再 当我们在谈论独立时 自我约束就是最好的自我接纳 从善与恶的表象出发 佛法不是心理学 别人眼中的你并不是你 高高山上走 祝你心想事成 祝你的噩梦早日发生 道是无情却有情 裙子只为自己而穿 不要盲目地评估自己 先别急着 “爱自己” 让生命欣然舞动 你无法复制乔布斯 符号不是目的 如果一件事发生了 每当我起心动念时 爱出者爱返 理解不是尊重的基础 在没有解决自己的问题之前 “知足常乐” 不是比较 逻辑是无法成为信仰的 买不到的自由 成为诵经者 伤口听不懂大道理 是立场让你不自由 - Unfreedom 天雨大不润无根之草 做自己的神 当心诱惑本身 牛洞冥思录 修罗启示录 让大脑自举 我更喜欢叫它无梦寺 存在主义也许不是解药 出南洋记 2022 的所有答复 没意义的表达 思考的记录 故宫暂行之幻想 极端的比较 解构的终极 舍利子是如何炼成的 心要野 佛教的偏见 文艺青年 我是动物
简洁编码指南
Surmon · 2017-04-11 · via Surmon.me

简洁编码指南

就三点:

  • 编码风格:忌简忌繁、统一风格
  • 编码结构:模块化、函数式、易读性、复用元素的抽象
  • 编码过程:扩展能力、测试

编码风格

保持良好的编码风格

  • 不要刻意简写难以理解的表达式,也不要嵌套过于冗余的函数
  • 缩进统一、命名统一、标符统一、文件结构统一... 一切能以标准量化的的都需要拿标准约束
  • Lint 等 QA 约束工具是必须的,用工具来实践程序正义

更详细的编码规范,可以来这: Developer code guide

编码结构

Spaghetti code (面条代码)的特征

  • 代码没有组织,且多处出现重复的代码块

    • 一般是封装粒度不够造成
  • 多个代码块之间高度耦合,跳来跳去,使其难以调试

    • 函数抽象程度不够
    • OOP 理解不深刻
    • 典型的命令式编程
  • 代码不会分解成条件块或标签,使其难以阅读。

    • 到这个程度就不知道代码写的有多糟了

避免面条代码的方法

  • 需要复用的代码一定要封装
  • “模块化” 不仅仅是文件意义的模块化,而是指逻辑单元的模块化,比如函数;当然现在大部分框架、库、平台... 都有自己成熟的模块化系统,在模块化的基础上尽量取得平衡
  • 函数的模块化和封装要尽量地 “函数式”,不依赖外部变量,不改变外部变量,有输入,有输出,不过度嵌套,中间量清晰易读
  • 避免全局变量和类成员传递数据,函数内部更应该优先使用局部变量和参数变量
  • 优秀的代码是不需要注释的,所以命名本身很重要很重要

优秀的代码组织应该是清晰的树状结构,自上而下分解任务, 自下而上完成任务。

编码过程

防止 over-engineering (过度设计)

过度设计是指,太过于考虑今后代码的扩展性、复用性,或太过于考虑测试的便利性,导致系统被过度设计为难以理解、难以重用的复杂结构。

世界上有两种 “没有 BUG” 的代码。一种是“没有明显 BUG 的代码”,另一种是 “明显没有 BUG 的代码”。

第一种情况,由于代码复杂不堪,加上很多测试,各种 coverage,看起来测试都通过了,所以就认为代码是正确的。

第二种情况,由于代码简单直接,就算没写很多测试,你一眼看去就知道它不可能有 BUG。

你钟爱哪一种?

防止过度设计的方法:

  • 先把眼前的问题解决掉,解决好,再考虑将来的扩展问题
  • 先写出可用的代码,反复推敲,再考虑是否需要重用的问题
  • 先写出可用,简单,明显没有 BUG 的代码,再考虑测试的问题

代码规范可以参考上面链接就可以了,可以根据自己的情况修改规范以建立自己的标准,下面分享一些平日较为不易理解的代码片段。

隐式转换

==!= 操作符会在需要的情况下自动转换数据类型; ===!== 不会,它们会同时比较值和数据类型,也称为严格比较。

        
        

12345678

[10] === 10 // false [10] == 10 // true '10' == 10 // true '10' === 10 // false [] == 0 // true [] === 0 // false '' == false // true (but true == "a" is false,因为true隐式转换为字符串为'1') '' === false // false

赋值判断

        
        

1234567891011

// 正常流程 var a if (b) { a = b } else { a = c } // 三目运算 var a = b ? b : c // 利用短路运算判断赋值 var a = b || c

数据类型判断 typeofinstanceof

        
        

123456789101112131415161718192021222324

/* typeof 会返回一个变量的基本类型,针对数组和对象均返回 'object' */ typeof 666 // 'number' typeof Date() // 'string' typeof [] // 'object' typeof {} // 'object' typeof false // 'boolean' typeof new Function() // 'function' typeof undefined // 'undefined' typeof null // 'object' /* instanceof 仅检测对象的原型链是否指向构造函数的 prototype 对象 由于 JavaScript 中万物皆对象,故一切用 new 关键字实例的对象最深原型永远指向 Object */ 666 instanceof Number // false new Number(666) instanceof Number // true new Number(666) instanceof Object // true '666' instanceof String // false new String('666') instanceof String // true new Object() instanceof Object // true [] instanceof Object // true [] instanceof Array // true new Date() instanceof Date // true new Date() instanceof Object // true

快速求和

        
        

123

// eval 能做的事真的太多了 var nums = [1, 2, 3, 4, 5, 6...] console.log('和:', eval(nums.join('+')))

简写判断

        
        

123456789101112131415

// 标准判断(推荐) if (a) { b() } // 简写 if (a) b() // 利用短路运算简写 a && b() // 或者(极力不推荐) var foo = 10 foo == 10 && doSomething() foo == 5 || doSomething()

with 作用域

        
        

1234

var obj = { name: 'xxx' } with (obj) { console.log(name) // 'xxx' }

复杂的流程控制

        
        

12345678910111213141516171819202122232425262728293031323334

// 一种不太好的情况 if (a) { doSomethingA() } else if (b) { doSomethingB() } else if (c) { doSomethingC() } else if (d || e) { doSomethingDE() } else if (f) { doSomethingF() } //... // 可以用switch/case来代替 switch (true) { case a: doSomethingA() break case b: doSomethingB() break case c: doSomethingC() break case d || e: doSomethingDE() break case f: doSomethingF() break default: doSomethingDefault() break }