97-js-13-作用域和闭包

作用域

作用域:变量的合法使用范围
全局作用域:在全局可以使用
函数作用域:只能在函数块中使用
块级作用域(ES6新增):let,const定义的变量有块级作用域{}内部使用

自由变量

1.一个变量在当前作用域没有定义,但是被使用了
2.向上级作用域,一层一层依次寻找,直到找到为止
3.如果到全局作用域都没找到,则报错:xxx is not defined

闭包

闭包:作用域应用的一种特殊情况
表现:

函数作为参数被传递

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

函数作为返回值被返回

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

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

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

闭包的作用

隐藏私有变量

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


块级作用域

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

推荐阅读

http://bonsaiden.github.io/JavaScript-Garden/zh/#function.scopes

http://bonsaiden.github.io/JavaScript-Garden/zh/#function.closures