# 有几种作用域?

1.5种,函数作用域类似块作用域

# 函数作用域

JS有函数作用域
外部无法访问函数内部声明的变量和函数。
函数内部可以访问外部。

作用隐藏内部实现(即封装),把只有自己使用的内容放到自己内部私有化,可以防止命名重复。

var globalNum = 2; // 声明全局变量

function smile() {
  // 函数内部变量,外部无法访问
  var num = 1;
  var str = 'haha';

  console.log(globalNum); // 2  内部可以访问外部
}

# 立即执行函数表达式 IIFE(隐藏函数名)

函数名也会“污染”所在作用域,如果不需要函数名,并且希望函数能够自动运行,可以使用立即执行函数(IIFE)

// 两种写法效果一样,只是写法不同
(function test() { })(); 
(function test1() { }());
// 第一个()使函数变成表达式
// 第二个()执行了这个函数

// 可传递参数
(function smile(global) {
  global.num = 1; // 相当于window.num = 1;
})(window);
// 注:函数的形参传递的是对象,则是这个对象的指针引用
// 改变这个形参的值会影响原对象
// 所以一般传递对象又不想影响原对象,会进行深拷贝

函数名对IIFE来说不是必须的,常见用法是使用匿名函数表达式。但使用具名函数会有很多好处,好调试调用自身易读(一个合理的函数名,可以让使用者更快的了解函数的用途)。

# 块作用域

JS没有块作用域。

for() {}括号和内部if() {}内部var定义的变量会存在于forif所在的词法作用域。

for (var i = 0; i < 10; i++) {
  var num = 11;
}
console.log(i); // 10
console.log(num); // 11

if (num) {
  var str = '22';
}
console.log(str); // 22

例外

  • withtry/catchcatcherr会只在catch中存在,但catch内声明的变量存在于catch所在的词法作用域

  • let

    • 将变量绑定到所在的作用域中(通常是{ ... }内部)
    • 声明的变量不会在块作用域中进行提升(关于提升相关下一章讲解)
  • const

    • 将变量绑定到所在的作用域中(通常是{ ... }内部)
    • 声明的变量不会在块作用域中进行提升(关于提升相关下一章讲解)
    • 值不能修改,修改会报错,但对象类型可以修改属性的值

如果觉得内容对你有帮助,请点个关注,你们的鼓励是我持续更新下去的动力,比心。

如需转载请注明出处,感恩。

更多内容可先关注GitHub (opens new window)