关于JavaScript全局作用域和函数作用域的拙见

在类c的语言中,用{}引起来的部分称为块级作用域,而在JS中没有块级作用域

作用域:一个变量作用的范围;中Js中一共有两种作用: 

  • 全局作用域

- 直接编写在script标签中的JS代码,都在全局作用域中

-全局作用域在页面打开时创建,在页面关闭时销毁

-在全局作用域中有一个全局对象window,它代表的是一个浏览器窗口,它由浏览器创建,我们可以直接使用

-在全局作用域中,创建的变量都会作为window对象的属性保存,创建的函数都会作为window对象的方法保存

  • 变量的声明提升

-使用var关键字声明的变量,会在所有代码执行之前声明(但是不会赋值

-但是如果声明变量不适用var关键字,则变量不会声明提前

  • 函数的声明提前

-使用函数声明形式创建的函数function 函数(){}

它会在所有代码执行之前就被创建,所以我们可以在函数声明前来调用

-使用函数表达式创建的函数,不会被声明提前,所有不能提前调用

全局作用域的变量都是全局变量,可以在页面的任意部分都可以访问到

  • 函数作用域

-调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁,

-每调用一次函数就会创建一个新的函数作用域,她们之间是相会独立的

-函数作用域中可以访问到全局作用域的变量,在全局作用域中,不能访问函数作用域的的变量

-当在函数作用域中操作一个变量时,它会先在自身作用域中寻找,若有就直接使用,若没有就向上一级作用域中寻找,直到全局作用域中

-在函数作用域中想访问全局中的变量,则可以用window

-在函数作用域中,使用var关键字声明的变量,会在函数中所有代码执行之前被声明

-在函数中,不使用var声明的变量都会成为全局变量

-定义形參,相当于函数作用域中声明了变量

var a=10;
function fun(){
alert(a);
var a=2;
}    
fun();//undifined,变量提升,但没赋值
alert(a);//10,a修改的局部的a

var a=10;
function fun(){
alert(a);
a=2;
}    
fun();//10
alert(a);//2

var a=10; function fun(a){ alert(a); a=2; } fun();//undifined alert(a);//10
var a=10;
function fun(a){
alert(a);
a=2;
}    
fun(123);//123
alert(a);//10


function fun(){
a=10;
}
fun()

alert(a);//a=10,变成了全局变量

 作用域链:

函数对象和其他对象一样,拥有可以通过代码访问的属性和一系列供JS引擎访问的内部属性,其中一个内部属性是[[Scope]],该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。

当一个函数创建后,它保存着一个作用域链,并且这个作用域链会被创建此函数的作用域中可访问的数据对象填充。

   function func(){
        var num=1;
        alert(num)
    }
    func();

在函数func创建时,它的作用域链会填入一个全局对象,该全局对象包含了所有全局变量,

执行此函数会创建一个称为“运行期上下文”的内部对象,运行期上下文定义了函数执行的环境。每个运行期上下文都有自己的作用域链,用于标识符解析,当运行期上下文被创建时,而它的作用域链初始化为当前运行的函数的[[Scope]]所包含的对象

这些值按照他们出现在函数中的顺序被复制到运行期上下文的作用域链中。它们共同组成了一个新的对象,叫“活动对象”,该对象包含了函数的所有局部变量,命名参数,参数集合以及this,然后此对象会被推入作用域链的前端。当运行期上下文被销毁,活动对象也随之被销毁,新的作用域如下:

 

原文地址:https://www.cnblogs.com/yuan233/p/6940661.html