/*
* 函数作用域
* -调用函数时,创建函数作用域,函数之完毕以后,函数作用域销毁
* 语法:
* function 函数(){
*
* }
* 这就是函数作用域,其实,就是声明一个函数。而函数作用域在没有调用前是关闭状态,
* 也就是说这个函数中任何语句都不会执行
*
*/
//没有调用函数作用域
function fun() {
console.log('是否开启了作用域');
}
/*
* 打印结果是空白,所以在没有调用函数时,函数中的语句不会被执行,而作用域也不会被开启,
*
* - 每调用一次函数就会创建一个新的函数作用域,他们之间是互相独立的
*/
function fun1(a) {
console.log('是否开启了作用域' + a);
}
fun1(1);
fun1(2);
/*
* 在多次调用函数时,除了函数作用域内的语句是一样的、调用也是一样的,以外还有就是它们之间都是独立的。
* 不会出现互相干扰,如果函数作用域中的代码有变化。
* 在多次调用中,会依次执行作用域,只有当第一次执行完毕,才会执行第二次,以此类推
*/
/*
* - 在函数作用域中可以访问到全局作用域的变量(实例-01)
* 在全局作用域中无法访问到函数作用域的变量(实例-02)
*/
//实例-01
var a = 123;
function fun2() {
console.log('a = ' + a);
}
/*
* 打印结果:
* a = 123
*
* 结果显示,fun2()内的console.log()可以访问外部的 a 变量;
*/
fun2();
//实例-02
// console.log('外部1:b = '+b);
// function fun3(){
// var b = 456;
// console.log('b = '+b);
// }
// fun3();
// console.log('外部2:b = '+b);
/*
* 结果显示,‘外部1’和‘外部2’不能访问fun3()内部的 b 变量,
* 并且在‘外部1’和‘外部2’无法访问fun3()内部 b 变量时,控制台会报
* ReferenceError: b is not defined的错误信息,出现这个报错会
* 停止程序运行,不会继续向下执行代码;
*
* 注意:为了下面的例子能顺利执行,这里会把fun3()注释掉
* 有一个可以放访问函数内的变量,那就是不使用 var 来声明(实例-03)
*/
//实例-03
//不能访问函数内变量的 console.log,暂时注释掉
// console.log('外部3:c = ' + c);
function fun4() {
c = 789;
}
fun4();
//可以访问函数内变量的 console.log
console.log('外部4:c = ' + c);
/*
* 打印结果:
* 外部4:c = 789
*
* 结果显示,当函数内的变量没有使用时 var 创建声明变量时,
* 外部4 可以访问函数内的变量。但是,不能在函数创建前去访问,
* 因为外部3 在访问函数时,函数还没有创建内部的变量也没有被创建
*
*
* 如果出现全局变量和局部变量是同一个变量名,会有什么样的结果(实例-04)
*
*/
//实例-04
var d = 90;
function fun5(){
d = 100;
console.log("d = "+d);
}
fun5();
/*
* 打印结果:
* d = 100
*
* 结果显示,当两个变量名相同时,在访问变量时,它会从下往上从内到外去查询这个变量。
* 例如实例-04:console.log要访问变量 d 时,它会从自身向上查找变量,直到查询到这个变量后直接使用,
* 如果在自身的作用域里没有查询到这个变量时,它会向包裹它的作用域一层一层的查询,除了和它平级
* 的作用域以外。只能向比自身作用域大的作用域查询。
*
*
* 相同的变量名,如果访问变量的位置是在调用函数之后,那么结果是什么?函数内的变量使用时 var
* 创建变量,那么结果又是什么?(实例-05)
*/
//实例-05
var e = 90;
function fun6(){
var e = 100;
}
fun6();
//访问变量
console.log("e = "+e);
/*
* 打印结果:
* e = 90
*
* 结果显示,当函数内的 e 变量使用 var 创建时,在调用函数下面访问 e 变量后,会直接访问到函
* 数上面的 e 变量,所以打印的结果就是 e = 90。
* 这是因为使用 var 创建变量后,只能在当前作用域有效,出了当前作用域就不能生效。如果在当前作
* 用域中还有很多个局部作用域时,在局部作用域中可以访问到这个当前作用域
*
*
* 注意:在不使用 var 创建变量时,所写的变量会直接成为 window的属性名,而window是最大的作用域,
* 所以在window内的所有局部作用域中都可以访问到这个变量。
*
* 注意:全局作用域在js中只有一个window的作用域,而在全局作用域中的函数方法和函数可以成为局部作用域,
* 全局作用域中可以套用 N 个局部作用域,而局部作用域中也可以套用 N 个局部作用域
*
* 如果全局作用域想要访问局部作用域中的变量,那么局部作用域中的变量不可以使用 var 来创建声明。
* 无论全局作用域中的变量是否用 var 创建声明,局部作用域可以访问全局作用域中的变量,如果全局作用域中
* 的变量和局部作用域中的变量是同一个名,那么局部作用域访问全局作用域的变量,需要使用window调用。
* (例如:全局变量是 a,在局部作用域中访问时是 window.a )
*/
//局部作用域访问全局作用域的变量
//带 var 被访问
var f = 110;
//不带 var 被访问
//f = 120;
function fun7(){
console.log('我是'+f);
}
fun7();
//全局变量和局部变量是同一个名时,局部作用域想要访问全局变量
var g = 12306;
function fun8(){
var g = 119;
console.log("我到底是"+window.g);
}
fun8();
/*
* fun8()这段代码有两个信息:
* 1.当全局变量和局部变量时同一个名时,局部作用域想要访问全局作用域的变量,需要使用 windo 来调用。
* 2.当全局变量和局部变量时同一个名时,局部作用域想要访问这个变量,他需要从它的位置向上查找,也就
* 是说它会从身边的变量中查找,如果没有它会向上一级作用域中查找,还没有继续上一级的上一级作用域
* 中查找直到查到为止。如果身边有这个变量,它会获取变量值输出完成后会继续进入下一段代码。
*/
/*
* 声明提前
* 在函数作用域中也有声明提前的特性
* 使用 var 关键字声明的变量,会在函数中所有的代码执行之前被声明
*/
function fun9(){
console.log(h);
var h = 111;
}
fun9();
/*
* 打印结果:
* undefined
*
* 打印的结果是undefined。在 h 创建变量之前调用,h 会被提前声明,
* 被提前声明后因为没有给变量赋值,所以在打印的时候,结果会是undefined
*/