JavaScript(简称JS)作为现代Web开发的基石,其灵活性和强大功能为前端开发人员提供了无限可能。理解和掌握JS的作用域机制,包括全局变量、局部变量以及作用域链的概念,对于编写高效、可维护的代码至关重要。本文旨在深入剖析这些概念,通过实例讲解它们的工作原理,帮助初学者和有经验的开发者巩固知识,提升编程技能。
var globalVar='I am global';
function localScope() {
var localVar='I am local';
console.log(localVar); // 输出: I am local
}
localScope();
console.log(globalVar); // 输出: I am global
console.log(localVar); // 报错: localVar is not defined
作用域链是JS引擎在函数执行时创建的一个链表,用于确定变量的可访问性。每个函数都有自己的作用域链,链的最前端是当前函数的局部变量,随后是包含它的函数的作用域,直到全局作用域。
当JS引擎查找一个变量时,它会从当前作用域开始搜索,如果没有找到,则沿着作用域链向上查找,直到找到变量或者到达全局作用域。
function outerFunction() {
var outerVar='Outer Variable';
function innerFunction() {
console.log(outerVar); // 输出: Outer Variable
}
return innerFunction;
}
var innerFunc=outerFunction();
innerFunc();
在构建模块化和可复用的代码时,理解作用域机制是至关重要的。例如,在异步回调或事件处理程序中正确使用闭包,可以避免“变量泄漏”。
function setupEvent() {
var counter=0;
document.getElementById('myButton').addEventListener('click', function() {
counter++;
console.log('Clicks:', counter);
});
}
setupEvent();
过度依赖全局变量可能导致内存泄漏和命名空间污染。使用模块模式或ES6的let和const关键字可以有效避免这些问题。
(function(module) {
module.init=function() {
// 初始化代码
};
})(window.MyModule={});
// 或者使用ES6
const myModule=(()=> {
let privateVar='Private';
return {
getPrivate: ()=> privateVar
};
})();
全局变量、局部变量以及作用域链是JS编程的基础概念,深刻理解它们有助于编写健壮、高效的代码。随着ES6及后续版本的推出,诸如块级作用域、箭头函数等新特性进一步增强了作用域管理的能力,为开发者提供了更多的工具和可能性。未来,随着前端工程化的发展,作用域管理和模块化的最佳实践将变得更加重要,助力开发者构建更加复杂和高性能的应用。
希望本文能帮助你建立对JS作用域机制的深入理解,并在实际项目中加以运用,不断精进你的编程技艺。
带领学生学习JavaScript,都讲到计时事件了。发现如果不讲清楚全局变量,便没办法把停止计时事件讲清楚。
clearInterval() 方法用于停止 setInterval() 方法执行的函数代码。
要使用 clearInterval() 方法, 在创建计时方法时你必须使用全局变量-----------菜鸟教程 JavaScript计时事件
便补充一下:
原本全局变量这个东西,在讲了函数后就应该介绍一下的,只是一直没有较好的应用场景,一直拖着。正好,借着这个机会,现讲现用。
举例1:
<script>function aa(){ var a=10; alert(a);}function bb(){ alert(a);}</script>
在函数bb中就无法访问到a这个变量。
每一个花括号({})好比我们的一间教室,而这个a好比是老师我,现在老师在这间教室上课,隔壁班的学生能听到吗?
不能!
类比一下,所以这种情况为什么是错误的,就能够理解了。
现在,如果老师我跑出去,跑到广播室,大声地宣布:都去到操场,课不上了,请问隔壁班的能听到吗?
<script>
var a=10;
functionaa(){
alert(a);
}
functionbb(){
alert(a);
}
</script>
能听到!
这种情况下,a就是一个全局变量!
这样比方之后,感觉学生大部分能理解了。但是出现了恶意抬杠的(感觉还是没理解透),问我这种情况a的值为什么变了:
<script>
ar a=10;
function aa(){
var a=100;
alert(a);
}
function bb(){
alert(a);
}
</script>
首先,函数aa里面的var 是多余的,有或者没有,一个意思。其次,这种情况好比:老师在广播里通知大家去操场, 回头又跑到你们班来说,不用去了。你们听哪一个?是去还是不去?
不去。
同样的道理,虽然全局变量的初始值是10,但是在函数里重新赋值为100,这个时候已经改变了变量的值。
学生进一步胡搅蛮缠:
<script>
var a=10;
function aa(){
var b=100;
alert(a);
}
function bb(){
alert(a);
}
</script>
那这种情况呢?
好比老师在广播通知你们班接下来两节课到机房上,然后你们班主任跑到教室通知你们下午的卫生要好好打扫,你们听谁的?
班主任的!这一次异口同声。
我倒忘了这茬,反问,接下来两节课都不是她的,你们也听她的啊?
两个变量毫不相干,没有任何影响嘛。
全局变量就讲了这么多,觉得这个比方还算贴切,所以贴了出来……
随后在计时事件中完善代码,终于完成了停止功能,按下不表……
我自己是一名从事了多年开发的web前端老程序员,目前辞职在做自己的web前端私人定制课程,今年年初我花了一个月整理了一份最适合2019年学习的web前端学习干货,各种框架都有整理,送给每一位前端小伙伴,想要获取的可以关注我的头条号并在后台私信我:前端,即可免费获取
作者:yulele
链接:https://www.jianshu.com/p/06e8f6a2fb65
avascript有两种变量:局部变量和全局变量。局部变量是指只能在变量声明的函数内部调用。全局变量时整个代码中都可以调用的变量(window对象的变量)。
局部变量包括函数内声明的变量和函数的形式参数。
全局变量num预处理时,只声明未定义,所以第一次输出undefined;函数fn内部num被声明,所以其为局部变量,预处理时函数fn既声明又定义了,并且函数fn有俩个形式参数n1和n2;函数fn执行时会开辟新的作用域,在新的作用域下,此时的局部变量num预处理时只声明,所以输出undefined;n1被赋值100,n2被赋值200,局部变量num为300,所以第三次输出为300;第四次输出为全局变量num,无法访问函数内的局部变量num,所以结果为10。
函数形成了一个私有的作用域,保护了内部的局部变量不被外界干扰。局部变量和全局变量相互独立、互不影响。
此时函数fn内的num未被声明,按照javascript作用域链的原理,当一个变量在当前作用域下找不到该变量的定义,那么javascript引擎就会沿着作用域链往上找直到在全局作用域里查找,所以函数fn内的num属于全局变量。
关键词:作用域 变量 作用域链 闭包
*请认真填写需求信息,我们会在24小时内与您取得联系。