js面试题——作用域和闭包

作用域和自由变量

作用域

  • 作用域:变量的合法使用范围

  • 全局作用域:在全局可以使用

  • 函数作用域:只能在函数块中使用

  • 块级作用域(ES6新增):let,const定义的变量有块级作用域{}内部使用

自由变量:

  1. 一个变量在当前作用域没有定义,但是被使用了

  2. 向上级作用域,一层一层一次寻找,知到找到为止

  3. 如果到全局作用域都没找到,则报错:xxx is not defined

闭包

闭包:所有自由变量的查找,是在函数定义的地方,向上级作用域查找

不是在函数执行的地方查找。

闭包是作用域应用的特殊情况,有两种表现:

  • 函数作为参数被传递

  • 函数作为返回值被返回

// 函数作为返回值
function create(){
    let a = 100
    return function(){
        console.log(a)
    }
}
let fn = create()
let a = 200
fn()
// 函数作为函数
function print(fn){
    let a = 200
    fn()
}
let a = 100
function fn(){
    console.log(a)
}
print(fn)

this

this 在各个场景中取什么样的值,是在函数执行的时候确定的,不是在函数定义时确定的。

this 的应用场景

  • 作为普通函数被调用

  • 使用 call apply bind 调用

  • 作为对象方法被调用

  • 在 class 方法中调用

  • 箭头函数

1.this的不同应用场景,如何取值?

  • 当作普通函数被调用,返回window

  • 使用call、apply、bind,传入什么返回什么

  • 作为对象方法调用,返回对象本身

  • 在class的方法中调用,返回本身

  • 在箭头函数中,取上级作用域this的值

2.手写bind函数

// 模拟 bind
Function.prototype.bind1 = function () {
    // 将参数拆解为数组
    const args = Array.prototype.slice.call(arguments)

    // 获取 this(数组第一项)
    const t = args.shift()

    // fn1.bind(...) 中的 fn1
    const self = this

    // 返回一个函数
    return function () {
        return self.apply(t, args)
    }
}

3.实际开发中闭包的应用场景,举例说明

// 闭包隐藏数据,只提供 API
function createCache() {
    const data = {} // 闭包中的数据,被隐藏,不被外界访问
    return {
        set: function (key, val) {
            data[key] = val
        },
        get: function (key) {
            return data[key]
        }
    }
}

const c = createCache()
c.set('a', 100)
console.log( c.get('a') )

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

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

 

posted @ 2021-01-15 14:42  倦梦还  阅读(239)  评论(0编辑  收藏  举报