1.25——JS执行机制

85 阅读3分钟

「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战」。

变量提升

当对我们的js代码进行编译的过程中,会创建执行上下文,而在这个过程中会对我们的代码进行变量提升,变量提升通常有3种。

  • var提升 在编译的过程中,对var进行提升,将var声明的变量提到最前面,var xx = undefined;但是我们的赋值操作,仍然是要到代码的实际行数处才进行赋值。
  • 函数提升 直接对函数进行提升,将函数的声明等提到最前面来。
  • let提升 let的创建提升,但是初始化和赋值不会被提升,因此会造成暂时性死区。

调用栈

在我们创建了执行上下文后,将其压入调用栈中。首先是全局上下文,其实是调用执行时的函数上下文,当当前函数执行结束后,需要将函数上下文弹出栈。调用栈有3个部分,执行代码部分,变量环境和词法环境。将我们需要执行的代码放在执行代码部分,变量环境中首先存放的是进行变量提升后的变量。

作用域

全局作用域

特点:①挂载在windo对象用下②只要页面不关闭,就会一直存活下来③不要使用name

函数作用域

特点:①只在函数中能够访问②函数执行结束,变量就会销毁。

块级作用域

特点:①块级作用域中的变量只能在块中起效,在外面无法访问。

每隔一秒打印一个自然数

for (var i = 0; i < 10; i++) {
    (function (j) {
        setTimeout(() => {
            console.log(j);
        }, 1000);
    })(i);
}
for(let i = 0;i < 10;i++){
    setTimeout(()=>{
        console.log(i);
    });
}

闭包

全局中创建的是全局变量,函数作用域中的是局部变量,而函数中的变量当函数执行结束后就会被销毁,但是有的时候我们在函数中声明的变量,并不希望它被销毁而且希望他在外部被操作或者访问,因此就引用了闭包。而由于全局变量能够在全局中被操作和访问,可能会被污染或销毁,而使用闭包的话,我们仅通过作用域链,来访问父级作用域中的变量。但是闭包可能会造成内存的泄露,这一块变量只要页面被关闭,就会一直存在。

  • 模拟块级作用域
  • 埋点计数器
  • 柯里化

柯里化:将一个多参数转化为单参数的方法

  • 参数复用 使用正则表达式,既校验电话号码又校验邮箱

this指向

常见场景

  • 严格模式与非严格模式 严格模式下,在全局调用的函数,其this为undefined,而非严格模式下,指向的是window。
  • 通过对象访问 通过对象访问访问函数的时候,this指向对象。
  • 箭头函数的this指向 箭头函数并不会创建自身的上下文,所以this指向取决于其它的外部函数。
  • new操作 new创建出来的对象,其this指向的是这个对象。
  • 嵌套函数 嵌套函数中的this指向是不继承的。

修改this的方法