选择最适合的作用域包含变量和函数
考虑一个函数传统的方式是 , 声明一个函数, 在它内部添加代码. 标题这里做了一个角度的切换: 在编写代码外围包装一个函数说明, 去 "隐藏" 这段代码.
我们看第一个代码片段:
- function doSomething(a) {
- b = a + doSomethingElse( a * 2 );
- console.log( b * 3 );
- }
- function doSomethingElse(a) {
- return a - 1;
- }
- var b;
- doSomething( 2 ); // 15
关注这里的变量 b 和 doSomethingElse 函数, 很可能是 doSomething 函数的 "私有细节", 允许外围的作用可访问不仅没必要而且可能是危险的. 更加恰当的设计是将所有私有细节隐藏在 doSomething 内部:
- function doSomething(a) {
- function doSomethingElse(a) {
- return a - 1;
- }
- var b;
- b = a + doSomethingElse( a * 2 );
- console.log( b * 3 );
- }
- doSomething( 2 ); // 15
驱使做这样的代码隐藏, 是一种成为 "最低权限原则" 的软件设计原则, 也被称为 "最低授权" 或 "最少曝光", 即仅暴露所需要的最低限度的东西. 结合上个代码片段, 结合函数包围代码这个主体, 是用哪个作用域来包含变量和函数最适合的选择.
IIFE 与函数包围代码
我们看第二个代码片段:
- var a = 2;
- function foo() { // <-- 插入这个
- var a = 3;
- console.log( a ); // 3
- } // <-- 和这个
- foo(); // <-- 还有这个
- console.log( a ); // 2
在这段代码中, 有函数包围代码的痕迹, foo 函数存在的意义只是保障内部变量 a 的声明和 a 的输出. 但是额外引入了两个问题:
标识符名称 foo 污染了外部作用域
需要手动调用函数 foo--foo()
IIFE-- 立即调用的函数表达式可以解决这个问题:
- var a = 2;
- (function foo(){ // <-- 插入这个
- var a = 3;
- console.log( a ); // 3
- })(); // <-- 和这个
- console.log( a ); // 2
标识符名称 foo 仅存在于函数 foo 内, 且函数立即调用.
命名函数和匿名函数的比较
YDKJS-SCOPE CLOSURES-ch3 在讨论 IIFE 时候, 引入了命名函数和匿名函数的比较, 认为命名函数完胜, 三条理由:
匿名函数在 Call Stack 没有名称表示, 使调试更加困难
匿名函数情况下, 只能接用废弃的 arguments.callee 调用自己
有个描述性的名称更可读
但架不住匿名函数方便阿, 比如像 arr#map,arr#filter 等第一个参数传函数, 使用箭头函数 ()=>{} 比较便利. 所以我们来试着反驳这三条命名函数完胜的理由:
在 Call Stack 中一个是(anonymous), 一个是带名字的, 但是 debugger 位置都是定位的, so... 问题不是很大
无力反驳
第三点很容易理解, 但是一个混乱的函数名字其实更难理解, so...
总结一下: 如果函数需要在之后调用自己, 使用命名函数, 否则其实匿名函数更加方便; 如果使用了命名函数, 函数命名要讲究, 找了找函数命名规范:
考虑使用前缀
动词 | 含义 | 返回值 |
---|---|---|
can | 判断是否可执行某个动作 ( 权限 ) | 函数返回一个布尔值。true:可执行;false:不可执行 |
has | 判断是否含有某个值 | 函数返回一个布尔值。true:含有此值;false:不含有此值 |
is | 判断是否为某个值 | 函数返回一个布尔值。true:为某个值;false:不为某个值 |
get | 获取某个值 | 函数返回一个非布尔值 |
set | 设置某个值 | 无返回值、返回是否设置成功或者返回链式对象 |
比如:
- // 是否可阅读
- function canRead(){
- return true;
- }
- // 获取姓名
- function getName{
- return this.name
- }
建议动宾结构 --doSomething, 比如 openFile,setName,addNumber
谨慎使用缩写, 除非是 hi 约定成俗广泛使用的缩写, 否则老老实实使用完整拼写
参考链接
YDKJS-SCOPE&CLOSURES-ch3
掘金 - 前端开发规范: 命名规范...
掘金 - 谈谈函数的命名规范
来源: https://juejin.im/post/5c5e8723e51d45015b4c945a