作用域和闭包——面试题

题目:

  • 说一下对变量提升的理解
  • 说明 this 几种不同的使用场景
  • 创建 10 个<a>标签,点击的时候弹出来对应的序号
  • 如何理解作用域
  • 实际开发中闭包的应用

1、说一下对变量提升的理解

函数执行时会先创建当前的上下文环境,其中这两点会产生“变量提升”的效果

  • 变量定义
  • 函数声明(注意和函数表达式的区别)

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

  • 作为构造函数执行
  • 作为对象属性执行
  • 作为普通函数执行
  • call apply bind

3、创建 10 个<a>标签,点击的时候弹出来对应的序号

错误的写法

var i, a
for (i = 0; i < 10; i++) {
    a = document.createElement('a')
    a.innerHTML = i + '<br>'
    a.addEventListener('click', function (e) {  // 只有在点击的时候才能执行
        e.preventDefault()
        alert(i)    // i 为自由变量,从父作用域找,而此时循环早已循环完,i=9
                    // 除了这个 i 以外都是全局作用域
    })
    document.body.appendChild(a)
}

正确的写法

var i
for (i = 0; i < 10; i++) {
    (function (i) {
        var a = document.createElement('a')
        a.innerHTML = i + '<br>'
        a.addEventListener('click', function (e) {
            e.preventDefault()
            alert(i)
        })
        document.body.appendChild(a)
    })(i)
}

4、如何理解作用域

  • 自由变量
  • 作用域链,即自由变量的查找
  • 闭包的两个场景

5、实际开发中闭包的应用

// 闭包实际应用中主要用于封装变量,收敛权限
// 即把变量隐藏起来,不让外面拿到和修改
function isFirstLoad() {
    var _list = []

    return function (id) {
        if (_list.indexOf(id) >= 0) {
            return false
        } else {
            _list.push(id)
            return true
        }
    }
}

// 使用
var firstLoad = isFirstLoad()
firstLoad(10) // true          
firstLoad(10) // false
firstLoad(20) // true

// 在 isFirstLoad 函数外面,根本不可能修改掉 _list 的值

猜你喜欢

转载自blog.csdn.net/Miranda0922/article/details/88791875