常见的作用域类型有哪些?

103 阅读2分钟

作用域可以有多种类型。以下是几种常见的作用域类型:

  1. 全局作用域: 在代码中任何地方都能访问到的对象拥有全局作用域。最外层函数和变量,所有未定义直接声明的变量,以及window的所有属性通常都拥有全局作用域。但全局作用域的一个缺点是可能会导致操作命名空间的污染。

var globalVar = "I am global!";  

function myFunction() {  
  console.log(globalVar); // 可以访问全局变量  
}  

myFunction(); // 输出 "I am global!"
//globalVar,myFunction 是全局变量
  1. 函数作用域(局部作用域): 在函数内部定义的变量或函数具有函数作用域。这种作用域是分层的,内部作用域可以访问外部的作用域,但反之不行。

  
function myFunction() {  
  var localVar = "I am local!";  
  console.log(localVar); // 可以访问局部变量 
  function innerFunction(){
    var inner=888
    console.log(inner);
  }
  innerFunction()
}  
  
myFunction(); // 输出 "I am local!"  
innerFunction();//  ReferenceError: innerFunction is not defined,因为innerFunction 是在myFunction函数内部定义的,只能在myFunction内部访问
console.log(localVar); // ReferenceError: localVar is not defined,因为 localVar 只在 myFunction 函数作用域内存在
  1. 块状作用域(let和const关键字): 位于一对花括号之间的所有语句称为代码块,在代码块内部声明的标识符具有代码块作用域。当代码块处于嵌套状态时,声明于内层代码块的标识符的作用域到达该代码块的尾部便结束。在ES6(ECMAScript 2015)中引入了let和const关键字,它们为JavaScript提供了块级作用域。这意味着在{}中声明的变量或常量只在这些花括号内有效。

/**
 * 示例1:
*/  
if (true) {  
  let blockVar = "I am block-scoped!";  
  console.log(blockVar); // 可以访问 blockVar  
}  

console.log(blockVar); // 不可以访问 blockVar,因为blockVar只能在声明的{}内访问:ReferenceError: blockVar is not defined
/**
 * 示例2:
*/  
if(true){
  let outsideBlockVar="I am outsideBlockVar block-scoped!"; 
  if (true) {  
    let blockVar = "I am block-scoped!"; 
    console.log(blockVar); // 可以访问 blockVar,输出"I am block-scoped!"
    console.log(outsideBlockVar); // 可以访问 outsideBlockVar ,输出"I am outsideBlockVar block-scoped!"
  } 
  console.log(blockVar); // 不可以访问 blockVar,因为blockVar只能在声明的{}内访问: ReferenceError: blockVar is not defined
}
  1. 动态作用域: JavaScript实际上并没有真正的动态作用域,而是词法作用域(lexical scoping),这意味着变量的作用域是在编写代码时确定的,而不是在运行时。但是,有些其他语言(如Perl和PHP的早期版本)确实支持动态作用域。在这些语言中,变量的可见性取决于代码的执行上下文。
var value=1

function fn(){
  console.log(value) //输出1
}
function food(){
  var value=2
  fn()
}
food()