阅读 167

函数作用域和块作用域

函数作用域和块作用域

函数中的作用域

考虑下面代码:

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


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐