深拷贝
浅拷贝只是拷贝了对象(引用类型)的指针,在修改对象时会影响到原来对象(基础类型不会影响)
深拷贝就是为了弥补浅拷贝的不足,说白了就是遇到对象或者数组时进行递归,将他们拆分成基础类型,这样就实现互不影响了。话不多说,直接撸
function deepClone(result,target){
//判断是否为数组
result = Array.isArray(target) ? [] : {};
for( var i in target ){
if(target[i] == 'object'){
deepClone(result[i],target[i])
}else{
result[i] == target[i]
}
}
return result;
}
promise
理解promise:promise只负责返回一个成功或者失败的状态(利用js提供的resolve和reject方法),然后就没用了,后续的要使用then接收状态来操作
1、new Promise传入的executor方法代码是同步执行的;
2、promise对象的状态有三种:pending(等待态),resolved(成功态),rejected(失败态),只能从等待态转化成成功态或失败态;
3、executor中执行resolve()方法,表示将转化为成功态,promise.then调用时执行成功的方法,executor中执行reject()方法,表示将转化为成功态,promise.then调用时执行失败的方法。
function myPromise(executor){
this.status = 'pending' ;
this.value = null;
this.reason = null;
this.resCallback = [];//存放then成功回调
this.rejCallback = [];//存放then失败回调
const resolve = (value) => {
if(this.status === 'pending') {
this.status = 'resolved';
this.value = value;
this.resCallback.forEach(fn => {
fn()
})
}
const rejected = (reason) => {
if(this.status ==' pending') {
this.status = 'rejected';
this.reason = reason;
this.rejCallback.forEach(fn => {
fn()
})
}
}
}
//1、then 生成一个新的 promise
//2、then同步调用:状态改变直接执行onFulfilled和onRejected
//3、then异步调用:(setTimeout为了表达异步的意思,其实内部并不是使用setTime实现的)
状态为pending,则将结果存储到函数数组中,此时then还没有执行,只用于存储状态,当调用
resolve和rejected时在执行。
//4、为了实现链式调用,所以then要返回一个状态。
myPromise.prototype.then = function(onFulfilled,onRejected){
switch(this.statu){
case fulfilled:
setTimeout(() => {
try {
resolve(onFulfilled(this.value));
} catch{
reject(reason);
}
}, 0);
break;
case rejected:
setTimeout(() => {
try {
resolve(onRejected(this.reason));
} catch{
reject(reason);
}
}, 0);
break;
case PENDING:
this.resCallback.push(() => {
setTimeout(() => {
onFulfilled(this.value)
}, 0);
})
this.rejCallback.push(() => {
setTimeout(() => {
onRejected(this.reason)
})
})
}
}
3、单例模式
立即执行函数加闭包
var alone =(function(){
var a = function(){
//...code
};
return a
})()
4、bind
bind的两个特性,柯里化和new,当new的时候,bind的this层面不起作用,只有后面传入的参数还起作用。下面简单实现柯里化
function myBind(context, ...args){
if(typeof context !== 'function'){//判断函数
throw new TypeError("error");
}
const self = this;
function myFunc(...args2){
return self.apply(context,args.concat(args2)//实现函数柯里化
}
}
继续优化
当使用new时,会创建一个空对象,将this指向这个空对象,空对象的隐式原型(proto)指向构造器的显示原型(myFunc.prototype)
function myBind(context, ...args){
if(typeof context !== 'function'){//判断函数
throw new TypeError("error");
}
const self = this;
const myFn = function(){}
function myFunc(...args2){
return self.apply(
this instanceof myFn ? this : context,
args1.concat(args2)
)
}
myFn.prototype = this.prototype;
myFunc.prototype = new myFn();
return myFunc;
}
参考链接:www.cnblogs.com/goloving/p/…
5、函数柯里化
说白了就是使用闭包把参数存起来,当参数数量足够执行函数了,就开始执行函数
function currying(fn,...args){
if(args.length >= fn.length){//参数数量够了,返回
return fn(args);
}else{//参数不够,递归返回一个闭包,存入传进的参数并返回
return (...args2) => currying(fn,...args,...args2)
}
}
6、es5继承
寄生组合继承
function child(){
parent.call(this);
}
var myProto = Object.create(parent.prototype);
myProto.constructor = child;
child.prototype = myProto;
7、实现instanceof
递归的判断左式的隐式原型连(即左式的原型链)是否等于右式的显示原型
function myInstanceof(target,origin){
const proto = target.__proto__;
if(proto){
if(origin.prototype === proto){
return true;
}else{
myInstanceof(proto,origin)
}
}else{
return false;
}
}
8、防抖
:触发事件后的n秒内,如果再次触发事件,就会重新计算时间,只有在n秒不再触发事件,n秒后执行事件。
就像王者荣回城一样,回程的几秒钟内,如果再次点击回城,就会重新计算回城,时间到了才回城。
function boun(enent, time){
let timer = null;//定义一个为空的定时器
return function(...args){
clearTime(timer);//清空定时器
timer = setTimeout(() => {//定时器是一个time秒后执行
event.apply(this,args);
},time);
};
}
9、节流
:不管事件的触发频率有多高,单位时间内只执行一次
举个栗子:就像王者荣耀的技能,例如冷却时间是三秒,那么这个技能3秒内只能是放一次,3秒后才能释放下一次。
function thro(event,time){
let timer = null; //定义空的定时器
return function(...args){
if(!timer){//如果此时定时器为空,那么执行定时器
timer = setTimeout(() => {
timer = null;
event.apply(this,args);
},time); //定时时间到将定时器置为空。
}
}
}