Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript深入系列之作用域链 #2

Open
archerU opened this issue May 15, 2018 · 0 comments
Open

JavaScript深入系列之作用域链 #2

archerU opened this issue May 15, 2018 · 0 comments

Comments

@archerU
Copy link
Owner

archerU commented May 15, 2018

函数作用域

任何声明在某个作用域内的变量,都将附属于这个作用域。在 JavaScript 语言中只有函数作用域。

隐藏内部实现

function doSomething(a) {
    b = a + doSomethingElse(a * 2);
    console.log(b * 3);
}   

function doSomethingElse(a) {
    return a - 1;
}
var b;
doSomething(2); 

// 15
function doSomething(a) {
    function doSomethingElse(a) {
        return a - 1;
    }
    var b;
    b = a + doSomethingElse(a * 2);
    console.log(b * 3);
}
doSomething(2); 

// 15

bdoSomethingElse(...) 都无法从外部被访问,而只能被 doSomething(...) 所控制。功能性和最终效果都没有受影响,但是设计上将具体内容私有化了。这便是函数作用域的作用。

立即执行函数表达式(IIFE)

var a = 2;
function foo() {
    var a = 3;
    console.log(a); // 3
}
foo();
console.log(a); //2

虽然隐藏内部实现可以解决一些问题,但是并不理想。首先,必须声明一个具名函数foo(),意味着foo这个名称本身“污染”了所在的作用域。其次,必须显式地通过函数名foo()调用这个函数才能运行其中的代码。

做如下改进:

var a = 2;
(function foo() {
    var a = 3;
    console.log(a); // 3
})();
console.log(a); //2 

函数被包含在一对 ()括号内部,因此成为一个表达式,通过在末尾加上另外一个 ()括号可以立即执行这个函数。

IIFE(Immediately Invoked Function Expression)的另外一个非常普遍的进阶用法是把它们当作函数调用并传递参数进去。用于解决如下问题:

undefined = true; // 给其他代码挖了一个大坑!绝对不要这么做!

(function IIFE(undefined) {
    var a;
    if (a === undefined) {
        console.log("Undefined is safe here!")
    }
})();
// Undefined is safe here!

IIFE还可以用于倒置代码的运行顺序,将需要运行的函数放在第二位,在IIFE执行之后当作参数传递进去。这种模式在 UMD(Universal Module Definition)项目中被广泛使用。

var a = 2;
(function IIFE(def) {
    def(window);
})(function def(global) {
    var a = 3;
    console.log(a); //3 
    console.log(global.a); // 2
});
@archerU archerU changed the title JavaScript深入系列之函数作用域和块作用域 JavaScript深入系列之作用域链 May 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant