算法
https://juejin.cn/post/6844903793923096590#heading-5
1. 什么是Promise
promise是js提供的一种解决异步编程的新的方案。从语法上Promise是一个构造函数,用来封装异步操作并获取结果的一个类。
Promise内部只有三种状态,Pending,reject,resolve,而且状态是不可逆的。
Promise可以解决异步回调地狱的问题。主要的实现方式是通过返回一个新的promise,实现链式调用。然后通过状态管理实现回调函数的调用时机。
Promise属于一种微任务,在事件循环中,等同步执行完成之后,会从微任务队列中取出微任务调用,当当前循环的微任务执行完之后,会从宏任务队列中函数调用。直至下一轮事件循环开始。
Promise的错误处理
Error:所有错误的父类型
ReferenceError:引用变量不存在
TypeError:数据类型不正确
SyntaxError: 语法错误
RangeError:数据值不在其所允许的范围内
2. axios取消请求的原理
axios有个cancelToken,用来取消请求。其原理就是cancelToken里面有一个promise,然后被reslove的权利交给cancelToken,也就是说cancelToken类可以拿到promise的resolve。在调用source.cancel的时候,调用promise的reslove。然后当这个promise状态发生变化的时候,就调用request.abort取消请求
3. 怎么截取url的参数
window.location.search的值,该值包含?后面的
arr = window.location.search.substring(1).split(“&”)
arr.forEach, item.split(“=”)
4. es6新增特性
let/const
首先let const都有块级作用于,会形成一个暂时性死区。在未定义就去取值的时候会报错。const主要是用来定义常量的,当以了之后不能修改。Let是可以进行修改的。
async/await
async、await是结合generator以及promise实现的一个语法糖。利用iterator的next方法实现的。
实现原理是promise包裹generator,然后循环递归调用next,直到为done,就resolve最终结果。
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
}
catch (error) {
reject(error); return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _asyncToGenerator(fn) {
return function () {
var self = this, args = arguments;
return new Promise(function (resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
function p() {
return _p.apply(this, arguments);
}
function _p() {
_p = _asyncToGenerator(function* () {
yield console.log('xx');
});
return _p.apply(this, arguments);
}
p();
Symbol基础数据类型
array添加了map,filter,every,some,reduce
Set/Map
set存放有序序列,类似于数组,可以用来做数组去重。weakSet使用的弱引用,在垃圾回收的时候,其实还存在引用,该对象也可以被回收
Map存放的是键值对,weakMap同理weakSet
Iterator,Generator
Proxy/Reflect
Class类,通过extends实现继承
es5组合继承,组合寄生式继承
5. 什么是闭包
闭包的含义就是函数外部可以访问函数内部的属性
一般具体的表现形式就是一个function里面返回一个function,或者把function当做一个形参传给一个function
主要的目的是可以实现私有属性
6. 事件循环
7. 观察者模式和发布订阅者模式
8. 深入理解继承
9. 深浅拷贝
判断数据类型:
typeof 可以判断除null以外的基础类型和function
instanceof可以判断复杂类型,不能判断基础类型
const myInstanceOf = (left, right) => {
if (typeof left !== "object" || left === null) {
return false;
}
let prop = Object.getPrototypeOf(left);
while (true) {
if (proto === null) {
return false;
}
if (prop = right.prototype) {
return true;
}
prop = this.getPrototypeOf(prop);
}
};
Object.prototype.toString.call();
- 浅拷贝
- Object.assign
- 扩展运算符
- Array.prototype.slice()
- Array.prototype.concat()
深拷贝
- JSON.parse(JSON.stringify(object))(忽略undefined,忽略symbol,不能处理正则,new Date,不能处理循环引用对象)
- 自己写的deepClone
- 如果是对象,并且不是null的时候,需要进行深度遍历,其他情况下直接返回value
- 循环引用问题,通过weakMap设置缓存,如果在缓存里面就直接取出,如果不在,就深度循环
- 对于symbol可以通过Reflect.ownKeys取到包含symbol的key值 ```html /**
- 对基础类型做一个最基本的一个拷贝
- 对引用类型开辟一个新的存储,并且拷贝一层对象属性
- @param {} target / const shadowClone = (target) => { if (typeof target !== “object” || target === null) { return target; }
const cloneTarget = Array.isArray(target) ? [] : {}; for (let prop in target) { if (target.hasOwnProperty(prop)) {
cloneTarget[prop] = target[prop];
} } return cloneTarget; };
```html
/**
* 1. 针对能够遍历对象的不可枚举属性以及 Symbol 类型,我们可以使用 Reflect.ownKeys 方法
* 2. 当参数为 Date、RegExp 类型,则直接生成一个新的实例返回
* 3. 利用 Object 的 getOwnPropertyDescriptors 方法可以获得对象的所有属性,以及对应的特性,顺便结合 Object 的 create 方法创建一个新对象,并继承传入原对象的原型链
* 4. 利用 WeakMap 类型作为 Hash 表,因为 WeakMap 是弱引用类型,可以有效防止内存泄漏;如果存在循环,则引用直接返回 WeakMap 存储的值
* @param {*} target
*/
const deepClone = (target,hash = new WeakMap()) => {
//1.普通类型
if (typeof target !== "object" || target === null) {
return target;
}
// 2.Date和 RegExp
if (target instanceof Date) {
return new Date(target);
}
if (target instanceof RegExp) {
return new RegExp(target);
}
//4. 如果循环引用就返回obj,这里使用weakMap是为了防止内存泄漏
if (hash.has(obj)) {
return hash.get(obj);
}
//5. 运用Object.create创建一个新的obj
let cloneObj = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
//3. Reflect.ownKeys获取不可枚举和Symbol类型
for (let key of Reflect.ownKeys(obj)) {
const item = obj[key];
if (typeof item === 'object' && item !== null) {
cloneObj[key] = deepClone(item, hash);
} else {
cloneObj[key] = obj[key];
}
}
return cloneObj;
};
10.TS与JS
TS是静态类型检查,JS是动态类型
TS需要编译,JS不需要编译,浏览器直接识别
TS有基础类型,String,Number,Object,Boolean,Null,Undefined,Void,any
TS还有元组,interface,type,泛型
泛型:我们在定义接口或者类的时候没有定义具体的类型,调用的时候才定义类型,用一个来表示泛型
类型声明:兼容没有声明的包
抽象类:能够定义具体的实现