JavaScript基础:做用域和做用域链

1、什么是做用域javascript

简单来讲,做用域就是定义变量和函数的区域,变量和函数在该区域能够被访问。java

须要注意的有三点:闭包

  • 访问变量时,应从变量定义的做用域沿着做用域链向上查找函数

    var name = '小明';
    function fn1() {
      var name = "小红";
      function fn2() {
    	console.log('方法fn2中打印name:' + name); // 方法fn2中打印name:小红
      }
      fn2();
    }
    fn1();
  • 函数做用域只有函数才能建立,而且在该做用域在函数定义时就已经肯定了code

    // 例子1
    var name1 = '小明';
    function fn1() {
      console.log('方法fn1中打印name1:' + name1); // 方法fn1中打印name1:小明
    }
    function fn2() {
      var name1 = '小红';
      fn1();
      console.log('方法fn2中打印name1:' + name1); // 方法fn1中打印name2:小红
    }
    fn2();
    
    // 例子2
    var name2 = '小明';
    function fn3() {
      var name2 = '小红';
      return function() {
        console.log('闭包函数中打印name2:' + name2); // 闭包函数中打印name2:小红
      }
    }
    fn3();
    
    // 例子3
    var name2 = '小明';
    function fn3() {
      var name2 = '小红';
      fn4 = function() {
        console.log('闭包函数中打印name2:' + name2); // 闭包函数中打印name2:小红
      }
    }
    fn3(); // 必须执行fn3方法,不然函数做用域中的js代码不会被预解析和执行(Uncaught ReferenceError: fn4 is not defined)
    fn4();
  • JavaScript只有全局做用域和函数做用域(或者说局部做用域)。ES5是不存在块级做用域的(例如 if 和 for 体现了没有块级做用域),ES6的出现 提供了两个定义变量的方式 let/const ,才有了块级做用域。ip

    // 例子1
    if (true) {
      var name1 = "小明";
    }
    console.log(name1); // 小明  (name1能够被打印说明name1为全局的,不存在块级做用域)
    // 例子2
    if (true) {
      const name2 = "小明";
    }
    console.log(name2); // Uncaught ReferenceError: name2 is not defined

2、做用域链作用域

了解了做用域后,做用域链就好说了,那么什么是做用域链呢?通俗点讲,当你声明一个函数时,函数做用域一级一级向上包裹起来,这就是做用域链。io

须要注意的有两点:console

  • 函数被执行时,内部的局部变量应从其所定义的区域开始查找
  • 当在做用域中找不到该变量时,则向定义该函数做用域的做用域查找,依次向上
相关文章
相关标签/搜索