10月11日
对执行上下文的理解
什么是执行上下文?
js在执行语句前,经过了一系列的“准备”,为代码执行创造一个“教室”,这就是执行上下文,执行上下文里有一个叫文本环境 用来把js所有代码里面的变量名 函数名 类名等放在文本环境 js在执行代码过程中 就可以在文本环境来查的
执行栈
- 执行栈栈顶的执行上下文称为当前执行上下文
- js代码总是在当前上下文中执行
- 意思是js代码中需要用到的资源 到当前执行上下文上查找
4种情况会创建新的执行上下文
(1)进入全局代码
(2)进入function函数体代码
(3)进入eval函数参数指定的代码
(4)进入module代码
文本环境
var和function声明创建在全局对象 而let const class声明的变量创建在全局scope中 先到全局scope中找变量 查找不到再去全局对象找
名字重复的处理
- let const class声明的名字之间不能重复
- let const class和var function的名字不能重复
- var和function名字重复的 function声明的函数名优先
全局执行上下文
- 创建全局执行上下文 并加入栈顶
- 找到所有的非函数中的var声明 找到所有的顶级函数声明 就是不包括在大括号之内的函数声明 不是函数表达式 找到顶级的let const class声明
- 把收集到的let const class声明做名字重复的处理
- 创建绑定
- 登记并初始化var为undefined
- 顶级函数声明 登记function名字 并初始化为新创建函数对象
- 块级中函数声明 登记名字 初始化为undefined
- 登记let const class。但未初始化
- 执行语句
这个就是为什么会有变量提升
-
作用域是解析变量名的一个变量 就是当前运行的上下文
- 全局作用域就是全局执行上下文
- 函数作用域就是函数运行上下文
-
函数调用时的执行上下文看地方 函数在哪里创建 就保存哪里的运行上下文
- 函数的作用域是在函数创建的时候决定的 而不是调用的时候决定的
函数运行上下文
- 创建执行上下文 并加入栈顶
- 找到所有的非函数中的var声明 找到所有的顶级函数声明 找到顶级的let const class声明
- var function和let const class名字不重复 let const class之间名字不重复
- 创建绑定
- 登记并初始化var为undefined
- 顶级函数声明 登记function名字 并初始化为新创建函数对象
- 登记let const class。但未初始化、
- 执行语句
词法作用域
- 并非根据调用嵌套形成作用域 而是根据函数创建嵌套形成作用域链 也就是函数的书写位置形成作用域链 因此称为词法作用域
块级作用域
- 创建新的记录环境 链接在原来的记录之前
- 所有的顶级函数声明 找到let const 声明
- function和let const名字不重复 let const之间名字不重复
- 创建绑定
- 登记function名字 并初始化为新创建函数对象
- 登记let const ,但未初始化、
- 执行语句
10月12日
1 对this对象的理解
this 是执行上下文中的一个属性,它指向最后一次调用这个方法的对象。在实际开发中,this 的指向可以通过四种调用模式来判断。
- 第一种是函数调用模式,当一个函数不是一个对象的属性时,直接作为函数来调用时,this 指向全局对象。
- 第二种是方法调用模式,如果一个函数作为一个对象的方法来调用时,this 指向这个对象。
- 第三种是构造器调用模式,如果一个函数用 new 调用时,函数执行前会新创建一个对象,this 指向这个新创建的对象。
- 第四种是 apply 、 call 和 bind 调用模式,
这四种方式,使用构造器调用模式的优先级最高,然后是 apply、call 和 bind 调用模式,然后是方法调用模式,然后是函数调用模式。
2.call() 和 apply() 的区别?
它们的作用一模一样,区别仅在于传入参数的形式的不同。
- apply 接受两个参数,第一个参数指定了函数体内 this 对象的指向,第二个参数为一个带下标的集合,这个集合可以为数组,也可以为类数组,apply 方法把这个集合中的元素作为参数传递给被调用的函数。
- call 传入的参数数量不固定,跟 apply 相同的是,第一个参数也是代表函数体内的 this 指向,从第二个参数开始往后,每个参数被依次传入函数。
3 this 关键字含义是什么?
this总是返回一个对象,this就是属性或方法“当前”所在对象。由于对象的属性可以赋值给另一个对象,所以属性所在的当前对象是可变的,即this指向是可变的。
4 为什么需要this指向属性和方法“当前”所在对象?
在函数体内部获得当前函数的运行环境(context),this出现了,它的设计目的就是在函数体内部,指代函数当前的运行环境。
5 cookie、session、localStorage、sessionStorage区别
(1). 区分cookie、session与localStorage、sessionStorage
cookie和session都是参与服务器通信的,而localStorage和sessionStorage不参与服务器通信。
(2) 区分cookie与session
cookie的作用是在客户端保持状态,比如登录状态。它被存储在本地硬盘或内存里,并且在发送http请求的时候会被放进请求头中参与通信。每个cookie最大为4k,每个域名可以拥有的cookie数量在不同浏览器中是不同的,但都多于20个,早期的20个限制已经不存在了。
session的作用是在服务器端保持状态,它被存储在服务器上。session被创建的时候会生成一个sessionid,它被存储在cookie中用来访问session。由于关闭浏览器不会导致session被删,迫使服务器为session设置了失效时间。
(3) 区分localStorage与sessionStorage
localStorage和sessionStorage都属于webStorage本地存储,不参与服务器通信。而且它们都属于window对象,最大存储都在5M左右。
区别在于localStorage是永久存储。而sessionStorage的存储时间是当前会话,关闭页面或浏览器就会被清除。localStorage可以用来长期保存登陆信息。而sessionStorage可以用来一次性保存登陆信息,而且不同浏览器不共享。
(4) 为什么要用sessionStorage,用全局js对象不行吗?
一旦刷新页面全局js对象就不在了,而sessionStorage还在。
10月13日
1 DOM事件模型和事件流?
DOM事件模型包括事件捕获(自上而下触发)与事件冒泡(自下而上触发,ie用的就是冒泡)机制。基于事件冒泡机制可以完成事件代理。
DOM事件流包括三个阶段事件捕获阶段、处于目标阶段、事件冒泡阶段
2 require/import之间的区别
(1)require是CommonJS语法,import是ES6语法;
(2)require只在后端服务器支持,import在高版本浏览器及Node中都可以支持;
(3)require引入的是原始导出值的复制,import则是导出值的引用;
(4)require时运行时动态加载,import是静态编译;
(5)require调用时默认不是严格模式,import则默认调用严格模式.
3. 什么是AJAX?如何实现?
ajax是一种能够实现局部网页刷新的技术,可以使网页异步刷新。
ajax的实现主要包括四个步骤:
(1)创建核心对象XMLhttpRequest;
(2)利用open方法打开与服务器的连接;
(3)利用send方法发送请求;("POST"请求时,还需额外设置请求头)
(4)监听服务器响应,接收返回值。
4. 回流和重绘
-
重绘:重新绘制 比如:字体颜色和背景色发生变化
-
回流 :比如元素位置或大小发生变化
例子 有一个重新装修的活 想改墙的颜色 这就叫重绘 又想改一下房子的结构 在改墙的颜色 这就叫回流 也就是说 回流之后一定会经过重绘的过程 -
性能方面 回流的性能开销一定大于重绘
很明显 同样是返工 重绘相当于一面墙重新刷漆 而回流相当于从新砌墙在刷漆 显然性能开销更大 -
性能优化
- 能重绘尽量不要回流
- 能少回流就少
- 能小区域不大区域回流
- 避免无效回流
- 利用GPU资源
5. 防抖和节流
- 防抖
频繁去触发一个事件,但是只触发最后一次。以最后一次为准
使用场景
- 电脑息屏时间,每动一次电脑又重新计算时间
- input框变化频繁触发事件可加防抖
- 频繁点击按钮提交表单可加防抖
- 节流
频繁去触发一个事件,但是只能每隔一段时间触发一次
使用场景
- 滚动频繁请求列表可加节流
- 游戏里长按鼠标,但是动作都是每隔一段时间做一次
6.什么是高阶函数
如果一个函数接受另一个函数作为参数,那么我们称该函数为高阶函数 ,像数组的map、reduce、filter这些都是高阶函数
10月14日
1 什么是函数柯里化?
它将一个接收多参数的函数转化为接 收部分参数的函数。柯里化后的函数只传 递部分参数来调用,并返回一个新的函数 去处理剩余的参数,是逐步传参的过程
- 例子
function add(a){
return function(b,c){
return a+b+c
}
}
const a =add(1)
console.log(a(2,2));
console.log(a(2,2));
2 AMD 和 CMD 的区别?
| 模块化 | 代表应用 | 特点 |
|---|---|---|
| AMD | require.js | 1、AMD的api默认一个当多个用 2、依赖前置,异步执行 |
| CMD | sea.js | 1、CMD的api严格区分,推崇职责单一 2、依赖就近,按需加载,同步执行 |
3 JS中如何将页面重定向到另一个页面?
-
1、使用 location.href:window.location.href =“www.onlineinterviewquestions.com/”
-
2、使用 location.replace: window.location.replace(" www.onlineinterviewquestions.com/;");
4 函数 f2 执行后为什么返回了 undefined?
let f1 = () => '前端自习课';
f1(); // -> '前端自习课'
let f2 = () => {};
f2(); // -> undefined
这本质原因是因为箭头函数返回的 {} 是箭头函数语法的一部分
5、绑定点击事件有几种方式?
三种
xxx.onclick = function (){}<xxx onclick=""></xxx>xxx.addEventListener('click', function(){}, false)
6、addEventListener的第三个参数是干嘛的?
第三个变量传一个布尔值,需不需要阻止冒泡,默认是false,不阻止冒泡
数组的常用方法有哪些?
| 方法 | 作用 | 是否影响原数组 |
|---|---|---|
| push | 在数组后添加元素,返回数组长度 | ✅ |
| pop | 删除数组最后一项,返回被删除项 | ✅ |
| shift | 删除数组第一项,并返回被删除项 | ✅ |
| unshift | 数组开头添加元素,返回新数组长度 | ✅ |
| reserve | 反转一个数组,返回修改后的数组 | ✅ |
| sort | 排序一个数组,返回修改后的数组 | ✅ |
| splice | 截取数组,返回被截取的区间 | ✅ |
| join | 将一个数组所有元素连接成字符串并返回这个字符串 | ❌ |
| concat | arr1.concat(arr2, arr3) 连接数组 | ❌ |
| join | arr.join(x)将arr数组元素连接成字符串并返回这个字符串 | ❌ |
| map | 操作数组每一项并返回一个新数组 | ❌ |
| forEach | 遍历数组,没有返回值 | ❌ |
| filter | 对数组所有项进行判断,返回符合规则的新数组 | ❌ |
| some | 数组有符合规则的一项就返回true | ❌ |
| reduce | 接收上一个return和数组的下一项 | ❌ |
| slice | 截取数组,返回被截取的区间 | ❌ |
7 函数声明和函数表达式的区别?
- 函数声明:享受函数提升
- 函数表达式:归类于变量声明,享受变量提升
- 函数提升优先级 > 变量提升优先级
console.log(fun) // fun () {}
// 函数表达式
var fun = function(name) {}
// 函数声明
function fun () {}
console.log(fun) // fun (name) {}
8.说一下图片的懒加载和预加载
什么是图片懒加载
- 图片懒加载又叫图片延迟(按需)加载
- 在需要的时候加载图片
- 更好的加载页面的首屏内容 无需考虑整个页面
什么是图片预加载
- 提前加载将来可能会用到的图片