关于JS作用域问题
函数声明与函数表达式
//1.
console.log(a);//Uncaught ReferenceError: a is not defined
//未捕获的ReferenceError: a没有定义。
//2.
console.log(b); // undefined
var b;
// 3.
console.log(c); // undefined
var c = 10;
// 4.
var d = 10;
console.log(d); // 10
在JS代码真正运行之前,浏览器已经做了一些“准备工作”,其中就包括对变量的声明,而不是赋值。变量赋值是在赋值语句执行的时候进行的。第一句报错,a未定义,很正常。
第二句、第三句输出都是undefined,说明浏览器在执行console.log(a)时,已经知道了a声明了,但却不知道a是10(第三句中)。
我们称这种现象为变量的声明提升,所有使用var声明的变量会在当前作用域最开始的部分被声明。
所以console.log( a ); 与console.log( b ); 得到的是undefined而不是not defined。
“函数表达式”和“函数声明”。两者都很常用,但是这两者在浏览器做“准备工作”时,却是两种待遇。
总结 浏览器做了哪些准备工作
变量、函数表达式——变量声明,默认但未赋值赋值;
this——赋值;
函数声明——把函数整个赋值;
作用域
JS中的作用域就是在一定的空间范围内对数据进行读写操作。
JS中一个变量的作用域(scope)是程序中创建这个变量的区域。
变量分为全局变量和局部变量两种。
全局作用域里申明的是全局变量,函数里声明的是局部变量
变量的生命周期:
1.永远存在----全局
程序没关,一直占用内存,少用全局
2.朝生暮死----局部
函数的大括号开头到函数的大括号结尾
所以使用全局变量会存在性能问题,但是有许多地方还是必须使用全局变量
全局变量的作用域是全局性的,在JavaScript代码中,即该全局变量处处都可以调用。
局部变量的作用域是局部性的,如函数体内声明的变量就只能在函数体内部调用,函数的参数也是局部变量,也只在函数体内部能找到。
但是 javascript 没有块级作用域”这个概念。所谓“块”,就是大括号{}中间的语句。
声明变量时,全局变量要在代码前端声明,函数中要在函数体开始就声明好变量。除了这两个地方,其他地方都不要出现变量声明。而且建议用“单var”形式
光知道“javascript没有块级作用域”是完全不够的,你需要知道的是——javascript除了全局作用域之外,只有函数可以创建的作用域。比如在for循环大括号里 声明的计数器 i 是可以在外面捕获到的.
for(var i=0;i<3;i++){
console.log("121")
}
console.log(i) //3
总结
函数是 JavaScript 中最常见的作用域。块作用域指的是变量和函数不仅可以属于所处的函数作用域,也可以属于某个代码块。
本质上,声明在一个函数内部的变量或函数会在所处的作用域中“隐藏”起来,这是有意为之的良好软件的设计原则。
有些人认为块作用域不应该完全作为函数作用域的替代方案。两种功能应该同时存在,开发者可以并且也应该根据需要选择使用哪种作用域,创造可读、可维护的优良代码。