js中作用域与作用域链

js中作用域与作用域链

作用域

*作用域基本概念

作用域一般指变量的作用范围,变量分为全局变量和局部变量,对应的作用域就分别是全局和函数作用域。

示例1

var scope="global";  
function t(){  
    console.log(scope);  
    var scope="local"  
    console.log(scope);  
}  
t(); 
//此处打印结果是undefine local 此处有坑,正常理解 第一个应该打印出来global ,因为scope全局变量,但是js中有个声明提前,这个代码可以解读为示例2,看不懂的出去哭会

示例2

var scope="global";  
function t(){  
    var scope;  
    console.log(scope);  
    scope="local"  
    console.log(scope);  
}  
t();  
//进入函数中,变量声明提前,第一次打印出来的依然是局部变量,只不过没有赋值,所以是undefine,

示例3

var name="global";  
if(true){  
    var name="local";  
    console.log(name)  
}  
console.log(name);  
//正常思路:内部打印local,外部打印global,恭喜你掉坑里了,全部是local,js只有全局与函数作用域 if中的声明覆盖了全局变量都打印出来local

作用域链

简单说就是函数里调用函数1,函数1里调用函数2,那么就有了这么一个作用域链全局作用域==>函数1作用域==>函数2作用域;特点是函数1里面可以直接使用全局作用域的变量,函数2里面可以直接使用全局作用域和函数1作用域的变量
示例1

function t(){  
    var name="tlwy";  
    function s(){  
        var name="slwy";  
        console.log(name);  
    }  
    function ss(){  
        console.log(name);  
    }  
    s();  
    ss();  
}  
t();  
//当执行s时,将创建函数s的执行环境(调用对象),并将该对象置于链表开头,然后将函数t的调用对象链接在之后,最后是全局对象。然后从链表开头寻找变量name,很明显name是"slwy"。但执行ss()时,作用域链是: ss()->t()->window,所以name是”tlwy"

示例2

<head>  
<script type="text/javascript">  
function buttonInit(){  
    for(var i=1;i<4;i++){  
        var b=document.getElementById("button"+i);  
        b.addEventListener("click",function(){ alert("Button"+i);},false);  
    }  
}  
window.onload=buttonInit;  
</script>  
</head>  
<body>  
<button id="button1">Button1</button>  
<button id="button2">Button2</button>  
<button id="button3">Button3</button>  
</body>  
</html>  
//此处错误经常出现 点击事件接触是Button4;这是因为点击事件是在html加载之后才触发的 此时匿名函数没有i需要逐级向上查找,找到循环体此时i已经是4
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容