searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享

Javascript中的“域”、“预”、“译”

2024-05-28 02:19:38
1
0

在 JavaScript 中,“域”通常指的是作用域。作用域是可访问变量的集合,它决定了变量和函数在代码中的可见性和可访问性。
JavaScript 中的作用域分为全局作用域和局部作用域。全局作用域是指在函数外部定义的变量和函数,它们可以在整个程序中被访问。局部作用域是指在函数内部定义的变量和函数,它们只能在函数内部被访问。
“预”通常指的是预解析。预解析是 JavaScript 引擎在执行代码之前进行的一项操作,它会将变量和函数的声明提升到当前作用域的顶部,以便在代码执行时能够正确地访问这些变量和函数。
“译”可能指的是翻译或解释。在 JavaScript 中,代码需要被翻译成机器能够理解的指令,然后才能被执行。这个过程通常由 JavaScript 引擎来完成。
总的来说,“域”、“预”、“译”都是 JavaScript 中非常重要的概念,理解它们对于编写正确的 JavaScript 代码非常重要。

一、作用域的概念

1、作用域有三种:全局作用域、函数作用域、块级作用域。(模块作用域)

(1)全局作用域:这时最高级别的作用域,在这定义的函数以及变量可以在代码的所有地方被访问。在浏览器的环境中,全局变量实际是window对象的属性。例如:

 
var a = 123 
function foo(){}
//在全局中定义了变量a 函数foo()

(2)函数作用域(局部作用域):在每个函数内部声明的变量(未使用const、let关键字)、function声明的函数,这些对象具有局部作用域,它们只可以在函数内部访问。例如:

 
function foo(){
    var a;
    function add(){}
}

(3)块级作用域:这个作用域是在ES6引入了let和const关键字,避免因var声明的变量的变量提升(接下来会进行解释)现象,导致的让人匪夷所思的行为。这个作用域可以简单的理解为:{} + let/const例如:

if(...){
    let a = 6;
    const b = 6
}
while(...){
    let a = 6;
    const b =6
}
for(){
    let a = 6;
    const b =6;
}
function foo(){
    let a = 6;
    const b =6;
}

注:(1) 以上作用域所指的是全局、函数体、块的域,而词法作用域则是变量声明的地方,注意不是调用的地方。例如:我们的寝室是一个域,则该域的词法作用域就是这一栋寝室楼。

(2)欺骗词法作用域:

eval:可以让原本不属于这里的代码,变得好像天生被定义了在这一样。

 
 function foo(a,str){
    eval(str) //相当于var b = 2;
    console.log(a,b)
}
foo(1,'var b = 2')

whit(){} 当修改对象中不存在的属性时,这个属性会被定义在全局,变为全局变量,造成数据泄露。

 
function foo(obj){
    with(obj){
        a = 2
    }
}
var o2= {
    b :1
}
foo(o2)
console.log(a) //输出a = 2,此时的a为全局变量

2、声明提升的概念与示例

概念:在变量声明和函数声明在代码执行前被提升,或者说移到,其包含的作用域的顶部的过程,发生在JS的编译阶段,导致了变量和函数可以在被声明之前就被访问。

 
 
console.log(a); //变量a只是声明被提示,输出undefined
var a = 6;

//编译器会将代码整理为
//var a;
//console.log(a);
//a = 6;

即使函数foo()在调用之后声明,但由于声明提升,他在执行开始时,就可以使用了,因此能正常输出。

foo()
function foo(){
    console.log('你好')
}
 

二、“预备与编译”--预编译的概念

1、预编译发生在代码被执行之前,是JS引擎对代码的预处理,保证了变量和函数在使用之前已经被正确的设置。

2、全局预编译:

(1)创建全局执行上下文GO(Global Object)。

(2)寻找变量声明,变量名作为GO的属性名,值为undefined。

(3)在全局找函数声明,函数名作为GO的属性名,值为函数体

画图实例:

3、函数中的预编译

(1)创建函数的执行上下文对象AO(Activation Object)。

(2)找到形参和变量声明,将形参和变量声明作为AO的属性名,值为undefined。

(3)将实参和形参统一

(4)在函数体内找到函数声明,将函数名作为AO的属性名,值为函数体。

画图实例:

注: 以上的执行上下文是被放在一个栈内,AO对象被放在变量环境中。在执行上下文中除了变量环境外,还有一个词法环境,用于let const 声明的变量的存储,这保证了它们可以遵守块级作用域的规则,处于临时死区,直到声明被执行才可被访问。这个栈叫做调用栈

画图实例:


0条评论
0 / 1000
w****n
4文章数
0粉丝数
w****n
4 文章 | 0 粉丝