深拷貝
function deepClone(source){
? const targetObj = source.constructor === Array ? [] : {}; // 判斷復(fù)制的目標(biāo)是數(shù)組還是對(duì)象
? for(let keys in source){ // 遍歷目標(biāo)
? ? if(source.hasOwnProperty(keys)){
? ? ? if(source[keys] && typeof source[keys] === 'object'){ // 如果值是對(duì)象,就遞歸一下
? ? ? ? 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
// 定義狀態(tài)常量
? ? 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))
? ? ? ? ? ? }
? ? ? ? ? ? // 當(dāng)executor執(zhí)行報(bào)錯(cuò)時(shí)显押,需要調(diào)用reject函數(shù)
? ? ? ? ? ? try{
? ? ? ? ? ? ? ? executor(resolve, reject)
? ? ? ? ? ? }catch(e){
? ? ? ? ? ? ? ? reject(e)
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? then(onFulfilled, onRejected){
? ? ? ? ? ? // 判斷當(dāng)前promise的狀態(tài)
? ? ? ? ? ? if(this.status == FULFILLED){
? ? ? ? ? ? ? ? onFulfilled(this.value)
? ? ? ? ? ? }else if(this.status == REJECTED){
? ? ? ? ? ? ? ? onRejected(this.reason)
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? // 狀態(tài)為pending艘儒,將onFulfilled和onRejected分別加入onResolvedCallbacks和onRejectedCallbacks數(shù)組中辕漂,
? ? ? ? ? ? ? ? // 等待resolve或reject函數(shù)執(zhí)行時(shí)調(diào)用
? ? ? ? ? ? ? ? this.onResolvedCallbacks.push(()=>{
? ? ? ? ? ? ? ? ? ? // do something
? ? ? ? ? ? ? ? ? ? onFulfilled(this.value)
? ? ? ? ? ? ? ? })
? ? ? ? ? ? ? ? this.onRejectedCallbacks.push(()=>{
? ? ? ? ? ? ? ? ? ? // do something
? ? ? ? ? ? ? ? ? ? onRejected(this.reason)
? ? ? ? ? ? ? ? })
? ? ? ? ? ? }
? ? ? ? }
? ? }
合并數(shù)組
? ? ? ? let arr1=[1,2,3];
? ? ? ? let arr2=[4,5,6];
? ? ? ? Array.prototype.push.apply(arr1,arr2); //將arr2合并到了arr1中
求數(shù)組最大值
? ? ? ? Math.max.apply(null,arr)
判斷字符類(lèi)型
? ? ? ? Object.prototype.toString.call({})
節(jié)流
? ? ? ? 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)); //事件處理函數(shù)
防抖
? ? ? ? function debounce(fn, wait) {
? ? ? ? ? ? var timeout = null;
? ? ? ? ? ? return function() {
? ? ? ? ? ? ? ? if (timeout !== null) clearTimeout(timeout);//如果多次觸發(fā)將上次記錄延遲清除掉
? ? ? ? ? ? ? ? timeout = setTimeout(function() {
? ? ? ? ? ? ? ? ? ? ? ? fn.apply(this, arguments);
? ? ? ? ? ? ? ? ? ? ? ? timer = null;
? ? ? ? ? ? ? ? }, wait);
? ? ? ? ? ? };
? ? ? ? }
? ? ? ? // 處理函數(shù)
? ? ? ? function handle() {
? ? ? ? ? ? console.log(Math.random());
? ? ? ? }
? ? ? ? // 滾動(dòng)事件
? ? ? ? window.addEventListener("onscroll", debounce(handle, 1000));
函數(shù)柯里化
? ? ? ? function curry(fn) {
? ? ? ? ? ? let arg = []; //用于收集參數(shù)
? ? ? ? ? ? //做一個(gè)閉包
? ? ? ? ? ? return function () {
? ? ? ? ? ? ? ? //每執(zhí)行一次收集一次參數(shù),為什么用concat是因?yàn)橛袝r(shí)候后是多個(gè)參數(shù)(2,3)
? ? ? ? ? ? ? ? arg = [...arg,...arguments];
? ? ? ? ? ? ? ? //直到參數(shù)收集完成執(zhí)行fn
? ? ? ? ? ? ? ? // 我們需要知道什么時(shí)候收集完了拟糕,條件就是curry參數(shù)fn的參數(shù)個(gè)數(shù) fn.length
? ? ? ? ? ? ? ? //如果收集的參數(shù)個(gè)數(shù)大于等于fn的參數(shù)個(gè)數(shù)執(zhí)行fn,如果沒(méi)有遞歸執(zhí)行
? ? ? ? ? ? ? ? // fn.length是形參個(gè)數(shù)
? ? ? ? ? ? ? ? if (arg.length >= fn.length) {
? ? ? ? ? ? ? ? ? ? return fn(...arg)
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? // 參數(shù)沒(méi)有收集完我們需要繼續(xù)收集注祖,遞歸,callee指向arguments的函數(shù)
? ? ? ? ? ? ? ? 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實(shí)現(xiàn)
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實(shí)現(xiàn)
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實(shí)現(xiàn)
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); //創(chuàng)建對(duì)象
? ? var k = func.call(o); //改變this指向谓厘,把結(jié)果付給k
? ? if (typeof k === 'object') { //判斷k的類(lèi)型是不是對(duì)象
? ? ? ? return k; //是财剖,返回k
? ? } else {
? ? ? ? return o; //不是返回返回構(gòu)造函數(shù)的執(zhí)行結(jié)果
? ? }
}?
參考鏈接:
https://segmentfault.com/a/1190000014405410
https://blog.csdn.net/weixin_47346395/article/details/107172086