面试必会知识点

82 阅读4分钟

1.上下文

在 JavaScript 中,上下文指的是代码执行时的环境和作用域。JavaScript 中有两种主要的上下文:全局上下文和函数上下文。

  1. 全局上下文:全局上下文是指整个 JavaScript 代码的默认上下文,它是在代码执行时创建的,包含了全局作用域中的变量、函数和其他数据。在浏览器中,全局上下文通常是 window 对象。

  2. 函数上下文:每当一个函数被调用时,都会创建一个新的函数上下文。函数上下文包含了函数内部的局部变量、参数和其他数据。每个函数都有自己的函数上下文,它们在函数调用时被创建,并在函数执行完毕后被销毁。

2.词法作用域

词法作用域(也称为静态作用域)是指在代码编写阶段就确定了变量的作用域,而不是在运行时确定。在词法作用域中,作用域是由代码中函数被声明的位置决定的。

在 JavaScript 中,词法作用域的工作方式是这样的:当在代码中声明一个函数时,它会创建一个作用域,该作用域包含了函数内部声明的变量和函数参数。这个作用域会在函数被定义时确定,而不是在函数被调用时。

举个例子:

var name = "Alice"; // 全局作用域

function greet() {
  var name = "Bob"; // greet 函数作用域
  console.log("Hello, " + name);
}

greet(); // 输出 "Hello, Bob"

在这个例子中,变量 name 在全局作用域和 greet 函数作用域中都有定义。根据词法作用域规则,当在函数内部引用变量 name 时,JavaScript 引擎会先在函数作用域中查找,如果找到了就使用函数作用域中的变量,否则再去全局作用域中查找。

词法作用域使得代码的作用域关系在编写代码时就变得明确,这有助于理解代码的行为和调试错误。与词法作用域相对的是动态作用域,动态作用域是在运行时根据函数调用栈来确定作用域的,而不是根据代码的结构。JavaScript 使用词法作用域,这也是大多数编程语言中常见的作用域规则。

3.this 指向问题

关于this的总结
1,普通的function函数
声明式 --- window
赋值式 --- window 
forEach循环 --- window 
定时器,延时器 --- window 
对象中的函数 --- 对象本身
事件绑定事件处理函数 --- 绑定事件的标签 
2,箭头函数的this指向
父级程序的this指向 如果父级程序有this指向(父级程序也是函数),this指向的就是父级程序的this指向 
如果父级程序没有this指向(数组,对象....),this指向的是window

普通函数的this指向

1,声明式 --- 指向的是window
function fun1(){ 
   console.log(this); 
} 
 fun1(); 
2,匿名函数/赋值式 --- 指向的是window
const fun2 = function(){
   console.log(this); 
} 
fun2();
3,定义在对象中的函数 --- 指向的是对象
const obj = { 
    fun3 : function(){ 
        console.log(this); 
    } 
} 
obj.fun3();
4,绑定的事件处理函数 --- 指向的是绑定事件处理函数的标签
const oDiv = document.querySelector('div'); 
oDiv.addEventListener('click' , function(){
    console.log(this)
})
forEach()中 函数的this指向,就是window
const arr = [1,2,3,4,5,6]; 
arr.forEach(function(){ 
    console.log(this); 
})

怎么改变箭头函数的 this 指向

实际上,箭头函数的 this 指向是静态的,无法通过传统的方式来改变。箭头函数的 this 始终指向词法作用域中的 this 值,而不是动态绑定的。

如果你需要在箭头函数中动态改变 this 指向,你可以使用一个变量来存储所需的 this 值,然后在箭头函数中使用这个变量。例如:

function Person() {
  this.age = 0;
  const self = this; // 存储 this 值

  setInterval(() => {
    self.age++; // 使用存储的 this 值
    console.log(self.age);
  }, 1000);
}

var p = new Person();

在这个例子中,我们使用了一个变量 self 来存储 this 值,然后在箭头函数中使用这个变量来访问想要的属性。

另外一种方法是使用 ES6 的箭头函数绑定的特性,可以在箭头函数外部创建一个普通函数,并在箭头函数内部调用这个普通函数,这样可以改变 this 的指向。例如:

function Person() {
  this.age = 0;

  const incrementAge = () => {
    this.age++;
    console.log(this.age);
  };

  setInterval(incrementAge, 1000);
}

var p = new Person();

在这个例子中,我们定义了一个普通函数 incrementAge,并使用箭头函数将其作为回调传递给 setInterval,这样就可以改变 this 的指向。

希望这些方法能够帮助你在箭头函数中处理 this 指向的问题。

EventLoop: 事件循环

async函数在await之前的代码都是同步执行的,可以理解为await之前的代码属于new Promise时传入的代码,await之后的所有代码都是在Promise.then中的回调