【JavaScript高级】7、函数高级(作用域与作用链)

一、作用域

1. 理解
  * 就是一块"地盘", 一个代码段所在的区域
  * 它是静态的(相对于上下文对象), 在编写代码时就确定了
2. 分类
  * 全局作用域
  * 函数作用域
  * 没有块作用域(ES6有了)
3. 作用
  * 隔离变量,不同作用域下同名变量不会有冲突
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>01_作用域</title>
</head>
<body>
<script type="text/javascript">
/*  //没块作用域
  if(true) {
    var c = 3
  }
  console.log(c)*/

  var a = 10,
    b = 20
  function fn(x) {
    var a = 100,
      c = 300;
    console.log('fn()', a, b, c, x)  // fn() 100 20 300 10
    function bar(x) {
      var a = 1000,
        d = 400
      console.log('bar()', a, b, c, d, x)
    }

    bar(100)  // bar() 1000 20 300 400 100
    bar(200)  // bar() 1000 20 300 400 200
  }
  fn(10)
</script>
</body>
</html>

 二、作用域与执行上下文

1. 区别1
  * 全局作用域之外,每个函数都会创建自己的作用域,作用域在函数定义时就已经确定了。而不是在函数调用时
  * 全局执行上下文是在全局作用域确定之后, js代码马上执行之前创建
  * 函数执行上下文是在调用函数时, 函数体代码执行之前创建
2. 区别2
  * 作用域是静态的, 只要函数定义好了就一直存在, 且不会再变化
  * 执行上下文是动态的, 调用函数时创建, 函数调用结束时就会自动释放
3. 联系
  * 执行上下文(对象)是从属于所在的作用域
  * 全局执行上下文==>全局作用域
  * 函数执行上下文==>对应的函数使用域
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>02_作用域与执行上下文</title>
</head>
<body>
<script type="text/javascript">
  var a = 10,
    b = 20
  function fn(x) {
    var a = 100,
      c = 300;
    console.log('fn()', a, b, c, x)  // fn() 100 20 300 10
    function bar(x) {
      var a = 1000,
        d = 400
      console.log('bar()', a, b, c, d, x)
    }

    bar(100)  // bar() 1000 20 300 400 100
    bar(200)  // bar() 1000 20 300 400 200
  }
  fn(10)
</script>
</body>
</html>

三、作用域链

1. 理解
  * 多个上下级关系的作用域形成的链, 它的方向是从下向上的(从内到外)
  * 查找变量时就是沿着作用域链来查找的
2. 查找一个变量的查找规则
  * 在当前作用域下的执行上下文中查找对应的属性, 如果有直接返回, 否则进入2
  * 在上一级作用域的执行上下文中查找对应的属性, 如果有直接返回, 否则进入3
  * 再次执行2的相同操作, 直到全局作用域, 如果还找不到就抛出找不到的异常
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>03_作用域链</title>
</head>
<body>
<script type="text/javascript">
  var a = 1
  function fn1() {
    var b = 2
    function fn2() {
      var c = 3
      console.log(c)  // 3
      console.log(b)  // 2
      console.log(a)  // 1
      console.log(d)  // 报错
    }
    fn2()
  }
  fn1()
</script>

</body>
</html>

 四、作用域—面试题

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>04_作用域_面试题</title>
</head>
<body>
<script type="text/javascript">
  var x = 10;
  function fn() {
    console.log(x);
  }
  function show(f) {
    var x = 20;
    f();
  }
  show(fn);  // 10 此处15行相当于调用fn()函数,然后打印x,在fn()作用域内找不到,往上一级作用域找是全局变量x=10
</script>
</body>
</html>

五、作用域—面试题2

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>04_作用域_面试题2</title>
</head>
<body>
<script type="text/javascript">
  var fn = function () {
    console.log(fn)
  }
  fn()
  /*输出:
  ƒ () {
    console.log(fn)
  }
   */

  var obj = {
    fn2: function () {
      //console.log(fn2)  // 此处会报错,变量fn2在函数内部找不到再往上也找不到,上面的fn2实际上是obj对象的属性即obj.fn2(或this.fn2)
      console.log(obj.fn2)
    }
  }
  obj.fn2()
</script>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/edc3001/article/details/85269944