JS基础知识题(中)作用域、闭包

说一下对变量提升的理解

JS的变量提升主要从两方面来说,变量定义、函数声明,二者都是把对应的内容放到对应定义时的执行环境的顶部,然后JS再开始往下依次解释(注意:函数声明的提升权重大于变量提升)

// 函数b和函数c的声明被放到了顶部
// var a
// var c
console.log(a) // undefined
console.log(c) // 此时输出的是函数c
var a = 100
var c = 100

b() // 我是b函数
function b() {
  console.log('我是b函数')
}
function c() {
  console.log('我是c函数')
}

说明 this 几种不同的使用场景

  • 作为对象的方法调用,this指向该对象
  • 作为普通函数调用,this指向window对象
  • 构造器调用,通常情况下构造函数里的this指向返回的这个对象
  • Function.prototype.call 和 Function.prototype.call 调用,可以动态的改变传入函数this的指向

创建10个 标签,点击的时候弹出对应的序号、

var i, a
for (i = 0; i < 10; i++) {
  // 利用闭包延长了每次i的生命周期
  ;(function (i) {
    a = document.createElement('a')
    a.innerHTML = i + '<br>'
    a.addEventListener('click', function (e) {
      e.preventDefault()
      alert(i) // 自由变量,要去父作用域获取值
    })
    document.body.appendChild(a)
  })(i)
}

如何理解作用域?

  • 自由变量:全局中定义了一个变量a,然后我在函数中使用了这个a,这个a就可以称之为自由变量,可以这样理解,凡是跨了自己的作用域的变量都叫自由变量。
  • 作用域链:即是自由变量的查找,JS会最先在使用该变量的作用域中查找,如果没有,则往上父级作用域查找,以此类推,直到全局作用域,这样就构成了一个作用域链
  • 闭包的两个场景:函数作为返回值;函数作为参数传递

实际开发中闭包的应用

// 封装私有变量
function isFirstLoad() {
  var _list = [] // 私有变量
  return function (id) {
    if (_list.indexOf(id) >= 0) {
      console.log('已经存在此状态')
      return false
    } else {
      _list.push(id) // _list 自由变量
      console.log('保存状态成功')
      return true
    }
  }
}
var firstLoad = isFirstLoad()
firstLoad(10) // true
firstLoad(10) // false
firstLoad(20) // true
firstLoad(20) // false
原文地址:https://www.cnblogs.com/cqkjxxxx/p/13336464.html