函数作用域和块作用域
函数作用域和块作用域
函数中的作用域
考虑下面代码:
function foo(a){ var b = 2; // 一些代码 function bar(){ // ... } // 更多的代码 var c = 3; } 复制代码
由于标识符a、b、c和bar都附属于foo(...),因此都无法从foo(...)的外部对它们进行访问
bar();//失败 console.log(a,b,c);//全都失败 复制代码
函数作用域的含义是指:
属于这个函数的全部变量都可以在整个函数的范围内使用及复用
(事实上在嵌套的作用域中也可以使用)。能充分利用JavaScript变量可以根据需要改变值类型的“动态”特性
隐藏内部实现
最小授权或最小暴露原则:是指在软件设计中,应该最小限度的暴露必要内容,而将其他内容都“隐藏”起来,比如某个模块或对象的API设计
function doSomething(a) { b = a + doSomethingElse(a * 2); console.log(b * 3); } function doSomethingElse(a) { return a - 1; } var b; doSomething(2);//15 复制代码
内部私有化
function doSomething(a) { function doSomethingElse(a) { return a - 1; } var b; b = a + doSomethingElse(a * 2); console.log(b * 3); } doSomething(2);//15 复制代码
函数作用域
区分函数声明和表达式最简单的方法是看function关键字出现在声明中的位置(不仅仅是一行代码,而是整个声明中的位置)。如果function是声明中的第一个词,那么就是一个函数声明,否则就是一个函数表达式。它们最重要的区别就是它们的名称标识符将会绑定在何处。
匿名和具名
1、函数表达式可以使匿名的而函数声明则不可以省略函数名 2、匿名函数表达式的几个缺点
匿名函数在栈追踪中不会显示出有意义的函数名,使得调试很困难(
不方便调试
)如果没有函数名,当函数需要引用自身时只能使用已经过期的arguments.callee引用,比如在递归中。另一个函数需要引用自身的例子,是在事件触发后事件监听器需要解绑自身。(
引用自身复杂
)匿名函数省略了对于代码可读性/可理解性很重要的函数名。一个描述性的名称可以让代码不言自明。(
降低了代码的可读性
)
行内函数表达式非常强大且有用,始终给函数表达式命名是一个最佳实践
立即执行函数表达式(IIFE)
三种用法:
把它们当做函数调用并传参进去
var a = 2; (function IIFE(global) { var a = 3; console.log(a);//3 console.log(global.a);//2 })(window) console.log(a);//2 复制代码
解决undefined标识符的默认值被错误覆盖导致的异常(虽然不常见)
undefined = true;//绝对不要这样做 (function IIFE(undefined) { var a; if (a === undefined) { console.log("Undefined is safe here"); } })(); 复制代码
IIFE还有一种变化的用途是倒置代码的运行顺序,将需要运行的函数放在第二位,在IIFE执行之后当做参数传递进去
(function IIFE(def) { def(window); })(function def(global) { var a = 3; console.log(a);//3 console.log(global.a);//2 }) 复制代码
块作用域
块作用域是一个用来对之前的最小授权原则进行扩展的工具,将代码从在函数中隐藏信息扩展为在块中隐藏信息。
1、with with是块作用域的一种形式,用with从对象中创建出的作用域仅在with声明中而非外部作用域中有效.
2、try/catch try/catch的catch分句会创建一个块作用域,其中声明的变量仅在catch内部有效
try { undefined();//执行一个非法操作来强制制造一个异常 } catch (err) { console.log(err);//能够正常执行 } console.log(err);//err not found 复制代码
err仅存在catch分句内部,当试图从别处引用它时会抛出错误
3、let let关键字可以将变量绑定到所在的任意作用域中(通常是{..}内部),let为其声明的变量隐式地了所在的块作用域。
4、const 同样可以用来创建作用域变量,但其值是固定的(常量)
作者:illion
链接:https://juejin.cn/post/7025508527711977508