ES6(2015) 学习笔记

326 阅读2分钟

作用域

常见的作用域主要分为几个类型:全局作用域、函数作用域、块状作用域、动态作用域。

对象 类型
global/window 全局作用域
function 函数作用域(局部作用域)
{} 块状作用域
this 动态作用域

如果一个 变量 或者其他表达式不在 “当前的作用域”,那么JavaScript机制会继续沿着作用域链上查找直到全局作用域(global或浏览器中的window)如果找不到将不可被使用。 作用域也可以根据代码层次分层,以便子作用域可以访问父作用域,通常是指沿着链式的作用域链查找,而不能从父作用域引用子作用域中的变量和引用

全局作用域

定义全局变量与window的属性

var a = 123 // 全部变量
b = 1234 // => 不加var的定义,会被挂载在window上 

// 验证 a 和 b 是否为变量,通过 delete,变量不能被delete,属性可以被delete
delete a // => false 删除失败
delete b // => true  删除成功

在函数中定义window的属性

function test () {
    c = 12345
}
test() // 一定要执行一次,执行挂载

console.log(c) // => 12345

函数作用域(局部作用域)

function test () {
    var a = 3
    return a + 4
}
console.log(test())

作用域链(闭包)

function test () {
    var a = 3
    function test2 () {
        var b = 4
        return a + b
    }
    return test2
}

块状作用域

在ES6之前没用块状作用域,只有全局作用域及函数作用域

没有块状作用域的情况(使用var定义变量)

function test () {
    var a = 3
    if (a === 3) {
        var b = 4 // 没有块状作用域时这个定义跟a是同级的,等同于都在一个函数作用域里
        console.log(true)
    } esle {
        console.log(false)
    }
    return a + b
}
test() // => 7

在JS中有变量提升的概念,在使用var创建变量时会被升级

function test() {
    var a = 3
    if (a === 3) {
        var b = 4
        console.log(true)
    }
}
// 经过编译升级后,上面的函数等价于下面的函数,最终浏览器执行时也会变成下面的样子执行
function test() {
    var a = 3
    var b
    if (a === 3) {
        b = 4
        console.log(true)
    }
}

使用块状作用域(使用 let 和 const 定义变量)

function test () {
    var a = 3
    if (a === 3) {
        let b = 4 // 块状作用域变量,不会被提升
        console.log(b)
    } esle {
        console.log(false)
    }
    return a + b // 会报错,因为找不到b,b已经变为块状作用域的变量
}
test() // => 报错

动态作用域

a = 3
function test () {
    console.log(this.a) // 此时的 this 为 window
}
test() // => 3
a = 3
function test () {
    console.log(this.a) // 此时的 this 为 window
}
test() // => 100
test.bind({a : 100})() // 动态绑定,动态作用域