ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
# 作用域 上下文 首先,有两个概念,LHS RHS。 > 第一种定义了标识符`a`并把数值2赋值给了`a`这种操作有一个专门的术语叫做LHS var a = 2; 第二种,var b = a ,其实对应a ,b 两个操作符是不同的操作,对b来说是一个赋值操作,这是LHS,但是对a来说却是取到a对应的值,这种操作也有一个专门的术语叫做“RHS” var b = a; ## 作用域链 当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级(词法层面上的父级)执行上下文的变量对象中查找,一直找到全局上下文的变量对象,也就是全局对象。这样由多个执行上下文的变量对象构成的链表就叫做作用域链。 ## scope作用域 #### 函数作用域 函数作用域是js中最常见的作用域了,函数作用域给我们最直观的体会就是,内部函数可以调用外部函数中的变量。同时,在函数中给从未声明过得变量赋值,会使该变量变为全局变量。 ~~~ function a (){ b=3 }; a() console.log(b); // 3 ~~~ 就像上面这个例子一样,a中如果我们使用的是var b = 3 那么结果就会是undefined了。 #### 块作用域 使用const let 就会在{}的范围内定义一个作用域,就是所谓的块作用域。需要注意的是try/catch语句中的catch也会创建一个 块作用域。 #### 声明提升 var声明的变量作用域为包围它的函数,而let声明的变量作用域仅在它所在的块中。 函数提升 ~~~ var test = function(){ console.log(1); } //函数表达式 function test(){ console.log(1); }//函数声明会提升 ~~~ 实际上,解析器在向执行环境中加载数据时,对函数声明和函数表达式并非一视同仁。解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问); 应用这一点,我们可以做一些事情: ~~~ // 函数表达式 var a = 2; (function foo() { // <-- 添加这一行 var a = 3; console.log(a); // 3 })(); // <-- 以及这一行 console.log( a ); // 2 ~~~ 比如说上面这段代码,不加var a = 3;时,输出的两个结果都是2.而我们在函数中声明了var a = 3以后,函数内的console返回的就是3 外面的依然是2。 #### 作用域链 关于作用域链,我觉得就是这样 ~~~ function Outer(){ var outer = 'outer'; Inner(); function Inner(){ var inner = 'inner'; console.log(outer,inner) // outer inner } } ~~~ 就是一个查找变量的过程。 ## content上下文 上下文用于指定代码特定部分中this所指向的值 执行期上下文指的是作用域 当一个函数被调用但还未被执行时,会做三个主要工作 1.创建变量 2. 创建作用域链 3. 设置上下文this的值 ~~~ function greet() { name = 'Hammad'; return function() { console.log('Hi ' + name); } } greet(); // 什么都没发生,没有错误 // 从 greet() 中返回的函数保存到 greetLetter 变量中 greetLetter = greet(); // 调用 greetLetter 相当于调用从 greet() 函数中返回的函数 greetLetter(); // logs 'Hi Hammad' 或者greet()() ~~~