1.什么是闭包?
参考链接:https://zhuanlan.zhihu.com/p/22486908
个人理解:大函数里面嵌套一个小函数,小函数里面的有个参数是大函数里面定义的就是闭包。
举例:once函数只执行一次 (使用了闭包)
function once(fn) {
let done = true; // 大函数定义
return function () {
if (!done) return;
done = false; // 小函数使用实现闭包
fn.apply(this,arguments);
}
}
function pay(money) {
console.log(`支付:${money}¥成功`)
}
const f = once(() => { pay(5) });
f();
f();
2.什么是防抖?
个人理解:触发高频事件后,n秒内函数只执行一次,如果n秒内高频事件再次被触发,则重新计算时间。
举例:
function fangdou(fn) {
let timer = null;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments);
}, 3000);
}
}
function test(){
console.log('start ..........');
}
const f = fangdou(test);
f();
setTimeout(()=>{
f();
},2000)
setTimeout(()=>{
f();
},4000)
3.什么是节流?
个人理解:触发高频事件后,规定函数n秒内只执行一次,如果这n秒内,再次触发,直接返回不进行执行。
function jieliu(fn) {
let done = true;
return function () {
if (!done) return;
done = false;
setTimeout(() => {
fn.apply(this, arguments);
done = true;
}, 3000)
}
}
function fn() {
console.log('start..........');
}
const test2 = jieliu(fn);
test2();
setTimeout(() => {
test2();
}, 2000);
setTimeout(() => {
test2();
}, 4000);
4.Promise定义及实现其基本功能实现。
- 1.创建Promise 对象, promise就是一个类,在执行这个类的时候,
- 需要传递一个执行器进去,这个执行器会立即执行
- 2.Promise中有三种状态,分别为
- 成功 —> fulfilled
- 失败 —> rejected
- 等待 —> pending
- 3.Promise 状态一旦发生改变,就不可更改
- 4.then方法内部做的事情是判断状态。
- 如果状态是成功,就调用成功回调函数,如果是失败,就调用失败回调函数
- 5.加入成功有返回值,失败也有返回值
- 6.加入异步
- 7.then多次调用 同步情况无需出处理 异步需要处理
- 8.then方法链式调用
- 9.自返回检查 自己调用自己处理
- 10.执行器错误,处理
- 11.then 未传值
- 12.all、any、rance
- 13.resolve 返回的就是一个对象
- 14.catch
Promise简易版代码:
'use strict';
const PENDING = 'pending';
const FULFILLIED = 'fulfillied';
const REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject);
} catch (e) {
this.reject(e);
}
}
value = undefined;
reason = undefined;
successCallback = [];
failCallback = [];
status = PENDING;
resolve = value => {
if (this.status !== PENDING) return;
this.value = value;
this.status = FULFILLIED;
while (this.successCallback.length > 0) this.successCallback.shift()();
}
reject = reason => {
if (this.status !== PENDING) return;
this.reason = reason;
this.status = REJECTED;
while (this.failCallback.length > 0) this.failCallback.shift();
}
then(successCallback, failCallback) {
successCallback = successCallback ? successCallback : value => value;
failCallback = failCallback ? failCallback : reason => { throw reason };
let promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLIED) {
try {
setTimeout(() => {
let x = successCallback(this.value);
resolvePromise(x, promise2, resolve, reject);
}, 0)
} catch (e) {
console.log(e);
}
} else if (this.status === REJECTED) {
try {
setTimeout(() => {
let x = failCallback(this.reason);
resolvePromise(x, promise2, resolve, reject);
}, 0)
} catch (e) {
console.log(e);
}
} else {
this.successCallback.push(() => {
try {
setTimeout(() => {
let x = successCallback(this.value);
resolvePromise(x, promise2, resolve, reject);
}, 0)
} catch (e) {
console.log(e);
}
});
this.failCallback.push(() => {
try {
setTimeout(() => {
let x = failCallback(this.reason);
resolvePromise(x, promise2, resolve, reject);
}, 0)
} catch (e) {
console.log(e);
}
});
}
});
return promise2;
}
static all(array) {
let result = [];
let index = 0;
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value;
if (++index === array.length) resolve(result);
}
for (let i = 0; i < array.length; i++) {
if (array[i] instanceof MyPromise) {
array[i].then(value => addData(i, value), reason => reject(reason));
} else {
addData(i, array[i]);
}
}
})
}
static resolve(value) {
if (value instanceof MyPromise) return value;
return new MyPromise(resolve => resolve(value));
}
finally(callback) {
return this.then(value => {
return MyPromise.resolve(callback()).then(value => value);
}, reason => {
return MyPromise.resolve(callback()).then(() => { throw reason });
});
}
catch(failCallback) {
return this.then(undefined, failCallback);
}
}
function resolvePromise(x, promise2, resolve, reject) {
if (x === promise2) {
return reject(new TypeError('promise === promise2'));
} else if (x instanceof MyPromise) {
x.then(resolve, reject);
} else {
resolve(x);
}
}
module.exports= MyPromise;
部分Promise测试代码:
'use strict';
const MyPromise = require('./promise3');
/**
// const a = new MyPromise((resolve, reject) => {
// console.log('12');
// reject('失败')
// resolve("成功")
// });
// a.then(value => {
// console.log(value)
// },reason=>{
// console.log(reason)
// });
// const asy = new MyPromise((resolve, reject) => {
// setTimeout(() => {
// resolve('等待结束');
// }, 2000);
// });
// asy.then(value => {
// console.log(value);
// }, reason => {
// console.log(reason);
// });
// asy.then(value => {
// console.log(value);
// }, reason => {
// console.log(reason);
// });
// asy.then(value => {
// console.log(value);
// }, reason => {
// console.log(reason);
// });
// const promise = new MyPromise((resolve,reject)=>{
// resolve('成功');
// });
// promise.then(value=>{
// console.log(value);
// return 100
// }).then(value=>{
// console.log(value)
// })
// function other(){
// return new MyPromise((resolve,reject)=>{
// resolve('other');
// });
// }
// const promise = new MyPromise((resolve,reject)=>{
// resolve('成功');
// });
// promise.then(value=>{
// console.log(value);
// return other();
// }).then(value=>{
// console.log(value)
// });
// function other(){
// return new MyPromise((resolve,reject)=>{
// resolve('other');
// });
// }
// const promise = new MyPromise((resolve,reject)=>{
// resolve('成功');
// });
// let p1 = promise.then(value=>{
// console.log(value);
// return p1;
// });
// p1.then(value=>{
// console.log(value)
// },reason=>{
// console.log('reason:',reason)
// });
// const executor = new MyPromise((re,rj)=>{
// throw new Error('执行器错误');
// });
// executor.then(value=>console.log(value),reason=>console.log(reason))
// let promise = new MyPromise((resolve,reject)=>{
// resolve('成功');
// });
// // promise.then().then(value=>console.log(value));
// MyPromise.all([1,2,3,4]).then(value=>{
// console.log(value);
// });
5.Iterator、for of
概念:它是一种接口,为各种不同的数据结构提供统一的访问机制。
推荐文章:https://www.jb51.net/article/70106.htm ; https://www.cnblogs.com/xiaohuochai/p/7253466.html
最开始的数组访问采用的:
const array = [3, 6, 9, 12];
for (let i = 0; i < array.length; i++) {
console.log(array[i]);
}
ES5之后提供了forEach,但是不能够break结束循环。
// forEach 提供了三个参数
// value :值
// index :索引
// arr :当前数组
// 无返回值
const array = [3, 6, 9, 12];
array.forEach((value, index, arr) => {
console.log(value, index, arr);
});
for in 能不能解决这一问题?答案是不能,请看代码
缺点一:
const array = [3, 6, 9, 12];
array.name = 'array'; // 给数组添加一个属性后
for(let i in array){
console.log(array[i]);
}
结果:
3
6
9
12
array
很明显属性也被遍历出来了, 但是我们是不需要的。
缺点二:遍历的索引是字符串,这样就会导致,你明明想访问index+1 索引数据结果访问的是parseInt(index + ‘1’)的数据。
代码如下:
const array = [3, 6, 9, 12];
for(let i in array){
console.log(typeof i,array[i]);
}
结果:
string 3
string 6
string 9
string 12
基于以上缺点:然后出现了for of
推荐文章:https://www.cnblogs.com/xuetuan/p/12658441.html
for of 方法就是基于iterator。
iterator适用类型:
- Array
- Map
- Set
- String
- 函数的 arguments 对象
- NodeList 对象
例如:
var arr = ['a', 'b', 'c', 'd', 'e'];
var eArr = arr[Symbol.iterator]();
console.log(eArr.next().value); // a
console.log(eArr.next().value); // b
console.log(eArr.next().value); // c
console.log(eArr.next().value); // d
console.log(eArr.next().value); // e
这里推荐:https://www.cnblogs.com/everlose/p/12894300.html ,不再赘述。
6.Map、Set
- Set
// set : 存储的数据唯一不重复
const set = new Set();
// 添加数据
set.add(1);
set.add(1);
set.add(2);
set.add({ a: 1 });
// 删除数据
set.delete(1);
// 是不是包含该成员
console.log(set.has(2));
console.log(set);
// 清除所有成员,无返回值
set.clear();
console.log(set);
- Map
// map 结构提供了“值-值”的对应,类似于对象,是键值对的集合,
// “键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
// map
const map = new Map();
const o = { p: "Hello World" };
// set 添加数据
map.set(o, "content");
// get取值
let a = map.get(o);
console.log(a);
// delete 删除
map.delete(o);
// has是不是包含该成员
console.log(map.has(2));
console.log(map);
7.node.js数据类型,堆和栈的区别
-
基本数据类型:undefined、NULL、String、Number、Symbol、NAN、Boolean。
-
引用数据类型:Object、Array、Set 、Map。
-
基本数据类型和引用数据类型的存储位置?
答:基本数据类型存储在栈上,引用数据类型数据存储在堆内存上,
栈一般存储的是有固定大小,或者说有一定上线的,而堆不是,
他的 大小是变动的,分配完堆内存后,会记录内存地址到栈上。 -
可参考:https://www.cnblogs.com/heioray/p/9487093.html
8.Node.js单线程机制。
待写。。。。。。。。。
9.进程和线程
参考:https://blog.youkuaiyun.com/xgangzai/article/details/98919412
10.Node.js实现对象的深拷贝
- 方法一
const obj = { name: 'xmh', age: 30 };
const obj2 = JSON.parse(JSON.stringify(obj));
- 方法二
const obj = { name: 'xmh', age: 30 };
const obj2 = Object.assign({}, obj);
- 方法三
const obj = { name: 'xmh', age: 30 };
const obj2 = { ...obj };
其他待准备