深拷贝
function deepClone(source){
const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象
for(let keys in source){ // 遍历目标
if(source.hasOwnProperty(keys)){
if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下
targetObj[keys] = source[keys].constructor === Array ? [] : {};
targetObj[keys] = deepClone(source[keys]);
}else{ // 如果不是,就直接赋值
targetObj[keys] = source[keys];
}
}
}
return targetObj;
}
或
function deepClone(obj, newObj) {
for (var key in obj) {
if(obj[key] instanceof Array){
newObj[key]=[]
deepClone(obj[key],newObj[key])
}else if(obj[key] instanceof Object){
newObj[key]={}
deepClone(obj[key],newObj[key])
}else{
newObj[key]=obj[key]
}
}
return newObj;
}
var obj = {
name: 'ww',
car: {
nick: 'ss',
brand: {
list: [1, 3]
}
}
}
console.log(deepClone(obj,{}))
Promise
// 定义状态常量
const PENDING = 'PENDING'
const FULFILLED = 'FULFILLED'
const REJECTED = 'REJECTED'
class Promise {
constructor(executor){
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = []
this.onRejectedCallbacks = []
const resolve = value =>{
this.status = FULFILLED
this.value = value
this.onResolvedCallbacks.map(fn=>fn(this.value))
}
const reject = reason => {
this.status = REJECTED
this.reason = reason
this.onRejectedCallbacks.map(fn=>fn(this.reason))
}
// 当executor执行报错时,需要调用reject函数
try{
executor(resolve, reject)
}catch(e){
reject(e)
}
}
then(onFulfilled, onRejected){
// 判断当前promise的状态
if(this.status == FULFILLED){
onFulfilled(this.value)
}else if(this.status == REJECTED){
onRejected(this.reason)
}else{
// 状态为pending,将onFulfilled和onRejected分别加入onResolvedCallbacks和onRejectedCallbacks数组中,
// 等待resolve或reject函数执行时调用
this.onResolvedCallbacks.push(()=>{
// do something
onFulfilled(this.value)
})
this.onRejectedCallbacks.push(()=>{
// do something
onRejected(this.reason)
})
}
}
}
合并数组
let arr1=[1,2,3];
let arr2=[4,5,6];
Array.prototype.push.apply(arr1,arr2); //将arr2合并到了arr1中
求数组最大值
Math.max.apply(null,arr)
判断字符类型
Object.prototype.toString.call({})
节流
let throttle = function(func, delay) {
let timer = null;
return function() {
if (!timer) {
timer = setTimeout(function() {
func.apply(this, arguments);
timer = null;
}, delay);
}
};
};
function handle() {
console.log(Math.random());
}
window.addEventListener("scroll", throttle(handle, 1000)); //事件处理函数
防抖
function debounce(fn, wait) {
var timeout = null;
return function() {
if (timeout !== null) clearTimeout(timeout);//如果多次触发将上次记录延迟清除掉
timeout = setTimeout(function() {
fn.apply(this, arguments);
timer = null;
}, wait);
};
}
// 处理函数
function handle() {
console.log(Math.random());
}
// 滚动事件
window.addEventListener("onscroll", debounce(handle, 1000));
函数柯里化
function curry(fn) {
let arg = []; //用于收集参数
//做一个闭包
return function () {
//每执行一次收集一次参数,为什么用concat是因为有时候后是多个参数(2,3)
arg = [...arg,...arguments];
//直到参数收集完成执行fn
// 我们需要知道什么时候收集完了,条件就是curry参数fn的参数个数 fn.length
//如果收集的参数个数大于等于fn的参数个数执行fn,如果没有递归执行
// fn.length是形参个数
if (arg.length >= fn.length) {
return fn(...arg)
}
// 参数没有收集完我们需要继续收集,递归,callee指向arguments的函数
return arguments.callee
}
}
function volume(l, h, w) {
return l + h + w
}
const hCy = curry(volume)
console.log(hCy(100)(200)(900)) // 1200
反柯里化
Function.prototype.uncurrying = function() {
var that = this;
return function() {
return Function.prototype.call.apply(that, arguments);
}
};
function sayHi () {
return "Hello " + this.value +" "+[].slice.call(arguments);
}
let sayHiuncurrying=sayHi.uncurrying();
console.log(sayHiuncurrying({value:'world'},"hahaha"));
call实现
Function.prototype.newCall = function(context, ...parameter) {
context.fn = this;
context.fn(...parameter);
delete context.fn;
}
let person = {
name: 'Abiel'
}
function sayHi(age,sex) {
console.log(this.name, age, sex);
}
sayHi.newCall (person, 25, '男'); // Abiel 25 男
apply实现
Function.prototype.newApply = function(context, parameter) {
if (typeof context === 'object') {
context = context || window
} else {
context = Object.create(null)
}
let fn = Symbol()
context[fn] = this
context[fn](parameter);
delete context[fn]
}
bind实现
Function.prototype.bind = function (context,...innerArgs) {
var me = this
return function (...finnalyArgs) {
return me.call(context,...innerArgs,...finnalyArgs)
}
}
let person = {
name: 'Abiel'
}
function sayHi(age,sex) {
console.log(this.name, age, sex);
}
let personSayHi = sayHi.bind(person, 25)
personSayHi('男')
var new2 = function (func) {
var o = Object.create(func.prototype); //创建对象
var k = func.call(o); //改变this指向,把结果付给k
if (typeof k === 'object') { //判断k的类型是不是对象
return k; //是,返回k
} else {
return o; //不是返回返回构造函数的执行结果
}
}
参考链接:
https://segmentfault.com/a/1190000014405410
https://blog.csdn.net/weixin_47346395/article/details/107172086