JS学习随笔
-
必考:ES 6 语法知道哪些,分别怎么用?
举例法
let :语句声明一个块级作用域的本地变量
const:常量是块级作用域,很像使用let语句定义的变量。常量的值不能通过重新赋值来改
变,并且不能重新声明。
箭头函数 Promise
import :导入由另一个模块导出的绑定
export :从模块中导出函数、对象或原始值
默认参数:function multiply(a, b = 1) { return a * b; }
展开操作符:function sum(x, y, z) { return x + y + z;} const numbers = [1, 2, 3]; console.log(sum(...numbers));
-
必考 Promise、Promise.all、Promise.race 分别怎么用?
-
背代码 Promise 用法
function fn(){ return new Promise((resolve, reject)=>{ 成功时调用 resolve(数据) 失败时调用 reject(错误) }) } fn().then(success, fail).then(success2, fail2)
-
背代码 Promise.all 用法
Promise.all([promise1, promise2]).then(success1, fail1)
promise1和promise2都成功才会调用success1
-
背代码 Promise.race 用法
Promise.race([promise1, promise2]).then(success1, fail1)
promise1和promise2只要有一个成功就会调用success1
-
-
必考:手写函数防抖和函数节流
-
背代码
// 节流(一段时间执行一次之后,就不执行第二次) function throttle(fn, delay){ let canUse = true return function(){ if(canUse){ fn.apply(this, arguments) canUse = false setTimeout(()=>canUse = true, delay) } } } const throttled = throttle(()=>console.log('hi')) throttled() throttled()
注意,有些地方认为节流函数不是立刻执行的,而是在冷却时间末尾执行的(相当于施法有吟唱时间),那样说也是对的。
-
背代码
// 防抖(一段时间会等,然后带着一起做了) function debounce(fn, delay){ let timerId = null return function(){ const context = this if(timerId){window.clearTimeout(timerId)} timerId = setTimeout(()=>{ fn.apply(context, arguments) timerId = null },delay) } } const debounced = debounce(()=>console.log('hi')) debounced() debounced()
-
-
必考:手写AJAX
-
背代码,完整版
var request = new XMLHttpRequest() request.open('GET', '/a/b/c?name=ff', true); request.onreadystatechange = function () { if(request.readyState === 4 && request.status === 200) { console.log(request.responseText); }}; request.send();
-
背代码,简化版
var request = new XMLHttpRequest() request.open('GET', '/a/b/c?name=ff', true) request.onload = ()=> console.log(request.responseText) request.send()
-
-
必考:这段代码里的 this 是什么?
- 背代码
- fn()
this => window/global - obj.fn()
this => obj - fn.call(xx)
this => xx - fn.apply(xx)
this => xx - fn.bind(xx)
this => xx - new Fn()
this => 新的对象 - fn = ()=> {}
this => 外面的 this
- fn()
- 看调用
《this 的值到底是什么?一次说清楚》
- 背代码
-
必考:闭包/立即执行函数是什么?
- 闭包 https://zhuanlan.zhihu.com/p/22486908 一个函数能访问这个函数作用域外的变量,那么这个函数和这个变量就叫闭包。
- 立即执行函数 https://zhuanlan.zhihu.com/p/22465092 立即执行函数,声明一个函数,然后立马执行。
!function(){alert('我是匿名函数')}()
,他的作用是创建一个独立的作用域。
var liList = ul.getElementsByTagName('li')
for(var i=0; i<6; i++){
liList[i].onclick = function(){
alert(i) // 为什么 alert 出来的总是 6,而不是 0、1、2、3、4、5
}
}
/* 因为 i 是贯穿整个作用域的,而不是给每个 li 分配了一个 i */
var liList = ul.getElementsByTagName('li')
for(var i=0; i<6; i++){
!function(ii){
liList[ii].onclick = function(){
alert(ii) // 0、1、2、3、4、5
}
}(i)
}
- 必考:什么是 JSONP,什么是 CORS,什么是跨域?
- JSONP是通过 script 标签加载数据的方式去获取数据当做 JS 代码来执行,提前在页面上声明一个函数,函数名通过接口传参的方式传给后台,后台解析到函数名后在原始数据上「包裹」这个函数名,发送给前端。换句话说,JSONP 需要对应接口的后端的配合才能实现。JSONP不能post,JSONP是通过动态创建script实现的,动态创建script只能用GET
比如:请求方:frank.com 的前端程序员(浏览器)
响应方:jack.com 的后端程序员(服务器)
请求方创建 script,src 指向响应方,同时传一个查询参数 ?callbackName=yyy
响应方根据查询参数callbackName,构造形如
yyy.call(undefined, '你要的数据')
yyy('你要的数据')
这样的响应
浏览器接收到响应,就会执行 yyy.call(undefined, '你要的数据')
那么请求方就知道了他要的数据 - CORS 跨域资源共享,它使用额外的 HTTP头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。
response.setHeader('Access-Control-Allow-Origin','需要共享的URL')
- 同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互,所以才需要跨域。
- JSONP是通过 script 标签加载数据的方式去获取数据当做 JS 代码来执行,提前在页面上声明一个函数,函数名通过接口传参的方式传给后台,后台解析到函数名后在原始数据上「包裹」这个函数名,发送给前端。换句话说,JSONP 需要对应接口的后端的配合才能实现。JSONP不能post,JSONP是通过动态创建script实现的,动态创建script只能用GET
- 常考:async/await 怎么用,如何捕获异常?
- 常考:如何实现深拷贝?
背代码,要点:- 递归
- 判断类型
- 检查环(也叫循环引用)
- 需要忽略原型
- 常考:如何用正则实现 trim()?
背代码
```
String.prototype.trim = function(){
return this.replace(/^\s+|\s+$/g, '')
}
//或者
function trim(string){
return string.replace(/^\s+|\s+$/g, '')
}
```
-
常考:不用 class 如何实现继承?用 class 又如何实现?
-
背代码,不用 class 这样实现
function Animal(color){ this.color = color } Animal.prototype.move = function(){} // 动物可以动 function Dog(color, name){ Animal.call(this, color) // 或者 Animal.apply(this, arguments) this.name = name } // 下面三行实现 Dog.prototype.__proto__ = Animal.prototype function temp(){} temp.prototye = Animal.prototype Dog.prototype = new temp() Dog.prototype.constuctor = Dog // 这行看不懂就算了,面试官也不问 Dog.prototype.say = function(){ console.log('汪')} var dog = new Dog('黄色','阿黄')
-
背代码,用 class 就简单了
class Animal{ constructor(color){ this.color = color } move(){} } class Dog extends Animal{ constructor(color, name){ super(color) this.name = name } say(){} }
-
常考:如何实现数组去重?
-
计数排序变形,背代码
-
使用 Set(面试已经禁止这种了,因为太简单)
-
使用 WeakMap
-
放弃:== 相关题目(反着答)
不要背,记不住,太复杂且没有规律 -
送命题:手写一个 Promise
提前写一遍,放在博客里,参考 https://juejin.im/post/5aafe3edf265da238f125c0a