「这是我参与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指向是不继承的。