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

作用域、作用域链、闭包 #32

Open
conan1992 opened this issue Jun 22, 2020 · 0 comments
Open

作用域、作用域链、闭包 #32

conan1992 opened this issue Jun 22, 2020 · 0 comments

Comments

@conan1992
Copy link
Owner

作用域

作用域定义了变量或函数访问其他数据的权限;

作用域类别

作用域分为词法作用域和动态作用域,JavaScript采用的是词法作用域,也就是静态作用域;也就是说作用域在定义函数的时候就生成了;

var value = 1;

function foo() {
    console.log(value);
}

function bar() {
    var value = 2;
    foo();
}

bar();// 打印:1;

作用域链

当访问一个变量时,解释器会首先在当前作用域查找标示符,如果没有找到,就去父作用域找,直到找到该变量的标示符或者不在父作用域中,这样由多个作用域形成的链表就叫做作用域链

闭包

闭包是指有权访问另外一个函数作用域中的变量的函数(红宝石书);
闭包是指那些能够访问自由变量的函数(MDN);

var value = 1;
function foo() {
    var value = 2;
    function bar(){
        console.log(value)
    }
    return bar;
}

var baz = foo();
baz();//输出2

上面这个例子就很好的证明了“静态作用域”;作用域在函数定义的时候就已经决定了,value先访问自身作用域存不存在value,再到父级foo作用域查找,找到value=2,所以输出为2;

闭包表现形式

  • 作为返回值返回
  • 作为参数
var value = 1;
function foo() {
    var value = 2;
    function bar(){
        console.log(value)
    }
    baz( bar );
}

function baz(fn){
    fn();
}
foo()//输出2

闭包应用

<!DOCTYPE html>
<html lang="zh-cmn-Hans">

<head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge, chrome=1">
    <title>waiting</title>
    <style>
        * { padding: 0; margin: 0;}
        body {display: grid;}
        li:nth-child(odd){ background:#eee;}
    </style>
</head>

<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</body>
<script>
    var lis = document.querySelectorAll("li");
    var len = lis.length;
    for(var i=0;i<len;i++){
        lis[i].onclick = function(){
            console.log(i)
        }
    }
</script>
</html>

三次打印都为3;
image

for(var i=0;i<len;i++){
        (function(j){
            lis[j].onclick = function(){
                console.log(j)
            }
        })(i);
    }

或者使用es6的块级作用域

for(let i=0;i<len;i++){
        lis[i].onclick = function(){
            console.log(i)
        }
    }

参考

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant