JS高级:作用域与作用域链

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44627407/article/details/102720116

1.作用域
全局作用域
函数作用域
没有块块级作用域(ES6之前)
栗子:

if(true){
  var a = 3
}
console.log(a) //3

2.作用域的作用:隔离变量,使每个作用域中的同名变量不会相互影响(如,一个函数A中的的a,和函数B中的a相互独立,互不影响)

  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
    console.log(d) // 报错
    function bar(x) {
      var a = 100
      d = 200
      console.log('bar',a,b,c,d,x)
    }
    bar(100) // bar 100 20 300 200 100
    bar(200) // bar 100 20 300 200 200
  }
  fn(10)
// 以上例子产生N+1个作用域(N为定义的函数的个数)
//打印的变量时,寻找变量的过程就形成了一条作用于链:现在自身中查找-->若无,往包裹它的外面一层找-->若无,以此类推继续往上找,直到在全局作用域中找,找不到就报错(不可逆向寻找)

3.作用域与执行上下文的对比
联系:执行上下文从属于所在的作用域
(1)全局执行上下文从属于全局作用域
(2)函数执行上下文从属于函数(局部)作用域
区别:
(1)函数的作用域在定义时已经确定,而函数执行上下文则在函数调用时,在即将调用的时候才产生
(2)全局执行上下文是在全局作用域确定之后才产生的
(3)作用域是静态的,在创建后就不会改变;而执行上下文是动态的,比如,函数执行上下文,函数执行结束后就自动释放,函数执行上下文也就不存在了,但是函数的作用域仍然不变

面试题:
题目1:

  var x = 10
  function fn() {
    console.log(x)
  }
  function test(f) {
    var x = 20
    f()
  }
 test(fn) // 10
//或者
  var x = 10
 function fn() {
   console.log(this.x)  //因为函数定义时已经确定this,所以在test中调用也不会改变它的this,能改变this的有apply、call、with语句等
 }
 function test(f) {
   var x = 20
   f()
 }
 test(fn) // 10

解析:即使fn是在test中调用的,但是fn在定义时就确定了它的作用域,它内部访问不到x时,直接会去全局作用域中找,而不会去test中找

题目2:

var fn = function () { // fn用var声明,会被放到全局中
  console.log(fn)
}
fn() // 输出fn函数体,因为打印语句中的fn在函数自身没有找到,但是在全局中能找到fn

var obj = {
  fn1: function () {
    console.log(fn1)
    // console.log(this.fn1) 因为this指向obj,而obj对象中有属性有fn1,其值是一个函数
  }
}
obj.fn1() // 报错,因为打印语句中的fn在函数自身没有找到,在全局中也没有找到

猜你喜欢

转载自blog.csdn.net/weixin_44627407/article/details/102720116