关于前端:作用域和闭包面试回顾

闭包

  • 作用域利用的非凡场景有两种体现
  • 函数作为参数被传递
  • 函数作为返回值被返回
//函数作为返回值
function create() {
    const a = 100
    return function () {
        console.log(a)
    }
}

const fn = create()
const a = 200
fn() // 100

// 函数作为参数被传递
function print(fn) {
    const a = 200
    fn()
}
const a = 100
function fn() {
    console.log(a)
}
print(fn) // 100

//  所有的自在变量的查找,是在函数定义的中央,向下级作用域查找
//     不是在执行的中央!!!

this

  • 作为一般函数
  • 应用call,apply,bind
  • 作为对象办法被调用
  • 在class办法中调用
  • 箭头函数(返回下级作用域的this)
this的取值是在函数执行的时候确定的,不是在定义的时候确定的

手写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)
    }
}

function fn1(a, b, c) {
    console.log('this', this)
    console.log(a, b, c)
    return 'this is fn1'
}

const fn2 = fn1.bind1({x: 100}, 10, 20, 30)
const res = fn2()
console.log(res)

理论开发中闭包的利用

// 闭包暗藏数据,只提供 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') )

创立十个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)
}

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理