gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区

站長資訊網
最全最豐富的資訊網站

JavaScript常見的手寫功能

JavaScript常見的手寫功能

相關學習推薦:javascript

1. 防抖

function debounce(func, ms = 500) {  let timer;  return function (...args) {    if (timer) {       clearTimeout(timer);     }     timer = setTimeout(() => {       func.apply(this, args);     }, ms);   }; }復制代碼

2. 節流

function throttle(func, ms) {  let canRun = true;  return function (...args) {    if (!canRun) return;     canRun = false;     setTimeout(() => {       func.apply(this, args);       canRun = true;     }, ms);   }; }復制代碼

3. new

function myNew(Func) {  const instance = {};  if (Func.prototype) {    Object.setPrototypeOf(instance, Func.prototype);   }  const res = Func.apply(instance, [].slice.call(arguments, 1));  if (typeof res === "function" || (typeof res === "object" && res !== null)) {    return res;   }  return instance; }復制代碼

4. bind

Function.prototype.myBind = function (context = globalThis) {  const fn = this;  const args = Array.from(arguments).slice(1);  const newFunc = function () {    if (this instanceof newFunc) {      // 通過 new 調用,綁定 this 為實例對象       fn.apply(this, args);     } else {      // 通過普通函數形式調用,綁定 context       fn.apply(context, args);     }   };  // 支持 new 調用方式   newFunc.prototype = fn.prototype;  return newFunc; };復制代碼

5. call

Function.prototype.myCall = function (context = globalThis) {  // 關鍵步驟,在 context 上調用方法,觸發 this 綁定為 context   context.fn = this;  let args = [].slice.call(arguments, 1);  let res = context.fn(...args);  delete context.fn;  return res; };復制代碼

6. apply

Function.prototype.myApply = function (context = globalThis) {  // 關鍵步驟,在 context 上調用方法,觸發 this 綁定為 context   context.fn = this;  let res;  if (arguments[1]) {     res = context.fn(...arguments[1]);   } else {     res = context.fn();   }  delete context.fn;  return res; };復制代碼

7. deepCopy

function deepCopy(obj, cache = new WeakMap()) {  if (!obj instanceof Object) return obj;  // 防止循環引用   if (cache.get(obj)) return cache.get(obj);  // 支持函數   if (obj instanceof Function) {    return function () {       obj.apply(this, arguments);     };   }  // 支持日期   if (obj instanceof Date) return new Date(obj);  // 支持正則對象   if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags);  // 還可以增加其他對象,比如:Map, Set等,根據情況判斷增加即可,面試點到為止就可以了    // 數組是 key 為數字素銀的特殊對象   const res = Array.isArray(obj) ? [] : {};  // 緩存 copy 的對象,用于出來循環引用的情況   cache.set(obj, res);  Object.keys(obj).forEach((key) => {    if (obj[key] instanceof Object) {       res[key] = deepCopy(obj[key], cache);     } else {       res[key] = obj[key];     }   });  return res; }復制代碼

8. 事件總線 | 發布訂閱模式

class EventEmitter {  constructor() {    this.cache = {};   }    on(name, fn) {    if (this.cache[name]) {      this.cache[name].push(fn);     } else {      this.cache[name] = [fn];     }   }    off(name, fn) {    const tasks = this.cache[name];    if (tasks) {      const index = tasks.findIndex((f) => f === fn || f.callback === fn);      if (index >= 0) {         tasks.splice(index, 1);       }     }   }    emit(name) {    if (this.cache[name]) {      for (let fn of this.cache[name]) {         fn();       }     }   }     emit(name, once = false) {    if (this.cache[name]) {      // 創建事件副本,如果回調函數內繼續注冊相同事件,觸發時,會造成死循環       const tasks = this.cache[name].slice()      for (let fn of tasks) {         fn();       }      if (once) {        delete this.cache[name]       }     }   } }復制代碼

9. 柯里化:只傳遞給函數一部分參數來調用它,讓它返回一個函數去處理剩下的參數

function curry(func) {  return function curried(...args) {    if (args.length >= func.length) {       func.apply(this, args);     } else {      return function (...args2) {         curried.apply(this, args.concat(args2));       };     }   }; }復制代碼

10. es5 實現繼承

function create(proto) {  function F() {}   F.prototype = proto;  return new F(); }// Parentfunction Parent(name) {  this.name = name; }  Parent.prototype.say = function () {  console.log(this.name); };// Childfunction Child(age, name) {   Parent.call(this, name);  this.age = age; } Child.prototype = create(Parent.prototype); Child.prototype.constructor = Child;  Child.prototype.say = function () {  console.log(this.age); };復制代碼

11. instanceof

function instanceOf(instance, klass) {  let proto = instance.__proto__;  let prototype = klass.prototype;  while (true) {    if (proto === null) return false;    if (proto === prototype) return true;     proto = proto.__proto__;   } }復制代碼

12. 異步并發數限制

/**  * 關鍵點說明  * 1. new promise 一經創建,立即執行  * 2. 使用 Promise.resolve().then 可以把任務加到微任務隊列,防止立即執行迭代方法  * 3. 微任務處理過程中,產生的新的微任務,會在同一事件循環內,追加到微任務隊列里  * 4. 使用 race 在某個任務完成時,繼續添加任務,保持任務按照最大并發數進行執行  * 5. 任務完成后,需要從 doingTasks 中移出  */function limit(count, array, iterateFunc) {  const tasks = [];  const doingTasks = [];  let i = 0;  const enqueue = () => {    if (i === array.length) {      return Promise.resolve();     }    const task = Promise.resolve().then(() => iterateFunc(array[i++]));     tasks.push(task);    const doing = task.then(() => doingTasks.splice(doingTasks.indexOf(doing), 1));     doingTasks.push(doing);    const res = doingTasks.length >= count ? Promise.race(doingTasks) : Promise.resolve();    return res.then(enqueue);   };  return enqueue().then(() => Promise.all(tasks)); }// testconst timeout = i => new Promise(resolve => setTimeout(() => resolve(i), i)); limit(4, [1000, 1000, 1000, 1000], timeout).then((res) => {  console.log(res); })復制代碼

13. 異步串行 | 異步并行

// 大廠面試題,實現一個異步加法function asyncAdd(a, b, callback) {   setTimeout(function () {     callback(null, a + b);   }, 1000); }// 0. promisifyconst promiseAdd = (a, b) => new Promise((resolve, reject) => {   asyncAdd(a, b, (err, res) => {    if (err) {       reject(err)     } else {       resolve(res)     }   }) })// 1. 串行處理async function serialSum(...args) {  return args.reduce((task, now) => task.then(res => promiseAdd(res, now)), Promise.resolve(0)) }// 2. 并行處理async function parallelSum(...args) {  if (args.length === 1) return args[0]  const tasks = []  for (let i = 0; i < args.length; i += 2) {     tasks.push(promiseAdd(args[i], args[i + 1] || 0))   }  const results = await Promise.all(tasks)  return parallelSum(...results) }// 測試(async () => {  const res1 = await serialSum(1, 2, 3, 4, 5, 8, 9, 10, 11, 12)  console.log(res1)  const res2 = await parallelSum(1, 2, 3, 4, 5, 8, 9, 10, 11, 12)  console.log(res2) })()復制代碼

14. vue reactive

// Dep moduleclass Dep {  static stack = []  static target = null   deps = null      constructor() {    this.deps = new Set()   }    depend() {    if (Dep.target) {      this.deps.add(Dep.target)     }   }    notify() {    this.deps.forEach(w => w.update())   }  static pushTarget(t) {    if (this.target) {      this.stack.push(this.target)     }    this.target = t   }  static popTarget() {    this.target = this.stack.pop()   } }// reactivefunction reactive(o) {  if (o && typeof o === 'object') {    Object.keys(o).forEach(k => {       defineReactive(o, k, o[k])     })   }  return o }function defineReactive(obj, k, val) {  let dep = new Dep()  Object.defineProperty(obj, k, {     get() {       dep.depend()      return val     },     set(newVal) {       val = newVal       dep.notify()     }   })  if (isObj(val)) {     reactive(val)   } }// watcherclass Watcher {  constructor(effect) {    this.effect = effect    this.update()   }    update() {     Dep.pushTarget(this)    this.value = this.effect()     Dep.popTarget()    return this.value   } }// 測試代碼const data = reactive({  msg: 'aaa'})new Watcher(() => {  console.log('===> effect', data.msg); })  setTimeout(() => {   data.msg = 'hello'}, 1000)復制代碼

15. promise

// 建議閱讀 [Promises/A+ 標準](https://promisesaplus.com/)class MyPromise {  constructor(func) {    this.status = 'pending'     this.value = null     this.resolvedTasks = []    this.rejectedTasks = []    this._resolve = this._resolve.bind(this)    this._reject = this._reject.bind(this)    try {       func(this._resolve, this._reject)     } catch (error) {      this._reject(error)     }   }    _resolve(value) {     setTimeout(() => {      this.status = 'fulfilled'       this.value = value      this.resolvedTasks.forEach(t => t(value))     })   }    _reject(reason) {     setTimeout(() => {      this.status = 'reject'       this.value = reason      this.rejectedTasks.forEach(t => t(reason))     })   }    then(onFulfilled, onRejected) {    return new MyPromise((resolve, reject) => {      this.resolvedTasks.push((value) => {        try {          const res = onFulfilled(value)          if (res instanceof MyPromise) {             res.then(resolve, reject)           } else {             resolve(res)           }         } catch (error) {           reject(error)         }       })      this.rejectedTasks.push((value) => {        try {          const res = onRejected(value)          if (res instanceof MyPromise) {             res.then(resolve, reject)           } else {             reject(res)           }         } catch (error) {           reject(error)         }       })     })   }  catch(onRejected) {    return this.then(null, onRejected);   } }// 測試new MyPromise((resolve) => {   setTimeout(() => {     resolve(1);   }, 500); })   .then((res) => {    console.log(res);    return new MyPromise((resolve) => {       setTimeout(() => {         resolve(2);       }, 500);     });   })   .then((res) => {    console.log(res);   }, err => {    console.log('==>', err);   });復制代碼

歡迎大家一起補充~

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区
亚洲va综合va国产va中文| 加勒比海盗1在线观看免费国语版| 国产91在线免费| 国产天堂在线播放| 天天综合天天添夜夜添狠狠添| 一区二区久久精品| 欧美精品一区二区性色a+v| 免费的一级黄色片| 国产精品秘入口18禁麻豆免会员 | 91热视频在线观看| mm131午夜| 日本www在线播放| 17c国产在线| 男人天堂av片| 免费观看成人网| 秋霞在线一区二区| 男人的天堂99| 北条麻妃亚洲一区| 热99这里只有精品| 中文字幕资源在线观看| 精品人妻人人做人人爽| 欧美激情成人网| 五月天综合婷婷| 欧美色图色综合| 天天做天天爱天天高潮| 97成人在线观看视频| 一级片黄色免费| 国产极品尤物在线| 在线播放 亚洲| 国产aaa一级片| 青青视频免费在线观看| 亚洲精品视频导航| 妞干网在线视频观看| 青青草久久伊人| av片中文字幕| 青青青青在线视频| 婷婷视频在线播放| 国产精品拍拍拍| 成年人看的毛片| youjizz.com亚洲| 亚洲综合欧美激情| 人妻精品无码一区二区三区 | 五月婷婷之婷婷| 黄色动漫网站入口| 精品人妻人人做人人爽| 日日干日日操日日射| 999香蕉视频| 欧美亚洲日本一区二区三区| 国产xxxxhd| 午夜在线观看av| 日本成人在线免费视频| 丰满的少妇愉情hd高清果冻传媒| 黄色三级视频在线播放| 91香蕉视频污版| 少妇高清精品毛片在线视频| www.avtt| 精品国产一区二区三区无码| 久久久国产精华液999999| www.日日操| 中国 免费 av| 中文字幕亚洲影院| 手机在线视频一区| av噜噜在线观看| 亚洲天堂伊人网| 国产成人美女视频| 久久久久久久久久久久久久久国产| 一级黄色香蕉视频| 国产小视频精品| 日本 片 成人 在线| 邪恶网站在线观看| 可以看污的网站| 色呦色呦色精品| 手机在线国产视频| 一二三av在线| 影音先锋男人的网站| mm131午夜| 欧美午夜小视频| 国产精品沙发午睡系列| 青青青国产在线视频| 男人女人黄一级| 91高清国产视频| 中文字幕精品在线播放| 国产精品久久久久久久久电影网| 国产日韩亚洲欧美在线| 欧美 丝袜 自拍 制服 另类| 成人黄色片视频| 色一情一区二区三区| 在线无限看免费粉色视频| 成人毛片100部免费看| 黄色大片在线免费看| www.爱色av.com| 久久久久久蜜桃一区二区| av动漫免费观看| 国产欧美日韩网站| 午夜免费精品视频| 女同性恋一区二区| 波多野结衣之无限发射| 人妻无码视频一区二区三区| 五月天丁香花婷婷| 日韩欧美不卡在线| 亚洲国产精品三区| 黄色一级视频播放| 久章草在线视频| 欧美爱爱视频网站| 热99这里只有精品| 三级性生活视频| 精品无码一区二区三区在线| 手机看片福利日韩| 干日本少妇视频| 久久久久久久久久久久久国产精品 | 黄色片久久久久| 精品一区二区成人免费视频 | 中国老女人av| 动漫av网站免费观看| 三级黄色片播放| 免费无码不卡视频在线观看| 男人的天堂最新网址| 一卡二卡三卡视频| 午夜天堂在线视频| 国产精品免费成人| www.日本三级| 精品日韩久久久| 少妇无码av无码专区在线观看| www.久久av.com| 欧美精品色婷婷五月综合| 高清无码一区二区在线观看吞精| 国产九九在线视频| 国产白丝袜美女久久久久| 在线观看免费视频高清游戏推荐| avav在线播放| 亚洲精品性视频| 中文字幕第21页| 国产精品又粗又长| 天堂а√在线中文在线| 欧美激情第3页| 国产精品69页| av免费观看大全| 日韩欧美猛交xxxxx无码| 九九热视频免费| 亚洲一区二区三区四区五区xx| 免费成人午夜视频| 欧美极品少妇无套实战| 日本高清久久久| 99视频免费播放| 99色精品视频| av网站在线观看不卡| 国产91xxx| av在线观看地址| 91九色丨porny丨国产jk| 久久视频免费在线| 穿情趣内衣被c到高潮视频| 91高清国产视频| 不卡的在线视频| 涩涩网站在线看| 成人手机视频在线| 欧美性受xxxx黑人猛交88| 欧美日韩一级在线| 狠狠干视频网站| 蜜臀av性久久久久蜜臀av| 蜜桃视频一区二区在线观看| 男女啪啪免费观看| 亚洲理论电影在线观看| 黄网站欧美内射| 日韩中文字幕在线视频观看| 免费在线a视频| 日本www.色| 午夜啪啪小视频| 永久免费看av| 欧美精品久久久久久久自慰| 午夜精品久久久久久久无码| 大肉大捧一进一出好爽动态图| 东京热加勒比无码少妇| www.日日操| 99中文字幕在线| 免费高清一区二区三区| 亚洲中文字幕无码中文字| 欧美性猛交xxx乱久交| 亚洲自拍第三页| 成人小视频在线观看免费| 霍思燕三级露全乳照| 亚洲五月天综合| www.色就是色.com| 大西瓜av在线| 成人免费毛片播放| 特级黄色录像片| 99热在线这里只有精品| 色婷婷.com| 成人性生活视频免费看| 一级黄色香蕉视频| 日韩不卡视频一区二区| 免费无码av片在线观看| 手机在线国产视频| 和岳每晚弄的高潮嗷嗷叫视频| 成人性生生活性生交12| 美女黄色片网站| 国产精品视频一区二区三区四区五区| 国产色视频在线播放| 日韩精品一区二区在线视频| 欧美综合在线观看视频| 天天干天天操天天干天天操|