├── .project ├── AMD-CMD-CommonJS.MD ├── AST.MD ├── Android-iOS.MD ├── Animation.MD ├── Axios.MD ├── BUG.MD ├── Babel.MD ├── Banner.MD ├── Blog.MD ├── CSS.MD ├── Canvas.MD ├── Chrome.MD ├── Chrome插件.MD ├── Cli.MD ├── Create-react-app.MD ├── Debug.MD ├── Docker.MD ├── ES6.MD ├── ESLint.MD ├── Easy-mock.MD ├── Electron.MD ├── Event-Loop.MD ├── Express.MD ├── Flutter.MD ├── Git.MD ├── GraphQL.MD ├── HTML.MD ├── HTTP.MD ├── Hexo.MD ├── Html2Canvas图像处理.MD ├── Hybrid.MD ├── Img.MD ├── JS-excel.MD ├── JS-file.MD ├── JS-pdf.MD ├── JS.MD ├── JSON.MD ├── JWT.MD ├── Koa.MD ├── Linux.MD ├── Mac.MD ├── Markdown.MD ├── Mobx.MD ├── Mock.MD ├── MongoDB.MD ├── NPM.MD ├── Nginx.MD ├── Node-cli.MD ├── Node-项目.MD ├── Node.MD ├── PWA.MD ├── PostCSS.MD ├── Promise.MD ├── README.md ├── React-cli.MD ├── React.MD ├── Redux.MD ├── RegExp.MD ├── Rollup.MD ├── Router.MD ├── SQL.MD ├── SSR.MD ├── SVG.MD ├── TypeScript.MD ├── Ui框架,图表.MD ├── Video.MD ├── VirtualDOM.MD ├── VsCode.MD ├── Vue-Component.MD ├── Vue-cli.MD ├── Vue.MD ├── Vue技巧.MD ├── Web Components.MD ├── WebAssembly.MD ├── WebGL.MD ├── WebWorker.MD ├── Webpack.MD ├── Websocket.MD ├── Weex.MD ├── Z7Z8.MD ├── _config.yml ├── javascript进阶 ├── Images │ ├── arguments.png │ ├── copy │ │ └── copy1.png │ ├── debounce │ │ ├── debounce-1.gif │ │ ├── debounce-4.gif │ │ ├── debounce-cancel.gif │ │ ├── debounce.gif │ │ └── event.png │ ├── each │ │ ├── each1.png │ │ └── each2.png │ ├── extend │ │ └── extend1.png │ ├── prototype1.png │ ├── prototype2.png │ ├── prototype3.png │ ├── prototype4.png │ ├── prototype5.png │ ├── recursion │ │ └── factorial.gif │ ├── shuffle │ │ ├── fisher-yates.png │ │ └── mathRandom.png │ ├── sort │ │ ├── bubble.gif │ │ ├── insertion-vs-quick.gif │ │ ├── insertion.gif │ │ ├── quick1.png │ │ ├── quick2.png │ │ ├── quick3.png │ │ ├── quickSort-time.png │ │ ├── quicksort.gif │ │ └── selection.gif │ ├── template │ │ └── template.png │ ├── throttle │ │ ├── throttle1.gif │ │ ├── throttle2.gif │ │ └── throttle3.gif │ ├── underscore │ │ └── new-obj.png │ └── xss │ │ └── sina_xss.jpg ├── articles │ ├── 专题系列文章 │ │ ├── JavaScript专题之jQuery通用遍历方法each的实现.md │ │ ├── JavaScript专题之乱序.md │ │ ├── JavaScript专题之从零实现jQuery的extend.md │ │ ├── JavaScript专题之偏函数.md │ │ ├── JavaScript专题之函数柯里化.md │ │ ├── JavaScript专题之函数组合.md │ │ ├── JavaScript专题之函数记忆.md │ │ ├── JavaScript专题之在数组中查找指定元素.md │ │ ├── JavaScript专题之如何判断两个对象相等.md │ │ ├── JavaScript专题之如何求数组的最大值和最小值.md │ │ ├── JavaScript专题之惰性函数.md │ │ ├── JavaScript专题之数组去重.md │ │ ├── JavaScript专题之数组扁平化.md │ │ ├── JavaScript专题之深浅拷贝.md │ │ ├── JavaScript专题之类型判断(上).md │ │ ├── JavaScript专题之类型判断(下).md │ │ ├── JavaScript专题之解读v8排序源码.md │ │ ├── JavaScript专题之跟着underscore学节流.md │ │ ├── JavaScript专题之跟着underscore学防抖.md │ │ └── JavaScript专题之递归.md │ └── 深入系列文章 │ │ ├── JavaScript深入之bind的模拟实现.md │ │ ├── JavaScript深入之call和apply的模拟实现.md │ │ ├── JavaScript深入之new的模拟实现.md │ │ ├── JavaScript深入之从ECMAScript规范解读this.md │ │ ├── JavaScript深入之从原型到原型链.md │ │ ├── JavaScript深入之作用域链.md │ │ ├── JavaScript深入之创建对象的多种方式以及优缺点.md │ │ ├── JavaScript深入之参数按值传递.md │ │ ├── JavaScript深入之变量对象.md │ │ ├── JavaScript深入之执行上下文.md │ │ ├── JavaScript深入之执行上下文栈.md │ │ ├── JavaScript深入之类数组对象与arguments.md │ │ ├── JavaScript深入之继承的多种方式和优缺点.md │ │ ├── JavaScript深入之词法作用域和动态作用域.md │ │ └── JavaScript深入之闭包.md └── demos │ ├── debounce │ ├── debounce1.js │ ├── debounce2.js │ ├── debounce3.js │ ├── debounce4.js │ ├── debounce5.js │ ├── debounce6.js │ ├── debounce7.js │ ├── index.html │ └── underscore.js │ ├── node-vm │ └── index.js │ ├── scope │ └── scope.bash │ ├── template │ ├── template1 │ │ ├── index.html │ │ └── template.js │ ├── template2 │ │ ├── index.html │ │ └── template.js │ ├── template3 │ │ ├── index.html │ │ └── template.js │ ├── template4.1 │ │ ├── index.html │ │ └── template.js │ ├── template4 │ │ ├── index.html │ │ └── template.js │ ├── template5 │ │ ├── index.html │ │ └── template.js │ ├── template6 │ │ ├── index.html │ │ └── template.js │ ├── template7 │ │ ├── index.html │ │ └── template.js │ └── template8 │ │ ├── index.html │ │ └── template.js │ ├── throttle │ ├── index.html │ ├── throttle1.js │ ├── throttle2.js │ ├── throttle3.js │ ├── throttle4.js │ └── throttle5.js │ └── web-worker │ ├── index.js │ └── webworker.html ├── this.MD ├── webpack.learning.js ├── 函数式编程.MD ├── 前端荣耀 └── 移动端踩坑之旅-ios下fixed、软键盘相关问题总结.md ├── 前端趋势.MD ├── 动画.MD ├── 后台.MD ├── 国际化.MD ├── 大屏展示.MD ├── 安全.MD ├── 小程序.MD ├── 微信.MD ├── 性能与异常上报.MD ├── 性能优化.MD ├── 技巧.MD ├── 数据结构算法.MD ├── 游戏.MD ├── 源码阅读.MD ├── 爬虫.MD ├── 算法.MD ├── 设计模式.MD ├── 跨域.MD ├── 面试.MD ├── 面试2.MD ├── 面试3.MD ├── 面试4.MD ├── 面试5.MD ├── 面试笔记.MD └── 面试笔记基础.MD /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | libin_Blog 4 | 5 | 6 | 7 | 8 | 9 | com.aptana.ide.core.unifiedBuilder 10 | 11 | 12 | 13 | 14 | 15 | com.aptana.projects.webnature 16 | 17 | 18 | 19 | 1517121199432 20 | 21 | 26 22 | 23 | org.eclipse.ui.ide.multiFilter 24 | 1.0-name-matches-false-false-node_modules 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /AMD-CMD-CommonJS.MD: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### [前端模块化详解(完整版)](https://juejin.im/post/5c17ad756fb9a049ff4e0a62#heading-7) 4 | ### [前端模块化之AMD与CMD原理(附源码)](https://juejin.im/post/5c3592b26fb9a049aa6f4456) 5 | ### [一览js模块化:从CommonJS到ES6](https://juejin.im/post/5c2053bd6fb9a049f23cc315) 6 | ### [CommonJS和ES6模块循环加载处理的区别](https://juejin.im/post/5c22f5696fb9a049e412bce6) 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /AST.MD: -------------------------------------------------------------------------------- 1 | ### [平庸前端码农之蜕变 — AST](https://juejin.im/post/5bfc21d2e51d4544313df666) 2 | ### [AST抽象语法树](https://juejin.im/post/5bff941e5188254e3b31b424) 3 | ## [前端与编译原理——用JS写一个JS解释器](https://segmentfault.com/a/1190000017241258) 4 | ### [AST 抽象语法树](http://jartto.wang/2018/11/17/about-ast/) 5 | ### [AST in JS](https://juejin.im/post/5c2714fb51882575f560503c) 6 | ### [实现一个简单的 JavaScript 编译器](https://juejin.im/post/5c6faa25e51d4501377ba82a) 7 | ### [精读《syntax-parser 源码》](https://juejin.im/post/5c7c7658f265da2db912888c) 8 | ### [高级前端基础-JavaScript抽象语法树AST](https://juejin.im/post/5c8d3c48f265da2d8763bdaf#heading-12) 9 | ### [[AST实战]从零开始写一个wepy转VUE的工具](https://juejin.im/post/5c877cd35188257e3b14a1bc) 10 | ### [通过分析AST自动重构three.js的老旧代码 ](https://github.com/hujiulong/blog/issues/10) 11 | 12 | ### [「译」什么是抽象语法树](https://juejin.im/post/5d05b794518825282e2c3802) 13 | ### [细谈 vue 核心- vdom 篇](https://juejin.im/post/5cab347fe51d456e7a303b3d) 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | ### [一个简单的例子看懂抽象语法树的魔力](https://juejin.im/post/5c860b2f5188257ddb6af8ff) 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Android-iOS.MD: -------------------------------------------------------------------------------- 1 | ### [H5页面监听Android物理返回键](https://juejin.im/post/5c0915795188250b064f4fa0) 2 | ### [JS监听手机物理返回键(及IOS微信端的bug)](https://juejin.im/post/5bf7c7b7e51d454c1c45d737) 3 | ### [小tips-一种移动端模拟实现返回拦截的方案](https://juejin.im/post/5c919cd75188252d5379db69) 4 | ### [微信中禁止网页下拉出现"网页由XXX提供" 【亲测有效】](https://juejin.im/post/5d090827e51d454fbe24a68c) 5 | 6 | --- 7 | ### [9102了,你还不会移动端真机调试?](https://juejin.im/post/5c947f5251882568396a6773) 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Animation.MD: -------------------------------------------------------------------------------- 1 | ### [炫酷的圆环加载及数字滚动效果(上)](https://juejin.im/post/5c1a5e4a518825678a7baf25) 2 | ### [记一次h5动画之旅](https://juejin.im/post/5c2b655051882504bd0e845f) 3 | ### [你知道的requestAnimationFrame【从0到0.1】](https://juejin.im/post/5c3ca3d76fb9a049a979f429) 4 | ### [React 写一个 spinner 圆形加载动画](https://juejin.im/post/5c3885296fb9a049e2323a6a) 5 | ### [学习 PixiJS — 粒子效果](https://juejin.im/post/5c466588518825246b0ff877) 6 | -------------------------------------------------------------------------------- /Axios.MD: -------------------------------------------------------------------------------- 1 | ### [记一次axios源码排查](https://juejin.im/post/5b9b7be8e51d450e704258a0) 2 | ## [axios 二次封装 api的统筹管理 配合async await实际项目中的运用](https://www.jianshu.com/p/6b626d72ea78) 3 | ### [axios源码分析——拦截器](https://juejin.im/post/5b272758e51d4558a04a2dbf) 4 | ### [Axios-源码分析](http://hejx.space/2017/08/25/Axios-%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/) 5 | ### [Vue+axios 实现http拦截及路由拦截](https://www.cnblogs.com/parkboyoung/p/6761863.html) 6 | ### [前端架构之vue+axios 前端实现登录拦截(路由拦截、http拦截)](https://juejin.im/post/5b791b8251882543057d8797) 7 | ### [Vue2学习小记-给Vue2路由导航钩子和axios拦截器做个封装](https://juejin.im/post/5a1550746fb9a045076f4fd2) 8 | ### [axios 前端实现登录拦截、登出、拦截器等功能](https://github.com/superman66/vue-axios-github) 9 | ### [前后端分离使用 Token 登录解决方案,登录拦截,权限控制](https://github.com/libin1991/libin_Blog/issues/621) 10 | ### [axios二次封装学习](https://github.com/libin1991/libin_Blog/issues/605) 11 | ### [vue+axios 前端实现登录拦截](https://github.com/libin1991/libin_Blog/issues/612) 12 | ### [axios源码分析——取消请求 ](https://github.com/libin1991/libin_Blog/issues/575) 13 | ### [axios源码分析——拦截器](https://github.com/libin1991/libin_Blog/issues/574) 14 | ### [vue中Axios的封装和API接口的管理](https://juejin.im/post/5b55c118f265da0f6f1aa354) 15 | ## [前端实现文件下载和拖拽上传](https://juejin.im/post/5bf543d851882518eb1f5cc4) 16 | ## [axios 核心源码解读](https://juejin.im/post/5c01126d6fb9a049fd0f9405) 17 | ## [【手把手带你撸一个接口测试工具】第二步, 基于ElementUI实现前端布局](https://juejin.im/post/5c0689476fb9a049ff4de4e0) 18 | ## [JS HTTP 请求库哪家强?Axios,Request,Superagent,Fetch 还是 Supertest](https://juejin.im/post/5c10fc4de51d455bea33a5e4#heading-6) 19 | -------------------------------------------------------------------------------- /BUG.MD: -------------------------------------------------------------------------------- 1 | ### [H5拍照上传填坑汇总](https://juejin.im/post/5bd705abf265da0a8d36dbdc) 2 | ### [ios 最新系统bug与解决——微信公众号中弹出键盘再收起时,原虚拟键盘位点击事件无效](https://juejin.im/post/5c07442f51882528c4469769) 3 | 4 | ### [一文彻底解决iOS中键盘回落后留白问题](https://juejin.im/post/5cff9601f265da1bc5525aae) 5 | 6 | 7 | ```js 8 | window.addEventListener('resize', function() { 9 | if( 10 | document.activeElement.tagName === 'INPUT' || 11 | document.activeElement.tagName === 'TEXTAREA'|| 12 | document.activeElement.getAttribute('contenteditable')=='true' 13 | ) { 14 | window.setTimeout(function() { 15 | if('scrollIntoView' in document.activeElement) { 16 | document.activeElement.scrollIntoView(); 17 | } else { 18 | document.activeElement.scrollIntoViewIfNeeded(); 19 | } 20 | }, 0); 21 | } 22 | }); 23 | ``` 24 | ### [修复苹果iOS 原生键盘遮挡input框](https://juejin.im/post/5b0401b2f265da0b71569ca0#comment) 25 | -------------------------------------------------------------------------------- /Babel.MD: -------------------------------------------------------------------------------- 1 | ### [一口(很长的)气了解 babel](https://juejin.im/post/5c19c5e0e51d4502a232c1c6) 2 | ### [深入Babel,这一篇就够了](https://juejin.im/post/5c21b584e51d4548ac6f6c99#heading-8) 3 | ### [webpack - babel 篇](https://juejin.im/post/5bfe541bf265da6179748834) 4 | ### [从零开始写Babel插件](http://eux.baidu.com/blog/fe/how-to-write-babel-plugin) 5 | ### [教你如何编写Babel插件](https://juejin.im/post/5c0698e36fb9a049cd53f8a8) 6 | ### [[实践系列]Babel原理](https://juejin.im/post/5c3beaee6fb9a04a027a9641) 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Banner.MD: -------------------------------------------------------------------------------- 1 | ### [myFocus焦点图插件](https://github.com/logan70/myfocus) 2 | ### [CSS图片切换特效](https://github.com/logan70/css3-banner) 3 | ### [商城轮播图](https://github.com/logan70/js-slider) 4 | -------------------------------------------------------------------------------- /Blog.MD: -------------------------------------------------------------------------------- 1 | ### [http://www.fly63.com/tool](http://www.fly63.com/tool) 2 | 3 | 4 | ## CSS 5 | ### [https://qishaoxuan.github.io/css_tricks/](https://qishaoxuan.github.io/css_tricks/) 6 | ### [前端蜗牛路](https://ggwork.github.io/) 7 | ### [Star 就是最大的鼓励👏👏👏](https://github.com/z2014/Blog) 8 | ### [https://jsonz1993.github.io/](https://jsonz1993.github.io/) 9 | ### [【译】30 Seconds of ES6 (一)](https://juejin.im/post/5c458913e51d4542253fee3a) 10 | ### [番茄技术小栈](http://fanqieto.top/) 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | --- 20 | ## JS 21 | ### 👍👍👍👍👍[打造最好的面试图谱](https://yuchengkai.cn/docs/) 22 | ### [https://qishaoxuan.github.io/js_tricks/](https://qishaoxuan.github.io/js_tricks/) 23 | --- 24 | # [吊炸天简历http://resume.caodj.cn/](http://resume.caodj.cn/) 25 | ### [吊炸天git@github.com:libin1991/resume.git](https://github.com/libin1991/resume) 26 | ### [http://alloween.top/](http://alloween.top/) 27 | ### [全栈工程师自我修养](https://segmentfault.com/blog/jianshu) 28 | ### [https://blog.seosiwei.com/file](https://blog.seosiwei.com/file) 29 | --- 30 | ### [OBKoro1前端积累](http://obkoro1.com/web_accumulate/) 31 | # [全栈工程师自我修养](https://segmentfault.com/blog/jianshu) 32 | # [百度FEX](http://fex.baidu.com/) 33 | # [百度EUX](http://eux.baidu.com/) 34 | # [百度EFE](http://efe.baidu.com/) 35 | # [淘宝FED](http://taobaofed.org/) 36 | # [腾讯AlloyTeam](http://www.alloyteam.com/) 37 | # [凹凸实验室](https://aotu.io/index.html) 38 | # [360奇舞团](https://75team.com/) 39 | # [前端观察](https://www.qianduan.net/) 40 | ### [前端练手小项目](https://github.com/libin1991/Web-Project) 41 | ## [木易杨,网易高级前端工程师](https://github.com/yygmind/blog) 42 | ### [个人博客](https://github.com/chenjigeng/blog) 43 | ## [My-Code](https://github.com/HongqingCao/My-Code) 44 | ### [前端笔记](https://denzel.netlify.com/) 45 | ## [博客项目,求Star⭐️ http://obkoro1.com](https://github.com/libin1991/OBKoro1.github.io) 46 | ### [前端导航](https://github.com/webproblem/learning-article) 47 | ### [https://github.com/dwqs/blog](https://github.com/dwqs/blog) 48 | ### [记录成长的过程](https://github.com/berwin/Blog) 49 | ## [https://www.pandashen.com/](https://www.pandashen.com/) 50 | ## [张云龙](https://github.com/fouber/blog) 51 | ## [xingbofeng.github.io PWA](https://github.com/xingbofeng/xingbofeng.github.io/issues) 52 | # [某大厂面试题与解析(欢迎纠错,优化)](https://juejin.im/post/5be2fcd7f265da616d53aad0) 53 | # [kailian.github.io](http://kailian.github.io/) 54 | # [react + node + express + ant + mongodb 的简洁兼时尚的博客网站](https://juejin.im/post/5bf60810f265da6124151529) 55 | # [JavaScript深入之史上最全](https://juejin.im/post/5bfe8fc5e51d4514e0515b90) 56 | ## [Jartto's blog](https://github.com/chenfengyanyu/source) 57 | ## [木易杨](https://github.com/yygmind/blog) 58 | # [http://jartto.wang/all-archives/](http://jartto.wang/all-archives/) 59 | # [https://suisuijiang.com/](https://suisuijiang.com/) 60 | ## [https://blog.hhking.cn/](https://blog.hhking.cn/) 61 | # [https://h.lishaoy.net/](https://h.lishaoy.net/) 62 | # [王玉略的个人网站](http://www.wangyulue.com/archives/) 63 | ## [Modeng(摩登)](https://www.modenng.com/) 64 | ## [一起学前端](https://github.com/ljianshu/Blog) 65 | --- 66 | ### [https://github.com/libin1991/Interviewproject](https://github.com/libin1991/Interviewproject) 67 | ### [https://github.com/fairyly/Interviewproject](https://github.com/fairyly/Interviewproject) 68 | ### [https://github.com/fairyly/mynodejs](https://github.com/fairyly/mynodejs) 69 | --- 70 | -------------------------------------------------------------------------------- /Canvas.MD: -------------------------------------------------------------------------------- 1 | ### [使用 Canvas 生成公众号头图](https://juejin.im/post/5b72d73ee51d4566205fe67b) 2 | # [Canvas实用库Fabric.js使用手册](https://juejin.im/post/5c4591bee51d4507fb1d79be) 3 | ### [玩转「Canvas」](https://juejin.im/post/5bfba4d6e51d452fd80f0f0d) 4 | 5 | 6 | 7 | ## [h5使用canvas画布实现手势解锁](http://www.wuhuan.me/2018/11/02/canvas-picture-unlock/) 8 | ### [学习 canvas 的 globalCompositeOperation 做出的神奇效果](https://juejin.im/post/5b87de766fb9a01a175dce1e) 9 | ### [canvas像素点操作 —— 视频绿幕抠图](https://juejin.im/post/5b9722045188255c971fbfe0) 10 | ## [svg、canvas、css3d实现数据可视化(伪3D效果)](https://juejin.im/post/5b690a66f265da0f820254bd) 11 | ### [canvas像素点获取 —— 拾色器、放大器](https://juejin.im/post/5b95d5df6fb9a05d11176489) 12 | ### [canvas绘图之钟表](https://juejin.im/post/5b95cfef6fb9a05d1a12b8db) 13 | ### [用 canvas 的 getImageData 做点有趣的事](https://juejin.im/post/5ba06596f265da0acc7957e4) 14 | ### [通过canvas生成图片并保存到本地](https://juejin.im/post/5b9a3113f265da0aaa04fffc) 15 | ### [小程序导出朋友圈海报详细记录](https://juejin.im/post/5b9dab12f265da0acf0ad156) 16 | ### [【5星级】html2img小程序生成图片库,轻松通过 json 方式绘制一张可以发到朋友圈的图片](https://github.com/libin1991/Painter) 17 | ### [html2canvas-实现页面截图](https://juejin.im/post/5bcdac8d6fb9a05d3017910d) 18 | ### [小哥哥~手把手教你如何绘制一辆会跑车](https://juejin.im/post/5bc34db36fb9a05d36350315) 19 | ### [canvas生成海报大小错误、模糊以及跨域的问题](https://juejin.im/post/5bddac7d6fb9a049ee7fe452) 20 | ### [Canvas环形倒计时组件](https://juejin.im/post/5beabe026fb9a049b829ff6f) 21 | ## [图片纯前端JS压缩的实现](https://juejin.im/post/5bec3c6cf265da614312a0fa) 22 | ## [用canvas实现一个vue弹幕组件](https://juejin.im/post/5bfe3f7c6fb9a04a0c2e250b) 23 | ## [canvas压缩图片以及卡片制作](https://juejin.im/post/5c03bd0ce51d4524d9252e1e) 24 | # [Canvas 实现画中画动画效果--网易娱乐年度盘点H5动画解密](https://juejin.im/post/5bfbcb1e5188252e8966a298#comment) 25 | # [前端谈谈实现五子棋](https://juejin.im/post/5c18fc9fe51d4570e5715ee2) 26 | ### [Cocos Creator实战-使用粒子资源实现屏幕点击效果](https://juejin.im/post/5c1f6536e51d45206d12422d) 27 | ### [Web数据可视化-手把手教你实现热力图](https://juejin.im/post/5c37ed836fb9a049d81c0f82) 28 | ## [前端庆祝节日的方法](https://juejin.im/post/5c2b766051882575f560553b) 29 | ### [又双叒叕是一个 canvas 动画](https://juejin.im/post/5c460109e51d4505171c7001) 30 | ### [解锁canvas导出图片跨域的N种姿势~](https://juejin.im/post/5c46b58cf265da617265c876) 31 | -------------------------------------------------------------------------------- /Chrome.MD: -------------------------------------------------------------------------------- 1 | ### [20个Chrome DevTools调试技巧](https://blog.fundebug.com/2018/08/22/art-of-debugging-with-chrome-devtools/) 2 | ## [V8引擎中的排序](https://juejin.im/post/5c472940e51d455249762bef#heading-8) 3 | ### [Chrome 调试工具的一些高阶功能](http://eux.baidu.com/blog/fe/Chrome%E8%B0%83%E8%AF%95%E5%B7%A5%E5%85%B7%E7%9A%84%E4%B8%80%E4%BA%9B%E9%AB%98%E9%98%B6%E5%8A%9F%E8%83%BD) 4 | ### [chorme devtools使用详解——Elements篇](https://juejin.im/post/5b8e4820f265da438151b753) 5 | ### [如何使用原生 JavaScript 构建简单的 Chrome 扩展程序](https://juejin.im/post/5b98a58b6fb9a05cec4d92e0) 6 | ### [网站性能调优开发工具: Lighthouse, Puppeteer 以及进阶部分丨 Google 开发者大会 2018](https://juejin.im/post/5ba73d1de51d450e551a0d08) 7 | ### [如何实现一个 鼠标点击特效的 chrome插件](https://juejin.im/post/5bea918c51882516b9377c4f) 8 | ### [图解浏览器的基本工作原理](https://zhuanlan.zhihu.com/p/47407398) 9 | ### [Puppeteer E2E测试入门](https://juejin.im/post/5bffb344e51d45378d0d39f4) 10 | ### [chrome devtools使用详解——Performance](https://juejin.im/post/5c009115f265da612859d8e2) 11 | ### [Chrome 72 开发者工具新特性](https://juejin.im/post/5c06878c5188257c3045d003) 12 | ### [[萌]chrome性能分析面板](https://juejin.im/post/5c05b95e6fb9a049e307dd37) 13 | ### [浏览器开发者工具详解](https://juejin.im/post/5c08b1826fb9a049a81f1d49) 14 | ### [【译】你不知道的Chrome调试工具技巧 第一天:console中的'$'](https://juejin.im/post/5c09a80151882521c81168a2) 15 | ### [【译】你不知道的 Chrome 调试工具技巧 第九天:给 console 计时](https://juejin.im/post/5c11809ef265da61141c76f1) 16 | ### [【译】你不知道的 Chrome 调试工具技巧 第十二天:忍者日志打印!(the ninja logs)](https://juejin.im/post/5c16d943518825566d2365f3) 17 | ### [一篇文章教你顺利入门和开发chrome扩展程序(插件)](https://juejin.im/post/5c135a275188257284143418) 18 | ### [Chrome插件开发先看这篇:如何实现一键上班赖皮](https://juejin.im/post/5c14e64a5188256e047d8e44) 19 | ### [【译】你不知道的 Chrome 调试工具技巧 第十四天:其他快捷键~](https://juejin.im/post/5c18b375f265da614e2c02e1) 20 | ### [【译】你不知道的 Chrome 调试工具技巧 第十三天:对象 & 方法](https://juejin.im/post/5c18b2d66fb9a049d235fc82) 21 | ### [JavaScriptCore全面解析](https://juejin.im/post/5c46ecec6fb9a049d1327821) 22 | ### [[译] Chrome 73 开发者工具新特性](https://juejin.im/post/5c493745e51d453211567ae8) 23 | 24 | 25 | 26 | --- 27 | 28 | ### [Video Speed Controller](https://chrome.google.com/webstore/detail/video-speed-controller/nffaoalbilbmmfgbnbgppjihopabppdk) 29 | 30 | Video Speed Controller ,一个可配置播放速度的 Chrome 插件,可配置快捷键,赖宅的我一般使用 D 来增加播放速度,特别提醒,该插件只支持 H5 播放器,Flash 是不支持的👀 比如某酷,对腾讯视频友好。Video Speed Controller 会将当前视频播放速度先是在左上角,Chrome 地址:https://chrome.google.com/webstore/detail/video-speed-controller/nffaoalbilbmmfgbnbgppjihopabppdkchrome.google.com/webstore/detai... 31 | 32 | 最后如果你听的是某人的演讲,建议倍数在 1.25 - 1.5,一个 2x 速度的煲剧党路过。 33 | 34 | 35 | -------------------------------------------------------------------------------- /Chrome插件.MD: -------------------------------------------------------------------------------- 1 | ### [快速给页面加上炫酷css3动画的chrome插件](https://github.com/libin1991/css3-animation-generator) 2 | ### [前端神器—Google Chrome Devtools细节详解](https://juejin.im/post/5b72a991518825615117717b) 3 | -------------------------------------------------------------------------------- /Cli.MD: -------------------------------------------------------------------------------- 1 | ### [手把手撸一个脚手架](https://juejin.im/post/5bec24ddf265da61171c4a34) 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Create-react-app.MD: -------------------------------------------------------------------------------- 1 | ### [create-react-app 源码解析之react-scripts](https://juejin.im/post/5af98aaf518825426d2d4142) 2 | ### [探索 create-react-app 源码](https://juejin.im/post/5af452fd518825671c0e96e5) 3 | ### [在 Create React App 中使用 CSS Modules](https://juejin.im/post/5c3c3df451882525153c2352#comment) 4 | ### [扔掉Create React App,打造你自己的React生成工具!](https://mp.weixin.qq.com/s/76007EbaArO8tp2Lzb6dVA) 5 | -------------------------------------------------------------------------------- /Debug.MD: -------------------------------------------------------------------------------- 1 | ### [JS 反混淆](http://jartto.wang/2017/10/31/js-anti-aliasing/) 2 | ### [移动端真机调试指南](https://aotu.io/notes/2017/02/24/Mobile-debug/) 3 | ### [9102了,你还不会移动端真机调试?](https://juejin.im/post/5c947f5251882568396a6773) 4 | ### [一文读懂H5移动开发调试技巧](https://juejin.im/post/5c0e34dce51d453595324d1e) 5 | ### [JS 反混淆](http://jartto.wang/2017/10/31/js-anti-aliasing/) 6 | ### [Eruda 一个被人遗忘的调试神器](https://juejin.im/post/5c15b7b7f265da613e2223c9) 7 | ### [慎用try catch](https://juejin.im/post/5c17dad7f265da611510b63f) 8 | ### [驳《慎用 try catch》](https://juejin.im/post/5c199882f265da617464c745) 9 | ## [在控制台使用debugger断点调试移动端h5页面的js代码](https://www.mobiledebug.com/Help/debugger.shtml) 10 | ## [https://www.mobiledebug.com/](https://www.mobiledebug.com/) 11 | ### [【译】远程调试 iOS Safari](http://scarletsky.github.io/2019/01/10/wireless-remote-debugging-with-safari-on-ios/) 12 | ### [如何优雅地查看 JS 错误堆栈?](https://juejin.im/post/5c3d5929f265da6174650f93) 13 | ### [记一次网页内存溢出分析及解决实践](https://juejin.im/post/5c3dce07e51d4551e960d840) 14 | 15 | 16 | 17 | 18 | 19 | ### [Fiddler助力微信开发调试](https://juejin.im/post/5d54b884e51d4561a60d9dd0) 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Docker.MD: -------------------------------------------------------------------------------- 1 | ### [9102 年了,学点 Docker 知识](https://juejin.im/post/5c2c69cee51d450d9707236e) 2 | -------------------------------------------------------------------------------- /ES6.MD: -------------------------------------------------------------------------------- 1 | ## [JavaScript模块化原理浅析](https://juejin.im/post/5c1083186fb9a049ec6aed5e) 2 | ## [如何在 ES5 环境下实现一个const ?](https://juejin.im/post/5c2042e95188255e9b620964) 3 | ### [ES6的Set和Map数据结构,由你制造](https://juejin.im/post/5acc57eff265da237f1e9f7c) 4 | ### [ES6中常用的10个新特性讲解](https://juejin.im/post/5b1d1fd6f265da6e410e137c) 5 | ### [ES6面试、复习干货知识点汇总(全)](https://juejin.im/post/5c061ed2f265da61357258ee) 6 | ### [简单了解ES6/ES2015 Symbol() 方法](http://www.zhangxinxu.com/wordpress/2018/04/known-es6-symbol-function/) 7 | ### [你知道为什么会有 Generator 吗](https://juejin.im/post/5adae8246fb9a07aa541e150) 8 | ### [双向绑定Proxy比defineproperty优劣如何?](https://juejin.im/post/5acd0c8a6fb9a028da7cdfaf) 9 | ### [ES6 系列之 let 和 const](https://juejin.im/post/5b0238f66fb9a07aca7a74ba#comment) 10 | ### [ES6 系列之模板字符串](https://juejin.im/post/5b0e2e1cf265da08e12f11fd) 11 | ### [ES6-Generator 函数 和 async 函数](https://juejin.im/post/5b1751d551882513756f0bdc) 12 | ### [ES2018 新增特性清单](https://juejin.im/post/5b353534f265da595f0d3f7e) 13 | ### [ES9已经来了 Are you ready?](https://juejin.im/post/5b685ed1e51d4533f52859e8) 14 | ### [ES6核心,值得驻足花一天时间来学习](https://juejin.im/post/5b6d6f8ae51d453509566974#heading-25) 15 | ### [ES6 系列之 Generator 的自动执行](https://juejin.im/post/5bc88f4ef265da0af1617162) 16 | ### [ES6 完全使用手册](https://juejin.im/post/5bfe05505188252098022400#heading-52) 17 | ### [ES6/ES7/ES8/ES9资料整理(个人整理)](https://juejin.im/post/5c02b106f265da61764aa0c1#heading-0) 18 | ### [JavaScript 遍历、枚举与迭代的骚操作(下篇)](https://juejin.im/post/5c07b764e51d450c457199f9) 19 | ### [使用 ES6 Proxy 代理的一些问题记录](https://juejin.im/post/5c064a0ae51d451dce59ceed) 20 | ### [菜鸟也谈js(一)——ES6解构对象篇](https://juejin.im/post/5c0b1aaa6fb9a049c30b0ee5) 21 | ### [ES6 Symbol之浅入解读😂](https://juejin.im/post/5c124eb76fb9a049ee8054c6) 22 | ### [深入理解Javascript之Module](https://juejin.im/post/5c20f3cee51d450d9706f65d) 23 | ### [继承 JavaScript 类中的静态属性](https://juejin.im/post/5c2217fc6fb9a049b348039d) 24 | ### [浅谈class私有变量](https://juejin.im/post/5c25faf3f265da61380f4b17) 25 | ### [使用ES6的新特性Proxy来实现一个数据绑定实例](https://juejin.im/post/5c34a86a6fb9a049f81976d8) 26 | ### [[前端怪谈_1] 从 for of 聊到 Generator](https://juejin.im/post/5c40484bf265da61171cfb4d) 27 | ### [使用 Proxy 来监测 Javascript 中的类](https://juejin.im/post/5c484b76e51d45522b4f5f7d#heading-4) 28 | -------------------------------------------------------------------------------- /ESLint.MD: -------------------------------------------------------------------------------- 1 | ### [ESLint 工作原理探讨](https://zhuanlan.zhihu.com/p/53680918) 2 | -------------------------------------------------------------------------------- /Easy-mock.MD: -------------------------------------------------------------------------------- 1 | ### [浅谈 Easy-mock 最好的备胎没有之一](https://juejin.im/post/5bfb36a2f265da61476fe444) 2 | -------------------------------------------------------------------------------- /Electron.MD: -------------------------------------------------------------------------------- 1 | ### [[electron]终极奥义 五千字教程丢给你](https://juejin.im/post/5ba06b67f265da0ae343e89c) 2 | ### [你不知道的 Electron (一):神奇的 remote 模块](https://juejin.im/post/5ba09712e51d450e9d648138) 3 | ## [从零开始用 electron 手撸一个截屏工具](https://juejin.im/post/5bbac5cee51d450e7042ad2c) 4 | ### [前端构造桌面级应用(QQ音乐)](https://juejin.im/post/5bfcb417e51d452e5e70ea8a) 5 | ## [用于Electron/Nodejs的数据持久缓存库](https://juejin.im/post/5c1728dd518825741e7c0eab) 6 | ### [Electron构建跨平台应用Mac/Windows/Linux](https://juejin.im/post/5c46ab47e51d45522b4f55b1) 7 | ### [Electron工程踩坑记录](https://juejin.im/post/5c4856cdf265da61620db538) 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Event-Loop.MD: -------------------------------------------------------------------------------- 1 | ``` 2 | setTimeout(function () { 3 | console.log(1); 4 | }, 0); 5 | 6 | Promise.resolve().then(function () { //必须通过then才能执行 7 | console.log(2); 8 | }) 9 | 10 | new Promise(function (resolve) { 11 | console.log(3); 12 | }); 13 | 14 | console.log(4); 15 | 16 | 17 | 18 | 3421 19 | ``` 20 | ### [JS 总结之事件循环](https://juejin.im/post/5c244b33e51d45593b4bbd3d) 21 | ### [浏览器事件环和Node事件环不得不说的故事!](https://juejin.im/post/5b5f365e6fb9a04fa8673f97) 22 | ### [hey,你的Event Loop](https://juejin.im/post/5b63b4cb6fb9a04fb4017f5a) 23 | ### [麻烦把JS的事件环给我安排一下!!!](https://juejin.im/post/5b69b07d6fb9a04f86065596) 24 | ### [JavaScript运行机制:event-loop](https://juejin.im/post/5b6aea43f265da0f894b956b) 25 | ### [一次弄懂Event Loop(彻底解决此类面试问题)](https://juejin.im/post/5c3d8956e51d4511dc72c200) 26 | ### [浏览器与Node的事件循环(Event Loop)有何区别?](https://juejin.im/post/5c337ae06fb9a049bc4cd218) 27 | ### [JS 事件机制 Event Loop](https://juejin.im/post/5c48380f5188252533160295) 28 | ### [浅析JavaScript的事件循环机制](https://juejin.im/post/5caaad5ce51d452b270ec317) 29 | -------------------------------------------------------------------------------- /Express.MD: -------------------------------------------------------------------------------- 1 | ### [express中间件,了解一下](https://juejin.im/post/5c10b5176fb9a049af6d1e1e) 2 | 3 | 4 | -------------------------------------------------------------------------------- /Flutter.MD: -------------------------------------------------------------------------------- 1 | ### [Hummingbird: 在Web上运行Flutter应用](https://juejin.im/post/5c07c3bbe51d451dee52bb75) 2 | ### [vscode快速构建Flutter项目+热加载调试](https://juejin.im/post/5c08b02e6fb9a049ec6addea) 3 | ### [手把手教你编译Flutter engine](https://juejin.im/post/5c24acd5f265da6164141236) 4 | ### [如何实现一个简单的雨滴动画?手把手告诉你](https://juejin.im/post/5c24a5acf265da613572a294) 5 | ### [Flutter 44集免费基础视频教程](https://juejin.im/post/5c452bac6fb9a049af6d919a) 6 | ### [用前端 最舒服的躺姿 "搞定" Flutter (组件篇)](https://juejin.im/post/5c41af466fb9a04a0e2d7d51) 7 | ### [移动跨平台技术方案总结](https://juejin.im/post/5c469f56e51d456e4138f911) 8 | ### [bugly的flutter版已完成,欢迎使用](https://juejin.im/post/5c45676c518825255008057f) 9 | ### [基于 Flutter 的CityPickers 城市选择器](https://juejin.im/post/5c642830e51d45016463781f) 10 | -------------------------------------------------------------------------------- /Git.MD: -------------------------------------------------------------------------------- 1 | ### [上传项目到 GitHub:如何用同一个 github 帐号在两台电脑上同步开发?/ 如何协同开发?](https://blog.csdn.net/zeqiao/article/details/75124532) 2 | ## [Github 排名](https://gitstar-ranking.com/) 3 | ### [码云代码克隆检测工具](https://copycat.gitee.com/) 4 | ### [打开Git的正确姿势](https://juejin.im/post/5c2743f7e51d45673971ce6c) 5 | ### [Git 必知必会](https://zhuanlan.zhihu.com/p/30355251) 6 | ### [Git 详细教程](https://juejin.im/entry/59b22efb6fb9a024a04b3726#_label3_2_3_2) 7 | ### [更优雅的使用 Git](https://juejin.im/post/5af152c1518825673e359539) 8 | ### [Git原理与高级使用](https://juejin.im/post/5ac9becb518825556f55b360) 9 | ### [实战笔记:Jenkins打造强大的前端自动化工作流](https://juejin.im/post/5ad1980e6fb9a028c42ea1be) 10 | ### [GitHub常用命令](https://shimo.im/docs/m2m3ZhdmJqgXY7JA) 11 | ### [git基本操作](https://juejin.im/post/5ae072906fb9a07a9e4ce596) 12 | ### [您必须知道的 Git 分支开发规范](https://juejin.im/post/5b4328bbf265da0fa21a6820) 13 | ### [规范 commit 与 changelog 生成](https://github.com/Mcbai/Blog/issues/19) 14 | ### [版本管理工具git的使用总结](https://www.imooc.com/article/251132) 15 | ### [Git 的 4 个阶段的撤销更改](https://mp.weixin.qq.com/s/_fbkqgEtYGxttWWip8Esjw) 16 | ### [超详实Git简明教程与命令大全](https://juejin.im/post/5bd2a0d8e51d457a4e0d4fd5) 17 | ### [利用emoji让的 git commit 生动清晰起来](https://juejin.im/post/5bf8f5fe518825158c533e22#comment) 18 | ### [Git常用操作总结](https://aotu.io/notes/2015/11/17/Git-Commands/) 19 | ### [花点时间顺顺Git(上)](https://mp.weixin.qq.com/s?__biz=MzU0OTExNzYwNg==&mid=2247484483&idx=1&sn=db181ee210f9490379af3e4a74f0cde8&chksm=fbb58f8accc2069cbe9afda4fcf0222791aee3eefa56e3471d05f4ca7390464ea2ab66e472a0&token=942885247&lang=zh_CN&rd2werd=1#wechat_redirect) 20 | ### [花点时间顺顺Git(下)](https://mp.weixin.qq.com/s/K7004_PVFW0kj8vcFh0s6Q) 21 | ### [Gitlab-CI 初级篇 - Gitlab Runner](https://juejin.im/post/5c227af6e51d452baa77d473) 22 | ### [git rebase](https://yrq110.me/post/tool/git-rebase-submodule-and-flow/) 23 | # [关于高效、高质和高产](https://juejin.im/post/5c2f2fd66fb9a049ff4e43f0) 24 | ## [2018(农历年)封山之作,和我一起嚼烂Git(两万字长文)](https://juejin.im/post/5c33f49de51d45523070f7bb#comment) 25 | 26 | 27 | 28 | --- 29 | ### [github emoji 表情列表](https://github.com/caiyongji/emoji-list) 30 | -------------------------------------------------------------------------------- /GraphQL.MD: -------------------------------------------------------------------------------- 1 | ### [GraphQL 的入门指南](https://segmentfault.com/a/1190000017851838) 2 | ### [GraphQL 初学者指南](https://juejin.im/post/5c32119651882525a50bb436) 3 | -------------------------------------------------------------------------------- /HTML.MD: -------------------------------------------------------------------------------- 1 | ### [👍👍👍如何在 Web 关闭页面时发送 Ajax 请求beforeunload和unload](https://juejin.im/post/5c7e541b6fb9a049e06415a5) 2 | ### [浏览器是如何解析html的?](https://juejin.im/post/5c1dde33f265da61776bf49a) 3 | ## [chrome window.open 弹窗在双屏情况下left居中定位异常分析](https://juejin.im/post/5c49354de51d45227a466980) 4 | ## [这应该是你见过的最全前端下载总结,下载保存](https://juejin.im/post/5c3c4b3551882524a5420119) 5 | ### [HTML5拍照、摄像机功能实战](https://juejin.im/post/5c4916c251882524fe52cf5e) 6 | ### [深入浅出浏览器渲染原理](https://juejin.im/post/5c24d736f265da614b120d4a) 7 | ## [Webnovel 不用照顾 Edge 浏览器性能?想多了!](https://juejin.im/post/5c499f3cf265da615f77986a) 8 | ### [合适的meta,你选对了吗?](https://juejin.im/post/5c08bb31518825371057fcd0) 9 | # [HTML5中手势原理分析与数学知识的实践](https://juejin.im/post/5c2ecd2ee51d45517334489e) 10 | ### [那些你不知道的meta标签](https://juejin.im/post/5c288546e51d451a6b51554a) 11 | ### [你应该要知道的重绘与重排](https://juejin.im/post/5c0c7f28f265da612e2875de) 12 | ### [浏览器重绘(reflow)重排(repaint)与优化[浏览器机制]](https://juejin.im/post/5c15f797f265da61141c7f86) 13 | ## [js如何读取excel文件,绘制echarts图形。](https://juejin.im/post/5c15e1a6e51d4571a1577973) 14 | ## [js读取excel文件,绘制echarts图形---数据处理](https://juejin.im/post/5c15f3055188254caf189baf) 15 | ### [前端接受后端文件流并下载的几种方法](https://juejin.im/post/5c1610cae51d455c627a967e) 16 | ### [记一次生成pdf的经历](https://juejin.im/post/5c122a766fb9a049fd0fb813) 17 | ### [2018年前端面试总结](https://juejin.im/post/5bee888fe51d4557fe34e356) 18 | ### [Canvas 实现画中画动画效果--网易娱乐年度盘点H5动画解密](https://juejin.im/post/5bfbcb1e5188252e8966a298#comment) 19 | ### [[译] 究竟什么是DOM?](https://juejin.im/post/5c0a2ea4f265da616c656ace) 20 | ### [移动端页面自定义input唤起键盘return,换行键为搜索](https://juejin.im/post/5c09ec23518825653a233a38) 21 | ### [移动端适配总结](https://juejin.im/post/5c0dd7ac6fb9a049c43d7edc) 22 | ### [DOM操作成本到底高在哪儿?](https://juejin.im/post/5c1069a16fb9a049e0632fb6) 23 | ### [你(可能)不知道的web api](https://juejin.im/post/5c1606d9f265da613d7bf7a4) 24 | ### [一个表情引发的思考](https://mp.weixin.qq.com/s?__biz=MzUxMDYxNTgwMA==&mid=2247484243&idx=1&sn=1a8c021816f01f22571fe659e4fc0d1a&chksm=f9010ac4ce7683d2a3452a5278f5528a5a6da8a54173c1ea32269396e79b2aa1b83b77d11dc2&token=1735694303&lang=zh_CN#rd) 25 | ## [HTML5 Audio的兼容性问题和优化](https://mp.weixin.qq.com/s?__biz=MzUxMDYxNTgwMA==&mid=2247484212&idx=1&sn=561ecda7a649360239952fff0869fd75&chksm=f9010aa3ce7683b51da033148b6d98d76eefffb09a786cf62fef359f23fae221ff12b078fb6e&token=1735694303&lang=zh_CN#rd) 26 | ## [HTML5中Audio使用踩坑汇总](https://juejin.im/post/5c17a2886fb9a049e7020593) 27 | ### [网页后退不刷新的N种解决方案](https://github.com/RicardoCao-Biker/RICO-BLOG/issues/17) 28 | ### [又双叒叕是一个动态简历](https://juejin.im/post/5c1fd3f1f265da61171cb8bf) 29 | ### [也许你对 Fetch 了解得不是那么多(上)](https://juejin.im/post/5c2715ae6fb9a049a42f209f) 30 | ### [也许你对 Fetch 了解得不是那么多(下)](https://juejin.im/post/5c2c36626fb9a049b506eb94) 31 | ## [在单页应用中,如何优雅的监听url的变化](https://juejin.im/post/5c26ec2f51882501cd6f497a) 32 | ### [浏览器渲染原理(性能优化之如何减少重排和重绘)](https://juejin.im/post/5c35cf62f265da615e05a67d) 33 | # [滚动穿透问题的解决方案](https://juejin.im/post/5c2dc9cce51d45690a254b79) 34 | ### [二进制数组实战 - 纯前端导出Excel文件](https://juejin.im/post/5c31a5086fb9a04a102f6f50) 35 | ## [开源 UI 库中,唯一同时实现了大表格虚拟化和树表格的 Table 组件](https://juejin.im/post/5c41543a51882525da2656f9) 36 | ## [优化关键渲染路径](https://juejin.im/post/5c458bb9e51d4551e653aeb6) 37 | ## [chrome弹窗在双屏情况下left居中定位异常分析](https://juejin.im/post/5c49354de51d45227a466980) 38 | -------------------------------------------------------------------------------- /HTTP.MD: -------------------------------------------------------------------------------- 1 | ## [面试官问:你了解HTTP2.0吗?](https://juejin.im/post/5c0ce870f265da61171c8c66) 2 | ### [完全图解 HTTPS](https://juejin.im/post/5c441073e51d455226654d60) 3 | ### [前端之浏览器缓存,一次搞定](https://juejin.im/post/5c417993f265da61285a6075) 4 | ### [深入研究:HTTP2 的真正性能到底如何](https://juejin.im/post/5c2cba45e51d455fb310e18b) 5 | ### [一文读懂前端缓存](https://juejin.im/post/5c22ee806fb9a049fb43b2c5) 6 | ## [Post,Get接口傻傻分不清?](https://juejin.im/post/5c0e610be51d45707261b10a) 7 | ### [关于TLS/SSL协议](https://juejin.im/post/5c1a02a06fb9a049db7313c9) 8 | ### [看图学HTTPS](http://blog.liuxuan.site/2018/05/21/learn_https_through_photos/) 9 | ### [从头到尾谈一下HTTPS](https://juejin.im/post/5b2a4d2951882574ba42123f) 10 | ### [一站到底 ---前端基础之网络](https://juejin.im/post/5b3357556fb9a00e5a4b63df) 11 | ### [HTTPS 到底加密了什么?](http://web.jobbole.com/94866/) 12 | ### [前端也要懂Http缓存机制](https://juejin.im/post/5b70edd4f265da27df0938bc) 13 | ### [10 分钟快速入门:HTTP缓存](https://juejin.im/post/5c1daddb6fb9a049d37f15c4) 14 | ### [HTTP 缓存的那些事儿](https://juejin.im/post/5b7c6d5b51882542cc2f4722) 15 | ### [HTTP三种缓存方式](https://juejin.im/post/5b8d10c66fb9a019f82fc16e) 16 | ### [浏览器缓存技术介绍](https://juejin.im/post/5b9346dcf265da0aac6fbe57) 17 | ### [http请求头与响应头的应用](https://juejin.im/post/5b854ddef265da43635d9302) 18 | ### [http缓存与cdn缓存配置指南](https://juejin.im/post/5be3f486e51d45053d5c38ca) 19 | ### [浅谈浏览器缓存机制](https://juejin.im/post/5be4e76f5188250e8601b4a6) 20 | ### [浅聊HTTP缓存 (HTTP Cache)](https://juejin.im/post/5bf3c28ee51d4514df5b7625) 21 | ### [f5到底刷新了点什么,你知道吗](https://juejin.im/post/5bfcd79e6fb9a04a08215cf3) 22 | ## [缓存从入门到放弃](https://juejin.im/post/5bfe879a51882531b81b0891) 23 | ## [HTTP 缓存](https://aotu.io/notes/2016/09/22/http-caching/) 24 | ### [作为前端的你了解多少tcp的内容](https://juejin.im/post/5c078058f265da611c26c235) 25 | ### [Vue SPA 项目,浏览器和 nginx 反向代理缓存问题解决实方案](https://juejin.im/post/5c09cbb1f265da617006ee83) 26 | ### [浏览器缓存机制剖析](http://louiszhai.github.io/2017/04/07/http-cache/) 27 | ### [浅解强缓存和协商缓存](https://juejin.im/post/5c0891f35188252bf829dc47) 28 | ### [前端技术演进(二):前端与协议](https://juejin.im/post/5c137ee0e51d4530e83576f7#heading-6) 29 | ### [搞懂 HTTP 1.0 /1.1/2.0 协议差别 #18](https://github.com/RicardoCao-Biker/RICO-BLOG/issues/18) 30 | ### [深入浅出HTTPS工作原理](https://juejin.im/post/5c1913a46fb9a049db73119a) 31 | ### [前端必知必会HTTP请求系列](https://juejin.im/post/5c2db028f265da61273d8186) 32 | ### [海绵宝宝也懂的HTTPS](https://juejin.im/post/5c341549e51d45524860cf99) 33 | ## [从前端角度理解缓存](https://juejin.im/post/5c4044cd51882524f23032eb) 34 | ### [浅谈HTTP之URL](https://juejin.im/post/5c402c85f265da611b589a82) 35 | ### [实践这一次,彻底搞懂浏览器缓存机制](https://juejin.im/post/5c4528a6f265da611a4822cc) 36 | ### [浏览器缓存](https://juejin.im/post/5c46b7a06fb9a049ee80c8d6) 37 | ### [[实战验证] http缓存(无代理服务器)](https://juejin.im/post/5c47d1a1f265da61553b20fd) 38 | -------------------------------------------------------------------------------- /Hexo.MD: -------------------------------------------------------------------------------- 1 | ### [Hexo博客主题之hexo-theme-matery的介绍](https://blinkfox.github.io/2018/09/28/qian-duan/hexo-bo-ke-zhu-ti-zhi-hexo-theme-matery-de-jie-shao/) 2 | 3 | 4 | 5 | 6 | ### [hexo next主题深度优化](https://mmmmmm.me/archives/) 7 | ### [大道至简——Hexo简洁主题推荐](https://www.haomwei.com/technology/maupassant-hexo.html) 8 | ### [简洁轻便的博客平台: Hexo详解](https://blog.csdn.net/kingice1014/article/details/52924523) 9 | ### [Hexo博客主题推荐](https://www.jianshu.com/p/bcdbe7347c8d) 10 | ### [hexo的Next创建tags](https://blog.csdn.net/lcyaiym/article/details/76762105?locationNum=5&fps=1) 11 | ### [2018最新版Hexo博客Next主题6.0配置优化](https://blog.csdn.net/qq_32454537/article/details/79482896) 12 | ### [Hexo-NexT配置超炫网页效果](https://www.jianshu.com/p/9f0e90cc32c2) 13 | ### [梦魇小栈](https://github.com/ihoey/blog) 14 | ## [chunge16.github.io](https://github.com/chunge16/chunge16.github.io) 15 | ### [使用Hexo+Github一步步搭建属于自己的博客(基础)](https://www.cnblogs.com/fengxiongZz/p/7707219.html) 16 | ### [使用Hexo+Github一步步搭建属于自己的博客(进阶)](https://www.cnblogs.com/fengxiongZz/p/7707568.html) 17 | ### [手把手教你用Hexo+Github 搭建属于自己的博客](https://blog.csdn.net/gdutxiaoxu/article/details/53576018) 18 | ### [手把手教你用Hexo+Github 搭建属于自己的博客](https://blog.csdn.net/gdutxiaoxu/article/details/53576018) 19 | ### [2018最新版hexo+Github搭建个人博客教程(2018-1-22 更新)](https://blog.csdn.net/qq_32454537/article/details/79482908) 20 | ## [用Hexo + github搭建自己的博客 --- 再也不用羡慕别人了!](https://blog.csdn.net/Hoshea_chx/article/details/78826689) 21 | ## [Hexo个人免费博客(一) 从零到发布Github](https://blog.csdn.net/linshuhe1/article/details/52415449) 22 | ## [Hexo 最常用的几个命令](https://blog.ihoey.com/posts/Hexo/2015-08-28-hello-world.html) 23 | ### [Hexo NexT主题添加点击爱心效果](https://asdfv1929.github.io/2018/01/26/click-love/) 24 | ### [Hexo-NexT配置超炫网页效果](https://www.jianshu.com/p/9f0e90cc32c2) 25 | > 配置Deployment 26 | ### [Hexo 最常用的几个命令](https://blog.csdn.net/dxxzst/article/details/76135935) 27 | > 同样在_config.yml文件中,找到Deployment,然后按照如下修改: 28 | 29 | ### [如何使用Github+Hexo快速搭建个人博客](https://juejin.im/post/5c4dac03f265da613c0a2811) 30 | ``` 31 | deploy: 32 | type: git 33 | repo: git@github.com:yourname/yourname.github.io.git 34 | branch: master 35 | ``` 36 | > 比如我的仓库的地址是git@github.com:gdutxiaoxu/gdutxiaoxu.github.io.git,所以配置如下 37 | ``` 38 | deploy: 39 | type: git 40 | repo: git@github.com:gdutxiaoxu/gdutxiaoxu.github.io.git 41 | branch: master 42 | ``` 43 | > 写博客、发布文章 44 | > 新建一篇博客,执行下面的命令: 45 | ``` 46 | hexo new post "article title" 47 | ``` 48 | 新建一个页面,命名为tags。命令如下: 49 | ``` 50 | hexo new page "tags" 51 | ``` 52 | > 这时候在我的 电脑的目录下 F:\hexo\source\ _posts 将会看到 article title.md 文件 53 | 54 | > 用MarDown编辑器打开就可以编辑文章了。文章编辑好之后,运行生成、部署命令: 55 | ``` 56 | hexo g // 生成 57 | hexo s // 本地启动 58 | hexo d // 部署发布 59 | hexo clean //清除缓存文件 db.json 和已生成的静态文件 public 60 | 61 | 当然你也可以执行下面的命令,相当于上面两条命令的效果 62 | 63 | hexo d -g #在部署前先生成 64 | 65 | 注意需要提前安装一个扩展: 66 | npm install hexo-deployer-git --save 67 | ``` 68 | 69 | ``` 70 | # 本地预览 71 | hexo s 72 | 73 | # 删除旧的静态文件,即 public 文件 74 | hexo clean 75 | 76 | # 生成新的静态文件,即 public 文件(或者 hexo g) 77 | hexo generate 78 | 79 | # 部署到远程站点,即 GitHub(或者 hexo d) 80 | hexo deploye 81 | 82 | # 当然你也可以执行下面的组合命令 83 | hexo d -g 84 | ``` 85 | 86 | 87 | 88 | 89 | ### [hexo博客主题「paper」的设计与开发](https://juejin.im/post/5df4cc44e51d45581f5eebfd) 90 | -------------------------------------------------------------------------------- /Html2Canvas图像处理.MD: -------------------------------------------------------------------------------- 1 | ### [基于canvas生成海报](https://juejin.im/post/5bc099896fb9a05ce576c516) 2 | ### [数字图像处理-前端实现](https://juejin.im/post/5bcee8816fb9a05cdd2d45a1) 3 | ## [微信小程序前端生成图片用于分享朋友圈最终解决方案](https://www.jianshu.com/p/7d47e52de73c) 4 | ### [移动端js模拟截屏生成图片并下载功能的实现方案+踩坑过程](https://juejin.im/post/5c415691e51d45518d46eb9c) 5 | 6 | 7 | 8 | ``` 9 | 还有其他插件,例如dom-to-image、rasterizehtml,可以根据需求使用 10 | ``` 11 | ### [HTML截图-html2canvas使用记录](https://juejin.im/post/5d1820296fb9a07f070e41b2) 12 | 13 | 14 | 15 | 16 | ### html2canvas[高质量前端快照方案:来自页面的「自拍」](https://juejin.im/post/5df2e8ab6fb9a0163770816d) 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Hybrid.MD: -------------------------------------------------------------------------------- 1 | ### [Hybrid App技术解析 -- 实战篇](https://juejin.im/post/5b5e7ec3f265da0f87593f9b) 2 | ### [Android webview 与 js(Vue) 交互](https://juejin.im/post/5b7d30dfe51d4538b2046d63) 3 | ### [H5唤起APP指南(附开源唤端库)](https://juejin.im/post/5b7efb2ee51d45388b6af96c) 4 | ### [app中的webview通识篇(上)](https://juejin.im/post/5bf35ef26fb9a049bc4c438a) 5 | -------------------------------------------------------------------------------- /Img.MD: -------------------------------------------------------------------------------- 1 | ### [WebP图片兼容性处理](https://github.com/libin1991/libin_Blog/issues/670) 2 | ### [图片裁剪上传示例(node + react)](https://juejin.im/post/5c18995c51882569b02433ab) 3 | ### [JS中通过指定大小来压缩图片](https://juejin.im/post/5c1b4eac6fb9a049d441c520) 4 | ### [图片上传方案详解](https://juejin.im/post/5c2dd1855188257c30462962) 5 | ### [Blob/DataURL/canvas/image的相互转换](https://www.cnblogs.com/jyuf/p/7251591.html) 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /JS-excel.MD: -------------------------------------------------------------------------------- 1 | ### [二进制数组实战 - 纯前端导出Excel文件](https://juejin.im/post/5c31a5086fb9a04a102f6f50) 2 | ### [tableExport(table导出文件,支持json、csv、txt、xml、word、excel、image、pdf)](https://github.com/huanz/tableExport) 3 | ### [纯前端利用 js-xlsx 实现 Excel 文件导入导出功能示例](https://www.jianshu.com/p/74d405940305) 4 | ## [js如何读取excel文件,绘制echarts图形。](https://juejin.im/post/5c15e1a6e51d4571a1577973) 5 | ## [js读取excel文件,绘制echarts图形---数据处理](https://juejin.im/post/5c15f3055188254caf189baf) 6 | ## [js读取excel文件,绘制echarts图形---数据处理](https://juejin.im/post/5c15f3055188254caf189baf) 7 | ### [csv和excel读取和下载](https://juejin.im/post/5b1fdbcc5188257d571f2c62) 8 | ### [js-xlsx + handsontable + echarts实现excel上传编辑然后显示成图表](https://juejin.im/post/5b924d096fb9a05cf67a6971) 9 | ### [Vue实现导出excel表格](https://juejin.im/post/5abb7855518825555d475215) 10 | ### [前端实现导出数据到excel文件](https://blog.csdn.net/github_36704158/article/details/78145732) 11 | ### [js 实现纯前端将数据导出excel两种方式,亲测有效](https://blog.csdn.net/hhzzcc_/article/details/80419396) 12 | ### [纯前端导出微信通讯录到 Excel](https://juejin.im/post/5bebd0e5f265da61417120a9) 13 | 14 | ### [Vue中级指南-01 如何在Vue项目中导出Excel](https://juejin.im/post/5cb7e74df265da039a3d68a1) 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /JS-file.MD: -------------------------------------------------------------------------------- 1 | ### [js对文件和二进制操作的一些方法汇总](https://juejin.im/post/5c4913fe6fb9a049d9758deb) 2 | -------------------------------------------------------------------------------- /JS-pdf.MD: -------------------------------------------------------------------------------- 1 | ### [完美解决jspdf各种中文乱码问题](https://juejin.im/post/5c1bb46a5188252dcb310f9f) 2 | 3 | 4 | ### [Vue页面转Pdf实践](https://juejin.im/post/5d511620f265da03c23ec758) 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /JS.MD: -------------------------------------------------------------------------------- 1 | # [JavaScript中任意两个数加减的解决方案](https://juejin.im/post/5c435227e51d45518d46f22f) 2 | ### [Javascript 中的设计模式(四):行为设计模式](http://elevenbeans.github.io/2018/04/11/javascript-design-patterns-3/) 3 | ### [TouchEvent实现前端录音打分功能](https://juejin.im/post/5acec44451882579ef4f5654) 4 | ### [前端简洁并实用的工具类](https://juejin.im/post/5ad2d9a751882510fd401114) 5 | ### [JavaScript如何实现UTF-16编码转换为UTF-8编码——utfx.js源码解析](https://juejin.im/post/5ad35e3a6fb9a028c14ae93d) 6 | ### [理解DOM到底是什么](https://juejin.im/post/5c01e2b051882518eb1f785a) 7 | ### [ 只有 20 行的 JavaScript 模板引擎](https://juejin.im/post/5c0e5042f265da61524d3a43) 8 | ### [JavaScript强制类型转换的抽象操作](https://juejin.im/post/5c0f3f885188257abf1d55ee) 9 | ### [OMG,这些鲜为人知的JavaScript 特性!](https://segmentfault.com/a/1190000017303869#articleHeader3) 10 | ### [JS单行、多行文本字符去重和行去重](https://juejin.im/post/5c10b53f6fb9a049c9658940) 11 | ### [JavaScript骚操作之操作符](https://juejin.im/post/5c15dc47e51d457b00691be5) 12 | ## [【译】JavaScript的工作原理:内存管理和4种常见的内存泄漏](https://juejin.im/post/5c1737876fb9a049c43d935c) 13 | ### [JavaScript防抖节流原理](http://blog.poetries.top/2018/12/21/js-debounce/#at?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io) 14 | ### [JS与内存](https://juejin.im/post/5c189120f265da611204f194) 15 | ## [深度剖析0.1 +0.2===0.30000000000000004的原因](https://juejin.im/post/5c023084f265da613e21fb54) 16 | ## [如何解决0.1 +0.2===0.30000000000000004类问题](https://juejin.im/post/5c05dbfb5188251da07df3bc) 17 | ### [JS中如何理解浮点数?](https://juejin.im/post/5c22fcbe6fb9a049ba419d4c) 18 | ## [从标准原理出发理解 JavaScript 数值精度](https://juejin.im/post/5c3db8b7e51d45515817bdeb) 19 | ### [通过垃圾回收机制理解 JavaScript 内存管理](https://juejin.im/post/5c4409fbf265da616f703d5a) 20 | -------------------------------------------------------------------------------- /JSON.MD: -------------------------------------------------------------------------------- 1 | ### [JSON.stringify和 JSON.parse 中的代码小技巧](https://juejin.im/post/5b7fb6f951882542ef0ee1c0) 2 | ### [有意思的JSON.parse()、JSON.stringify()](https://juejin.im/post/5be5b9f8518825512f58ba0e) 3 | -------------------------------------------------------------------------------- /JWT.MD: -------------------------------------------------------------------------------- 1 | ### [JWT - just what?](https://www.bestvist.com/p/62) 2 | -------------------------------------------------------------------------------- /Koa.MD: -------------------------------------------------------------------------------- 1 | ### [聊聊 koa 中间件](https://juejin.im/post/5b5e780cf265da0f6b7713a8) 2 | ### [koa2+vue+axios搭建一个博客台管理系统之session踩坑](https://juejin.im/post/5b6f120ff265da283b563f5d) 3 | ### [Koa2 中间件原理解析 —— 看了就会写](https://juejin.im/post/5ba7868e6fb9a05cdf309292) 4 | ### [node进阶——之事无巨细手写koa源码](https://juejin.im/post/5ba48fc4e51d450e704277fa) 5 | ### [koa2核心源码浅析](https://juejin.im/post/5bbef6e9e51d450e482c2c90) 6 | ### [koa2 一网打尽(基本使用,洋葱圈,中间件机制和模拟,源码分析,核心点,生态)](https://github.com/HCThink/h-blog/blob/master/source/koa2/readme.md) 7 | ### [骚年,Koa和Webpack了解一下?](https://juejin.im/post/5c01f46c51882516d725ee51) 8 | ### [精简版 koa 简单实现](https://juejin.im/post/5c0b8a08f265da612c5db4ea) 9 | ### [从koa-session源码解读session原理](https://juejin.im/post/5c148fd551882530544f341f) 10 | ### [玩转Koa -- 核心原理分析](https://juejin.im/post/5c1631eff265da615f772b59) 11 | ### [玩转Koa -- koa-router原理解析](https://juejin.im/post/5c24c3b9e51d45538150f3ab#heading-10) 12 | ### [玩转Koa -- koa-bodyparser原理解析](https://juejin.im/post/5c3de636f265da6179750d2b) 13 | -------------------------------------------------------------------------------- /Linux.MD: -------------------------------------------------------------------------------- 1 | ### [方便好用的 tree](https://mp.weixin.qq.com/s/Prny3p7MAt34BrNBOW7dnw) 2 | ### [命令搜索Linux](http://cmd.alibt.top/) 3 | ### [学会使用 curl 命令](https://juejin.im/post/5c1da55b6fb9a049c84f709b) 4 | -------------------------------------------------------------------------------- /Mac.MD: -------------------------------------------------------------------------------- 1 | ### [Mac 福利:从前端入手,搞定 iCloud 自动同步 node_modules 的痛点](https://juejin.im/post/5c01166a6fb9a04a0378f2bf) 2 | 3 | 4 | ### [Mac OS 终端强化美化:iterm2 + zsh + oh~my~zsh 设置教程](https://www.cnblogs.com/toulanboy/p/9609365.html) 5 | ### [ITerm2配置-让你的mac命令行更加丰富高效](https://www.jianshu.com/p/405956cdaca6) 6 | 7 | 8 | ### [iterm2 Themes](https://github.com/ohmyzsh/ohmyzsh/wiki/Themes) 9 | 10 | -------------------------------------------------------------------------------- /Markdown.MD: -------------------------------------------------------------------------------- 1 | ### [如何使用marked.js使Markdown在网页上良好的展示(vue + element ui)](https://juejin.im/post/5be1469fe51d457c1f756a37) 2 | ### [基于Next.js脚手架实现仿掘金编辑器](https://juejin.im/post/5c10d0d0e51d45449970d3cd) 3 | -------------------------------------------------------------------------------- /Mobx.MD: -------------------------------------------------------------------------------- 1 | ### [Mobx如此简单](https://juejin.im/post/5c2f00c9f265da61764b04bc) 2 | -------------------------------------------------------------------------------- /Mock.MD: -------------------------------------------------------------------------------- 1 | ### [非常便捷的本地Mock](https://juejin.im/post/5bdbe92f6fb9a049bb7bc18f) 2 | ### [前端之数据模拟之Mock.js](https://juejin.im/post/5c1b02dde51d4529bf51f272) 3 | -------------------------------------------------------------------------------- /MongoDB.MD: -------------------------------------------------------------------------------- 1 | ### [MongoDB中常用语句](https://juejin.im/post/5bf020d3f265da61764a7a16) 2 | ### [mongodb想速成吗,这个系列教程你可以看看(1)](https://juejin.im/post/5ca0110ee51d45452a07916b) 3 | -------------------------------------------------------------------------------- /NPM.MD: -------------------------------------------------------------------------------- 1 | ### [vue插件开发、文档书写、github发布、npm包发布一波流](https://juejin.im/post/5b96586de51d450e7d0984a6) 2 | ### [手把手教你发布一个vue组件到npm上](https://juejin.im/post/5bc44175f265da0a906f9869) 3 | ## [告诉你为何以及如何搭建一个私有的npm仓库](https://zhuanlan.zhihu.com/p/35773211) 4 | ## [CPM - 轻量的NPM私有源程序搭建](https://juejin.im/post/5bf62141e51d4509cc6c9b0f) 5 | ### [npm私有库服务搭建及规范定制](https://juejin.im/post/5c184e2a5188257abf1d691c) 6 | ### [[译]635000 个 npm 包中我应该用哪个](https://juejin.im/post/5c1b5cabe51d4548ec65ce3b) 7 | ## [npm使用技巧](https://juejin.im/post/5c1b0e55e51d4550442a31b1) 8 | ### [package.json的所有配置项及其用法,你都熟悉么](https://juejin.im/post/5c21847ef265da6143131652) 9 | ### [极简NPM指南与常用命令](https://juejin.im/post/5c2328e7e51d4516da711843) 10 | ### [不敢阅读 npm 包源码?带你揭秘 taro init 背后的哲学](https://juejin.im/post/5c21f4e5f265da61117a54a0#comment) 11 | ## [pkg版本规范管理自动化最佳实践](https://juejin.im/post/5c4454146fb9a04a0164a289) 12 | -------------------------------------------------------------------------------- /Nginx.MD: -------------------------------------------------------------------------------- 1 | ### [谁说前端不需要懂-Nginx反向代理与负载均衡](https://juejin.im/post/5b01336af265da0b8a67e5c9) 2 | ### [教你快速撸一个免费HTTPS证书](https://juejin.im/post/5b57e1c05188251afe7b922a) 3 | ### [Nginx与前端开发](https://juejin.im/post/5bacbd395188255c8d0fd4b2) 4 | ### [全面了解 Nginx 到底能做什么](https://mp.weixin.qq.com/s/BjjLYMJEgQM37luvD49Tug) 5 | ### [Traefik 入手及简单配置](https://github.com/shfshanyue/blog/blob/master/Articles/Traefik/Readme.md) 6 | ### [当我有一台云服务器时,我做了些什么](https://juejin.im/post/5c9232a8e51d45729b3b71e1) 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Node-cli.MD: -------------------------------------------------------------------------------- 1 | ### [NodeJs交互式命令行工具Inquirer.js-开箱指南](https://www.jianshu.com/p/db8294cfa2f7) 2 | ### [Vue-cli@3.0 插件系统简析](https://juejin.im/post/5b8f586c5188255c9d55eedf) 3 | ### [教你从零开始搭建一款前端脚手架工具](https://juejin.im/post/5c237d1a5188256b9e0f21e1) 4 | ### [用node开发并发布一个cli工具](https://juejin.im/post/5c2c6eb4e51d452626299036) 5 | ## [Node.js项目配置文件教程](https://www.2cto.com/kf/201710/690294.html) 6 | ### [脚手架的开发总结](https://juejin.im/post/5c36f2f86fb9a049ea3925dd) 7 | -------------------------------------------------------------------------------- /Node-项目.MD: -------------------------------------------------------------------------------- 1 | ### [Node - 从0基础到实战企业官网](https://juejin.im/post/5c1f8e52f265da6170071e43#chapter-three-eight) 2 | ### [使用node+puppeteer破解验证码](https://juejin.im/post/5c343f4ff265da611639f5bb) 3 | -------------------------------------------------------------------------------- /Node.MD: -------------------------------------------------------------------------------- 1 | ### [一点感悟:《Node.js学习笔记》star数突破1000+](https://juejin.im/post/5b1717a86fb9a01e3e5ce540) 2 | ### [Node.js 进程平滑离场剖析](https://juejin.im/post/5c4937eee51d452a167bd158) 3 | ### [用 Node.js 快速开发出多功能的多人在线的文章分享平台](https://juejin.im/post/5c184e396fb9a049dc022ab5#comment) 4 | ### [你不知道的Node.js性能优化](https://zhuanlan.zhihu.com/p/50055740) 5 | ## [Node中fs模块 API详解](https://juejin.im/post/5b9768b2e51d450e9942eb98) 6 | ## 5星级[将node.js的终端输出重定向到浏览器控制台中](https://blog.suisuijiang.com/node-js-console-log-redirect-to-browser/) 7 | ## [node.js中实现代码Hot-Reload功能](https://blog.suisuijiang.com/in-nodejs-realize-code-hot-reload-function/) 8 | ### [七天学不会nodejs——流](https://juejin.im/post/5b54a7f95188251afc257dac) 9 | ### [Node.js Streams 基础总结](https://juejin.im/post/5bf7b53c6fb9a04a06048354) 10 | ### [Node.js 中间件模式](https://juejin.im/post/5b1e3f28e51d4506bd72db7c) 11 | ### [express使用笔记](https://github.com/chyingp/Express-learning-guide) 12 | ### [Node.js中的事件循环(Event Loop),计时器(Timers)以及process.nextTick](https://github.com/libin1991/libin_Blog/issues/516) 13 | ### [面试之Event Loop,nextTick()和setImmediate()区别分析](https://github.com/libin1991/libin_Blog/issues/120) 14 | ### [浅度理解NodeJS的HTTP模块](https://juejin.im/post/5ad5a14a6fb9a028d82c445a) 15 | ### [node ( 5 ) -----process详解(这个标题不讨喜……)](https://juejin.im/post/5ad4d5066fb9a028e25e0a8a) 16 | ### [Koa:核心探秘与入坑指北](https://juejin.im/post/5ad466d25188253edd4d898a) 17 | ### [node实现登录图片验证码](https://juejin.im/post/5ad82856f265da50463e3ae7) 18 | ### [node打造微信个人号机器人](https://juejin.im/post/5ae00f966fb9a07aaf34dfcd) 19 | ### [node.js 命令行工具(cli)](https://juejin.im/post/5af2a2cbf265da0b9c109f59) 20 | ### [Node.js执行系统命令](https://juejin.im/post/5b07eb1c5188254e28710d80) 21 | ### [Node.js 服务端图片处理利器——sharp 进阶操作指南](https://juejin.im/post/5b0bd60e6fb9a00a1610e4be) 22 | ### [手写node可读流之流动模式](https://juejin.im/post/5b0f4cb3f265da08d51d3f3c) 23 | ### [全面理解 koa-router](http://zhangxiang958.github.io/2018/06/03/%E5%85%A8%E9%9D%A2%E7%90%86%E8%A7%A3%20koa-router/) 24 | ### [Event Loop 必知必会(六道题)](https://zhuanlan.zhihu.com/p/34182184) 25 | ### [求不更学不动之Node.js多线程](https://segmentfault.com/a/1190000015383666) 26 | ### [一站到底 ---前端基础之网络](https://juejin.im/post/5b3357556fb9a00e5a4b63df) 27 | ### [node.js的小美好](https://juejin.im/post/5b3352abe51d4558ab7b454a#heading-7) 28 | ### [node基础面试事件环?微任务、宏任务?一篇带你飞](https://juejin.im/post/5b35cdfa51882574c020d685) 29 | ### [面试高级前端工程师必问之流-stream](https://juejin.im/post/5b421b5ee51d45198651159b) 30 | ### [带你一起撸一遍 nodejs 常用核心模块(二)](https://juejin.im/post/5b417842f265da0f96286f2b) 31 | ## [node-"fs-extra"模块代替fs使用](https://juejin.im/post/5b52fd21e51d4519234468f1) 32 | ## [node.js判断换行](https://github.com/libin1991/libin_Blog/issues/596) 33 | ### [循序渐进教你实现一个完整的node的EventEmitter模块](https://github.com/forthealllight/blog/issues/21) 34 | ### [koa初了解](https://juejin.im/post/5b55baccf265da0f4b7a9760) 35 | ### [Express, Koa, Redux中间件的区别,写法和执行流程](https://juejin.im/post/5b5d8e55e51d4535a65ae507) 36 | ### [浏览器事件环和Node事件环不得不说的故事!](https://juejin.im/post/5b5f365e6fb9a04fa8673f97) 37 | ### [如何用node开发自己的cli工具](https://juejin.im/post/5b6b086cf265da0f8d368935) 38 | ### [探索 PM2 Cluster 模式下 Log4js 日志丢失](https://juejin.im/post/5b7ea1e56fb9a01a0f24979a) 39 | ### [对node工程进行压力测试与性能分析](https://juejin.im/post/5b827cbbe51d4538c021f2da) 40 | ### [【Node】简单快捷的图片压缩脚本](https://juejin.im/post/5b8a9769e51d4538c17e121c) 41 | ### [nodejs“并行”处理尝试](https://juejin.im/post/5b8a36f551882542c7638bae) 42 | ### [使用 Node 构建命令行应用](https://juejin.im/post/5b952f4ce51d450e7632caaf) 43 | ## [使用node构建文件重命名脚本工具](https://juejin.im/post/5b99d59de51d450e9c55468e) 44 | ## [Node中的两种遍历方式-深度优先和广度优先(附Node删除文件例子进行详解)](https://juejin.im/post/5b976a7a6fb9a05cdf307795) 45 | ## [redux, koa, express 中间件实现对比解析](https://juejin.im/post/5b9a23a45188255c9c751b07) 46 | ## [动手制作nodejs命令行工具 iconfont-cli](https://juejin.im/post/5ba231b06fb9a05ce873d609) 47 | ## [必知必会的Node-CLI开发基础](https://juejin.im/post/5bc496196fb9a05d0f170694) 48 | ## [[译]你不知道的Node](https://houxingyi.github.io/2018/10/20/2018-10-10-you-dont-know-Node/) 49 | ### [手把手教你用node撸一个图片压缩工具](https://juejin.im/post/5bd350a76fb9a05d2d02697c) 50 | ### [教你如何用node.js开发微信公众号(一)](https://juejin.im/post/5be3af8ae51d4554b54b0a0d) 51 | ## [Node.js 10 LTS 值得关注的特性](https://zhuanlan.zhihu.com/p/49429391) 52 | ## [【手把手撸一个脚手架】第一步, 创建第一个命令](https://juejin.im/post/5bead1b25188251e1a1f4d34) 53 | ### [教你在Nodejs中如何获取当前函数被调用的行数及文件名](https://juejin.im/post/5c0f97dcf265da616f6fd065) 54 | ### [在Node.js中发起HTTP请求的5种方法](https://juejin.im/post/5c35775f6fb9a049c6440789) 55 | -------------------------------------------------------------------------------- /PWA.MD: -------------------------------------------------------------------------------- 1 | ### [PWA 的探索与最佳实践](https://mp.weixin.qq.com/s/e9I2G2JD-SXfJLLLThyaIg) 2 | ### [PWA学习与实践](https://juejin.im/post/5ac8a67c5188255c5668b0b8) 3 | ### [前端应该了解的PWA](https://juejin.im/post/5af2fd776fb9a07a9c04372f) 4 | ### [Service Worker 的生命周期与使用场景](https://juejin.im/post/5b0f9e50518825155911e7be) 5 | ### [在Vue里用Service Worker来搞个中间层(React同理)](https://juejin.im/post/5b4017c1f265da0fb0184fae) 6 | ### [浅谈web前端的发展趋势PWA](https://juejin.im/post/5b440eeae51d4519195a9bd3) 7 | ### [[贝聊科技]PWA初探](https://juejin.im/post/5b751dabf265da28072f1833) 8 | ### [浅谈PWA](https://juejin.im/post/5bed580cf265da6166240a1e) 9 | ### [Service Worker学习与实践(二)——PWA简介](https://github.com/xingbofeng/xingbofeng.github.io/issues) 10 | ### [深入理解 PWA](https://juejin.im/post/5c07493951882516cd70d213) 11 | ### [[译]前端离线指南(上)](https://juejin.im/post/5c0788a65188250808259ae4) 12 | ### [利用ServiceWorker实现页面的快速加载和离线访问](https://juejin.im/post/5c36b6f76fb9a04a0d570c62) 13 | ### [PWA(Progressive Web App)入门系列:Cache Storage & Cache](https://juejin.im/post/5c6ee4f5f265da2dd218caac) 14 | -------------------------------------------------------------------------------- /PostCSS.MD: -------------------------------------------------------------------------------- 1 | ### [PostCSS真的太好用了!](https://juejin.im/post/5c022f4a6fb9a049ca371684) 2 | -------------------------------------------------------------------------------- /Promise.MD: -------------------------------------------------------------------------------- 1 | ### [Promise的分层解析及实现](https://juejin.im/post/5be93f6ff265da6153044d88) 2 | ### [Promise 中的三兄弟 .all(), .race(), .allSettled()](https://juejin.im/post/5d534ff16fb9a06b1027209c) 3 | ### [原生es6封装一个Promise对象](https://juejin.im/post/5bfc9e4ee51d451dca4794af) 4 | ### [TS 版 Promise 详解](https://juejin.im/post/5c010de86fb9a049b41c3285) 5 | ### [手写实现满足 Promise/A+ 规范的 Promise](https://juejin.im/post/5c0a3d696fb9a04a0604ad44) 6 | ### [老生常谈-实现一个Promise](https://juejin.im/post/5c0dc1bd6fb9a049e06328f7) 7 | ### [面试高频点-Promise解析和实现](https://juejin.im/post/5c10d77ee51d4536425c852e) 8 | ### [前端杂谈: 如何实现一个 Promise?](https://juejin.im/post/5c121b82f265da612061b225) 9 | ### [站住,你这个Promise!](https://juejin.im/post/5c179aad5188256d9832fb61) 10 | ### [Promise 源码分析](https://juejin.im/post/5c1cb4b0e51d455fb3109f48) 11 | ### [面试官眼中的Promise](https://juejin.im/post/5c233a8ee51d450d5a01b712) 12 | ### [实现一个Promise(基于Promise/A+规范)](https://juejin.im/post/5c2b34a15188257abf1d96eb) 13 | ### [Promise进阶——如何实现一个Promise库](https://juejin.im/post/5c2c718ce51d4558bf39860d) 14 | ### [你能手写一个Promise吗?Yes I promise。](https://juejin.im/post/5c41297cf265da613356d4ec) 15 | ### [原生es5封装的Promise对象](https://juejin.im/post/5c4576cf6fb9a04a06052f3f#heading-12) 16 | -------------------------------------------------------------------------------- /React-cli.MD: -------------------------------------------------------------------------------- 1 | ### [纯css模拟下雪效果](https://juejin.im/post/5c4525ab6fb9a049bb7ca45c) 2 | ### [React干货:SPA单页如何规划路由、设计Store、划分模块、按需加载](https://juejin.im/post/5c41b3b451882525380642d6) 3 | ### [React 组件生命周期详解](https://juejin.im/post/5c4575626fb9a049ca37aac2) 4 | ### [React16.6和Typescript高仿B站Web移动端](https://juejin.im/post/5c455f7ae51d4551e744aad9) 5 | -------------------------------------------------------------------------------- /Redux.MD: -------------------------------------------------------------------------------- 1 | ### [如何构建一个不到100行的小程序端mini版本redux](https://juejin.im/post/5bc152505188255c7566f150) 2 | ### [逐行阅读redux源码(二)combineReducers](https://juejin.im/post/5bebf227518825170d1aa30b) 3 | ### [redux 入门到实践](https://juejin.im/post/5c0e3ff6f265da61553aa8b6#heading-21) 4 | ### [深入浅出redux-middleware](https://juejin.im/post/5c0e61836fb9a049cd5408c2) 5 | ### [为什么Redux 需要 reducers是纯函数?](https://juejin.im/post/5b7eb925f265da43445f63c6) 6 | ### [为什么redux要返回一个新的state引发的血案](https://juejin.im/post/5c1b6925e51d455ac91d6bac) 7 | ### [使用react-hook 重写 react-redux](https://juejin.im/post/5c230aa2e51d4529355bc2e0) 8 | ### [React的上下文-Context](https://juejin.im/post/5c2c99d0f265da61736a65be) 9 | ### [彻彻底底教会你使用Redux-saga(包含样例代码)](https://segmentfault.com/a/1190000015583055) 10 | -------------------------------------------------------------------------------- /RegExp.MD: -------------------------------------------------------------------------------- 1 | ### [可能是最好的正则表达式的教程笔记了吧...](https://juejin.im/post/5b5db5b8e51d4519155720d2#comment) 2 | ![1533045856 1](https://user-images.githubusercontent.com/16753554/43464913-ca6b33c2-950e-11e8-9cb9-febe0d7d20bb.jpg) 3 | ### [如何判断用户浏览器以及一些前端常用的正则表单验证](https://juejin.im/post/5aed6da16fb9a07aac2457f6) 4 | ### [教科书式的正则匹配](https://juejin.im/post/5b0cf331f265da0905017b48) 5 | ### [面试官!让我们聊聊正则](https://juejin.im/post/5b62717ee51d4519873f858a) 6 | ### [【译】ES2018 新特性: 正则表达式的 s (dotAll) 标志](https://juejin.im/post/5b6a86f2f265da0f9c67c999) 7 | ### [一篇文章搞定 javascript 正则表达式](https://juejin.im/post/5b6adc7ee51d4534b8587560) 8 | ### [出来混总是要还的-JS正则常用的有四种操作: 验证、切分、提取、替换](https://juejin.im/post/5bcd3703518825778c497908) 9 | ### [22分钟学会书写正则](https://segmentfault.com/a/1190000016964825) 10 | ## [正则表达式详解及实战](https://juejin.im/post/5bf174396fb9a049ca36f13d) 11 | ### [浅谈JavaScript正则表达式](https://juejin.im/post/5c203a49e51d455de377202b#heading-16) 12 | ### [高亮:单关键词、多关键词、多组多关键词,从简单到复杂实现满足多方面需求的页面关键词高亮](https://juejin.im/post/5c2434856fb9a049f362269f#heading-33) 13 | ### [JavaScript实现段落文本高亮](https://www.cnblogs.com/libo0125ok/p/7810982.html) 14 | ### [javascript 查找文本并高亮显示](https://www.cnblogs.com/joyho/articles/3510388.html) 15 | ### [正则实现数组滤重](https://juejin.im/post/5c2f0220e51d455023415955) 16 | ### [正则表达式-数字每隔3位加入逗号](https://blog.csdn.net/emilyorchid/article/details/47859823) 17 | ### [使用正则表达式每3位数字加逗号](http://www.cnblogs.com/mcshell/p/5655797.html) 18 | -------------------------------------------------------------------------------- /Rollup.MD: -------------------------------------------------------------------------------- 1 | ### [10分钟快速入门rollup.js](https://juejin.im/post/5bed8b26e51d4560336ca5b3) 2 | ### [10分钟快速进阶rollup.js](https://juejin.im/post/5bf532546fb9a049e129d529) 3 | -------------------------------------------------------------------------------- /Router.MD: -------------------------------------------------------------------------------- 1 | ### [[实践系列] 前端路由](https://juejin.im/post/5c380afde51d4552232fb077) 2 | -------------------------------------------------------------------------------- /SQL.MD: -------------------------------------------------------------------------------- 1 | ### [MongoDB的基本用法](https://juejin.im/post/5add9e655188256735642122) 2 | -------------------------------------------------------------------------------- /SSR.MD: -------------------------------------------------------------------------------- 1 | 2 | ### [解密Vue SSR](https://zhuanlan.zhihu.com/p/35871344) 3 | ### [Vue 服务端渲染技术](https://juejin.im/post/5ade9343518825673f0b3f17) 4 | ### [带你走近Vue服务器端渲染(VUE SSR)](https://juejin.im/post/5b72d3d7518825613c02abd6) 5 | ### [通过vue-cli3构建一个SSR应用程序](https://juejin.im/post/5b98e5875188255c8320f88a#comment) 6 | ### [带你五步学会Vue SSR](https://juejin.im/post/5bbda9ed5188255c8f06c0dc#comment) 7 | ### [React服务端渲染(前后端路由同构)](https://juejin.im/post/5bbedfca5188255c5e670682#heading-1) 8 | ### [基于vue-cli3 SSR 程序实现热更新功能](https://juejin.im/post/5bc4321b6fb9a05d1e0e824b) 9 | ### [Vue SSR( Vue2 + Koa2 + Webpack4)配置指南](https://juejin.im/post/5be85c7af265da612909b436) 10 | ### [Vue 服务端渲染(SSR)、Nuxt.js - 从入门到实践](https://juejin.im/post/5be4e31ef265da616623f770#comment) 11 | ## [React 服务端渲染方案完美的解决方案](https://juejin.im/post/5bf3cb59f265da612b1336e2#comment) 12 | ### [如何用 React 做服务端渲染](https://juejin.im/post/5c18c34ef265da615114ae78) 13 | ### [VueJS SSR 后端绘制内存泄漏的相关解决经验](https://juejin.im/post/5c1b019a6fb9a049fb439d33) 14 | ### [深入学习Vue SSR服务端渲染 用Nuxt.js打造CNode社区](https://juejin.im/post/5c45f13f6fb9a049e12a86fb) 15 | -------------------------------------------------------------------------------- /SVG.MD: -------------------------------------------------------------------------------- 1 | ## [类似淘票票 选座功能(svg)](https://juejin.im/post/5bed39096fb9a049b3478caf) 2 | ## [图像优化原理](https://juejin.im/post/5bfe00e7e51d456f4f2c8860) 3 | ### [SVG-让世界变得柔软](https://juejin.im/post/5c0e50846fb9a04a016428be) 4 | ### [如何用svg画一个骚气的名字](https://juejin.im/post/5c1c56046fb9a049f7462b32) 5 | ### [Web字体图标-自动化方案](https://jiangxiaokun.com/web/2019/01/12/web_iconfont/) 6 | -------------------------------------------------------------------------------- /TypeScript.MD: -------------------------------------------------------------------------------- 1 | ### [TypeScript 入门教程](https://github.com/xcatliu/typescript-tutorial) 2 | ### [使用typescript+vue 编写电影信息小项目!](https://juejin.im/post/5bc2fd06e51d450e7903c783) 3 | ### [Typescript配合React实践](https://juejin.im/post/5bc49b59e51d450e5162d8ae) 4 | ### 5星级[Ts + React + Mobx 实现移动端浏览器控制台](https://juejin.im/post/5bf278295188252e89668ed2) 5 | ### [小邵教你玩转Typescript、ts版React全家桶脚手架](https://juejin.im/post/5c04d3f3f265da612e28649c#heading-13) 6 | ## [关于依赖注入(typescript)](https://juejin.im/post/5c16004ae51d45485a098ef8) 7 | ### [Typescript 中的 interface 和 type 到底有什么区别](https://juejin.im/post/5c2723635188252d1d34dc7d) 8 | ### [2.TypeScript 基础入门(二)](https://juejin.im/post/5c3eca17f265da61461e6707) 9 | ### [TypeScript 3.3来了!快看看有什么新功能](https://juejin.im/post/5c48286a6fb9a049c43e0247) 10 | ### [深入理解 TypeScript](https://jkchao.github.io/typescript-book-chinese/) 11 | -------------------------------------------------------------------------------- /Ui框架,图表.MD: -------------------------------------------------------------------------------- 1 | ## MUI 2 | ### [wux-weapp](https://github.com/libin1991/wux-weapp) 3 | ### [高质量移动端UI框架](https://github.com/uileader/touchui) 4 | ### [https://github.com/youzan/vant](https://github.com/youzan/vant) 5 | ### [https://github.com/wangdahoo/vonic](https://github.com/wangdahoo/vonic) 6 | ### [https://github.com/kwun12/ydui](https://github.com/kwun12/ydui) 7 | ### [mint-ui](https://github.com/ElemeFE/mint-ui/) 8 | ### [cube-ui](https://github.com/didi/cube-ui) 9 | ### [2017 年 4 月:15 个有趣的 JS 和 CSS 库](https://zhuanlan.zhihu.com/p/26317328) 10 | ### [多端统一开发框架 Taro 1.0 正式发布](https://juejin.im/post/5ba2222be51d450e8a65fd4a) 11 | ### [一只基于Vue2.x的移动端&微信UI。 -YDUI Touch](http://vue.ydui.org/) 12 | ### [🥒 黄瓜 UI: 一个即插即用的 React 组件库](https://juejin.im/post/5c233564e51d455d382ebeaa#comment) 13 | ### [uni-app 1.4 发布,一套代码,发行小程序(微信/支付宝/百度)、H5、App多个平台](https://juejin.im/post/5c2dc4aef265da612c5e02d7) 14 | ### [一个基于Vue2的小型移动端组件库](https://github.com/libin1991/im-vuer) 15 | ### [一个基于Vue2.0的移动端UI组件库](https://github.com/xiaojun1994/unique-ui) 16 | ### [Chameleon快速上手简易教程](https://juejin.im/post/5c63eefa6fb9a049a42f8ad4) 17 | ### [轻量级移动端Vue组件库 (A Vue.js 2.0 UI Toolkit for Mobile Web) https://nutui.jd.com](https://github.com/libin1991/nutui) 18 | 19 | 20 | --- 21 | ## PC 22 | ### [https://2ue.github.io/vui/#/select](https://2ue.github.io/vui/#/select) 23 | ### [https://github.com/museui/muse-ui](https://github.com/museui/muse-ui) 24 | ### [HeyUI](https://github.com/heyui/heyui) 25 | ### [vue-ydui](https://github.com/libin1991/vue-ydui) 26 | ### [不厌其烦,又一个Vue组件库](https://juejin.im/post/5c2cc6616fb9a049b07d765a) 27 | ### [开源接口管理工具 YApi 1.5.1 版本发布](https://juejin.im/post/5c63e81af265da2d914d7305) 28 | ### [HeyUI 组件库两周年,中后台管理系统 HeyUI Admin 发布](https://juejin.im/post/5c84ea195188257e342db793#comment) 29 | --- 30 | 31 | ## 框架 32 | ## [Vue应用框架整合与实战--Vue技术生态圈篇](https://www.jianshu.com/p/22a99426b524) 33 | #### [vue-style-codebase](https://github.com/libin1991/vue-style-codebase) 34 | ### [【5星级】一个骚气的文章目录自动生成器了解一下](https://github.com/libin1991/progress-catalog) 35 | ### [vue 项目快速输出微信、支付宝、百度小程序](https://juejin.im/post/5be9748d6fb9a049dd7fcf32) 36 | --- 37 | ## weex 38 | ### [基于weex的有赞无线开发框架](https://juejin.im/post/5bd7feb85188257100456a85) 39 | ### [Weex Eros快速入门](https://juejin.im/post/5c01f249e51d4566754074c2) 40 | --- 41 | ## charts 42 | ### [Vue.js 轻量级组件化 SVG 图表库](https://github.com/libin1991/laue) 43 | ### [一个为移动端而生的炫酷的图表库](https://github.com/antvis/f2) 44 | ### [很漂亮的数据展示!](https://news.cgtn.com/event/2019/whorunschina/index.html?from=timeline&isappinstalled=0) 45 | --- 46 | ## 库 47 | ### [前端常用插件、工具类库汇总,不要重复造轮子啦!!!](https://juejin.im/post/5ba7d5dd5188255c6140cc9d) 48 | ### [我扒下了某音乐的 😂😂😂 V2.0](https://juejin.im/post/5c372e31518825253208edf2) 49 | --- 50 | ## 小程序 51 | ### [wux-weapp](https://github.com/libin1991/wux-weapp) 52 | ### [Taro + 小程序云开发实战](https://juejin.im/post/5bd7f93f6fb9a05cff326537) 53 | ### [在小程序中使用 React with Hooks](https://juejin.im/post/5c3bea2651882523785596a0) 54 | ### [TaroEcharts-各种图表在Taro中的实践](https://juejin.im/post/5c3f1ae0e51d455249760c8f) 55 | ### [小程序原生高颜值组件库--ColorUI组件库](https://juejin.im/post/5c773b746fb9a049f43bff0f) 56 | ### [一个多端开发框架?这次是 Vue 驱动,能完美适配 H5](https://juejin.im/post/5cbd34e7f265da036504fa3c) 57 | 58 | --- 59 | 60 | ## API 61 | ### [开源接口管理平台YApi v1.4.3 元旦发布](https://juejin.im/post/5c2981d6f265da613e2255b8) 62 | --- 63 | ## 工具 64 | ### [左边编写vue组件,右边可以查看vuese最终生成的markdown和parser result以及render result。](https://vuese.github.io/vuese-explorer/) 65 | -------------------------------------------------------------------------------- /Video.MD: -------------------------------------------------------------------------------- 1 | ### [html5中video在安卓与ios实际应用中遇到的问题及解决](https://juejin.im/post/5ba5abedf265da0aa664c0f6) 2 | -------------------------------------------------------------------------------- /VirtualDOM.MD: -------------------------------------------------------------------------------- 1 | ### [探索Virtual DOM的前世今生](https://juejin.im/post/5b0638a9f265da0db53bbb6d) 2 | ## virtual dom很多时候都不是最优的操作,但它具有普适性,在效率、可维护性之间达平衡。 3 | ### [解析vue2.0的diff算法](https://github.com/aooy/blog/issues/2) 4 | ### [详解vue的diff算法](https://juejin.im/post/5affd01551882542c83301da) 5 | ### [理解virtual dom的实现细节-snabbdom](https://juejin.im/post/5c2ad7f951882565986a2517) 6 | ### [深度剖析:如何实现一个 Virtual DOM 算法](https://github.com/livoras/blog/issues/13) 7 | -------------------------------------------------------------------------------- /VsCode.MD: -------------------------------------------------------------------------------- 1 | ### [VsCode读取项目文件的Eslint规则 保存时自动修复格式错误](https://juejin.im/post/5b9dee8ff265da0afe62d1dd) 2 | ### [ 再来一波大前端适用系列的插件(主打编码体验改善)](https://juejin.im/post/5c356b106fb9a049ef26c368) 3 | ### [VS Code:让你工作效率翻倍的23个插件和23个编辑技巧](https://juejin.im/post/5bc55606e51d450e853075c9) 4 | ### [VS Code 快速使用指南](https://juejin.im/post/5bc86b0b5188255ca00cc58f) 5 | ### [30个极大提高开发效率的Visual Studio Code插件](https://juejin.im/post/5b99a927f265da0a922399cd) 6 | ### [Markdown 中的 Table 一键排序](https://juejin.im/post/5be1963df265da61620cde1f) 7 | ### [JavaScript 开发者 10 种必备 VS Code 扩展](https://www.css88.com/archives/10004) 8 | ### [VS Code书写vue项目配置 eslint+prettier 统一代码风格](https://juejin.im/post/5be5429de51d4511a808f4ac) 9 | ### [写给前端开发者不一样的VSCode配置(JS/React)](https://juejin.im/post/5bea48c4e51d454e5b5f19e8) 10 | ### [一个vue前端的VSCODE插件分享(2018)](https://juejin.im/post/5be53004f265da615b70f7a0) 11 | ### [vscode下的vue文件格式化](https://juejin.im/post/5bfcdee25188251d9e0c40f2) 12 | ### [推荐一个很好用的vscode插件:一个可以给出vuex中store定义信息的vscode插件](https://juejin.im/post/5c0d14d9518825793d15c5a8) 13 | ### [提高 JavaScript 开发效率的高级 VSCode 扩展](https://segmentfault.com/a/1190000017339754) 14 | ### [提高效率的VScode插件](https://segmentfault.com/a/1190000012067159) 15 | ### [VSCode折腾log插件](https://juejin.im/post/5c1e2612e51d452aaa7c43fe) 16 | -------------------------------------------------------------------------------- /Vue-Component.MD: -------------------------------------------------------------------------------- 1 | ### [「Vue」与「React」--使用上的区别](https://juejin.im/post/5c2de832f265da6172659b45#heading-4) 2 | ### [利用 JavaScript Profiler 分析 Vue 性能问题](https://juejin.im/post/5c2ebae16fb9a049be5d9e49) 3 | ### [奇技淫巧 - Vue Mixins 高级组件 与 Vue HOC 高阶组件 实践](https://juejin.im/post/5c08c6ac6fb9a04a0e2cfe0a#comment) 4 | ### [Vue实现函数防抖组件](https://juejin.im/post/5c2dc7a9e51d4573c8491e77) 5 | ### [以vue组件或者插件的形式,实现throttle或者debounce](https://juejin.im/post/5c18a7b7f265da61553ac179) 6 | ### [基于vue.js实现树形表格的封装](https://juejin.im/post/5b568730f265da0fa1222a4c) 7 | ### [一个Vue媒体多段裁剪组件](https://juejin.im/post/5b6960d8e51d4519115d5d2f) 8 | ### [Vue实现左右菜单联动实现](https://juejin.im/post/5b6ea54cf265da0f6436f77a#comment) 9 | ### [vue2实现搜索结果中的搜索关键字高亮](https://juejin.im/post/5b73e5a3f265da28201d9831#comment) 10 | ### [弹弹弹,弹走鱼尾纹的弹出菜单(vue)](https://juejin.im/post/5b976bfcf265da0ac372ef14) 11 | ### [在Vue3.0之前,回顾Vue2.0新特性的使用](https://juejin.im/post/5c204c98e51d454637699e33) 12 | ### [通过几个问题深入浅出Vue](https://juejin.im/post/5c206fb8f265da61141c9c89) 13 | ### [(译)函数式组件在Vue.js中的运用](https://juejin.im/post/5c2d7030f265da613a54236f) 14 | ### [vue 组件的三种使用方式教程,组件插槽,插件,全局组件](https://juejin.im/post/5c91e54f5188252d7c216627) 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Vue-cli.MD: -------------------------------------------------------------------------------- 1 | ### [vue-cli3配置vue.config.js持续更新](https://github.com/libin1991/vue-cli3-config) 2 | ### [webpack build后生成的app、vendor、manifest三者有何职能不同?](https://juejin.im/post/5c17b9805188251e663ec239) 3 | ### [为vue的项目添加单元测试](https://juejin.im/post/5c17a4bd6fb9a049fb4392f2) 4 | ### [Vue CLI 3.0脚手架如何在本地配置mock数据](https://www.modenng.com/2018/11/27/vue-mock/) 5 | ### [【vue-cli3升级】老项目提速50%(一)](https://juejin.im/post/5c395e7a51882523995dfc16) 6 | ### [vue-cli3 从搭建到优化](https://juejin.im/post/5c3c544c6fb9a049d37f5903) 7 | ### [【vue-cli3升级】老项目提速50%(二)](https://juejin.im/post/5c403bcaf265da61587765c9) 8 | ### [【前端打包部署】谈一谈我在SPA项目打包=>部署的处理](https://juejin.im/post/5c4835d651882523ea6e0a9a) 9 | ### [窥探 Vue CLI3 UI 内置插件 - 关闭网络端口](https://juejin.im/post/5c46c1ebe51d4552411afcb2) 10 | ### [离职后才搞懂vue项目开发流程中的疑惑点](https://juejin.im/post/5c488a3cf265da615705cc2a) 11 | ### [JS 中的数据代理](https://juejin.im/post/5c491bdc51882525db14549e) 12 | -------------------------------------------------------------------------------- /Vue技巧.MD: -------------------------------------------------------------------------------- 1 | ### [vue-router浅析原理](https://juejin.im/post/5bc6eb875188255c9c755df2) 2 | ## [这些vue技巧你肯定不知道](https://juejin.im/post/5bc937285188255c63763ae2#comment) 3 | # [vue源码-内部运行机制剖析](https://github.com/libin1991/vue-1?organization=libin1991&organization=libin1991) 4 | ### [关于做常规的数字定时滚动效果](https://juejin.im/post/5be14a296fb9a049a62c0930) 5 | ## [一份超级详细的Vue-cli3.0使用教程[赶紧来试试!]](https://juejin.im/post/5bdec6e8e51d4505327a8952) 6 | ## [Vue一个案例引发「动画」的使用总结](https://juejin.im/post/5bfcf3eaf265da61542d50e3) 7 | ### [在移动端使用vue-router和keep-alive](https://juejin.im/post/5c01f6f4e51d45551f2c0b6e) 8 | ## [用 vue + d3 画一棵树](https://juejin.im/post/5c039491e51d4529db2aa26e) 9 | ## [如何在vue项目中优雅的使用SVG](https://juejin.im/post/5c049a28f265da61273d2317) 10 | ### [vue中async-await的使用误区](https://juejin.im/post/5bfa4bb951882558ae3c171e#comment) 11 | ### [vue权限路由实现方式总结二](https://juejin.im/post/5c0b2130f265da615c5913d9) 12 | ### [vue组件的那点事](https://juejin.im/post/5c1304645188257c3045eb12#heading-4) 13 | ### [关于v-for的一点小总结](https://juejin.im/post/5c2746b4e51d450d50306db2) 14 | -------------------------------------------------------------------------------- /Web Components.MD: -------------------------------------------------------------------------------- 1 | ### [Web Components 小榄](https://juejin.im/post/5c037e2ee51d455da60244ea) 2 | -------------------------------------------------------------------------------- /WebAssembly.MD: -------------------------------------------------------------------------------- 1 | ### [WebAssembly 为什么这么快?](https://mp.weixin.qq.com/s/cPLw8G62kS-MqeX2fvG9Vg) 2 | -------------------------------------------------------------------------------- /WebGL.MD: -------------------------------------------------------------------------------- 1 | ### [学习WebGL:着色器、绘制一个点](https://www.cnblogs.com/etopx/p/6535638.html) 2 | -------------------------------------------------------------------------------- /WebWorker.MD: -------------------------------------------------------------------------------- 1 | ### [前端er来学习一下webWorker吧](https://juejin.im/post/5bf8fa045188252f170e0dcb) 2 | ### [JavaScript 性能利器 —— Web Worker](https://juejin.im/post/5c10e5a9f265da611c26d634) 3 | ### [如何提升JavaScript的任务效率?学会后教给你同事](https://juejin.im/post/5c1712505188256ec35fdac3) 4 | ### [WebWorker究极探索](https://juejin.im/post/5c9f6a07f265da30933fc232) 5 | -------------------------------------------------------------------------------- /Webpack.MD: -------------------------------------------------------------------------------- 1 | # [webpack4系列教程](https://godbmw.com/categories/webpack4%E7%B3%BB%E5%88%97%E6%95%99%E7%A8%8B/) 2 | ### [Webpack 将代码打包成什么样子?](https://segmentfault.com/a/1190000014129037) 3 | ### [webpack打包性能优化之路](https://juejin.im/post/5c399d6ae51d4539b927ccdc) 4 | ### [使用webpack4提升180%编译速度](http://louiszhai.github.io/2019/01/04/webpack4/) 5 | ### [如何利用webpack来提升前端开发效率(二)?](https://juejin.im/post/5c41a4866fb9a049f7467d73) 6 | ### [精读《如何编译前端项目与组件》](https://juejin.im/post/5c451ab06fb9a049fe357481) 7 | ### [webapck4 玄妙的 SplitChunks Plugin](https://juejin.im/post/5c08fe7d6fb9a04a0d56a702) 8 | ### [webpack4之splitchunksPlugin拆拆拆--项目实践](https://juejin.im/post/5c00916f5188254caf186f80) 9 | ### [webpack SplitChunksPlugin实用指南](https://juejin.im/post/5b99b9cd6fb9a05cff32007a) 10 | ### [一步一步的了解webpack4的splitChunk插件](https://juejin.im/post/5af1677c6fb9a07ab508dabb) 11 | --- 12 | ## [Vue项目Webpack优化实践,构建效率提高50%](https://juejin.im/post/5c1fa158f265da613c09cb36) 13 | ### [你可能还没试过的 react modern build 构建优化!](https://github.com/Weiyu-Chen/blog/issues/6) 14 | ## [Webpack揭秘——走向高阶前端的必经之路](https://juejin.im/post/5badd0c5e51d450e4437f07a#comment) 15 | ## [webpack源码分析](https://juejin.im/post/5c1859745188254fef232ead) 16 | # [webpack4之splitchunksPlugin拆拆拆--项目实践](https://juejin.im/post/5c00916f5188254caf186f80) 17 | ### [webpack.optimize.CommonsChunkPlugin 详解](https://juejin.im/post/5c2205e15188257507558c5a#comment) 18 | ## [webpack-tapable-0.2.8 源码分析](https://juejin.im/post/5c0f2953e51d451dd71e2f36) 19 | ### [值得了解的webpack高级技能](https://juejin.im/post/5aefc770f265da0b9c108c40) 20 | ## [基于webpack4[.3+]构建可预测的持久化缓存方案[5星级]](https://juejin.im/post/5b977a19f265da0ac4469057) 21 | ## [使用 webpack 进行 web 性能优化(二):利用好持久化缓存](https://juejin.im/post/5b9b0fdfe51d450e7210892d) 22 | ## [使用 webpack 进行 web 性能优化(一):减小前端资源大小](https://juejin.im/post/5b976f4b5188255c865e0240) 23 | ### [webpack性能优化不完全指北](https://juejin.im/post/5b8ac03ff265da431c627f8e) 24 | ### [一步一步的了解webpack4的splitChunk插件](https://juejin.im/post/5af1677c6fb9a07ab508dabb) 25 | ### [webpack 4 :从0配置到项目搭建](https://juejin.im/post/5b3daf2ee51d451962727fbe) 26 | ### [webpack 4.x + Vue基础配置,顺利启动项目](https://juejin.im/post/5b4f60f5e51d45190a431396) 27 | ### [webpack怎么能只是会用呢,核心中的核心tapable了解下?](https://juejin.im/post/5b5889b3e51d451949093ef0) 28 | ### [三十分钟掌握Webpack性能优化](https://juejin.im/post/5b652b036fb9a04fa01d616b) 29 | ### [Webpack4 和单页应用入门](https://github.com/libin1991/libin_Blog/issues/599) 30 | ### [手摸手,带你用合理的姿势使用webpack4(上)](https://juejin.im/post/5b56909a518825195f499806) 31 | ### [手摸手,带你用合理的姿势使用webpack4(下)](https://juejin.im/post/5b5d6d6f6fb9a04fea58aabc) 32 | ### [glob 在webpack中的使用。](https://www.cnblogs.com/waitforyou/p/7044171.html) 33 | ### [使用webpack4打造自己的前端工作流](https://juejin.im/post/5b7f7bcf6fb9a019d137d06f) 34 | ### [体积减少80%!释放webpack tree-shaking的真正潜力](https://juejin.im/post/5b8ce49df265da438151b468) 35 | ### [webpack loader—自己写一个按需加载插件](https://juejin.im/post/5b8e3162f265da432f655639) 36 | ### [用实验的思路优化webpack4项目编译速度](https://juejin.im/post/5b89ea97518825284910db48) 37 | ### [优秀前端必知的话题:我们应该做些力所能及的优化](https://juejin.im/post/5bbc1b0c6fb9a05cf230140c) 38 | ## [干货!撸一个webpack插件(内含tapable详解+webpack流程)](https://juejin.im/post/5beb8875e51d455e5c4dd83f) 39 | ## [webpack雪碧图生成](https://juejin.im/post/5bee2b1ce51d45787a4bc441) 40 | ## [webpack系列之一总览](https://juejin.im/post/5bf7c2186fb9a049fd0f7e8a) 41 | ## [从Webpack源码探究打包流程,萌新也能看懂~](https://juejin.im/post/5c0206626fb9a049bc4c6540) 42 | ### [用于前端开发的webpack4配置[带注释]](https://juejin.im/post/5be45723e51d45305c2ceaf0) 43 | ## [可能是全网最全最新最细的 webpack-tapable-2.0 的源码分析](https://juejin.im/post/5c12046af265da612b1377aa) 44 | ## [webpack性能榨汁机](https://juejin.im/post/5c1c92276fb9a04a102f4254) 45 | ### [Webpack 是怎样运行的?(一)](https://juejin.im/post/5c2331fd6fb9a04a0a5f3a96#heading-2) 46 | ### [webpack系列之二Tapable](https://juejin.im/post/5c25f920e51d45593b4bc719) 47 | ### [JavaScript性能优化之tree-shaking](https://mp.weixin.qq.com/s?__biz=MzUxMzcxMzE5Ng==&mid=2247490230&idx=1&sn=7c407256e1d144631ea143f593311153&chksm=f951aff5ce2626e3c362361ac5473dcc231ffee12c8e5e9e34fd5b9b664b2cce3122b517e992&mpshare=1&scene=1&srcid=0106DfqJpO0QezcItmI4zZkl#rd) 48 | ### [webpack 之 loader 和 plugin 简介](https://juejin.im/post/5980752ef265da3e2e56e82e#heading-3) 49 | -------------------------------------------------------------------------------- /Websocket.MD: -------------------------------------------------------------------------------- 1 | ### [用node实现一个简单的聊天室——websocket实践](https://juejin.im/post/5b6d0142e51d45196350249c) 2 | ### [WebSocket 快速入门](https://juejin.im/post/5c0d0e466fb9a049f66beefe) 3 | ### [利用WebSocket和EventSource实现服务端推送](https://juejin.im/post/5c121c77f265da614a3a5e07) 4 | ### [WebSocket 协议 1~4 节](https://juejin.im/post/5c3ff78451882524a23f2d9a) 5 | ### [小心 !跨站点websocket劫持!](https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665515571&idx=1&sn=0d0b7dea7f77e8f1844b366f1af9667f&chksm=80d67270b7a1fb66d93bae6cb36eabb52671ca9c4fcfcbd4b99a0f97477ea3d7f7ef87f086f3&token=1745763505&lang=zh_CN#rd) 6 | -------------------------------------------------------------------------------- /Weex.MD: -------------------------------------------------------------------------------- 1 | ### [企鹅电竞weex实践——UI开发篇](https://juejin.im/post/5bed1477e51d456c57127b30) 2 | -------------------------------------------------------------------------------- /Z7Z8.MD: -------------------------------------------------------------------------------- 1 | ### [不如自己写一个 schema 类库吧](https://juejin.im/post/5c3c8aed518825259278e95d#comment) 2 | ### [canvas与svg的那些事](https://github.com/dxiaoqi/canvas-svg-) 3 | ## [js读取excel文件,绘制echarts图形---数据处理](https://juejin.im/post/5c15f3055188254caf189baf) 4 | ### [ios 最新系统bug与解决——微信公众号中弹出键盘再收起时,原虚拟键盘位点击事件无效](https://juejin.im/post/5c07442f51882528c4469769#comment) 5 | ## [深度剖析0.1 +0.2===0.30000000000000004的原因](https://juejin.im/post/5c023084f265da613e21fb54) 6 | ## [如何解决0.1 +0.2===0.30000000000000004类问题](https://juejin.im/post/5c05dbfb5188251da07df3bc) 7 | --- 8 | ### [前端 H5 横屏 独特处理方案详解](https://juejin.im/post/5be2403df265da616b102e23) 9 | ### [前端进阶之路-利用Jenkins快速打造前端项目自动化工作流](https://juejin.im/post/5bc000826fb9a05d330adf9d) 10 | ### [SVG波浪:浪啊,浪来了,大浪来了](https://zhuanlan.zhihu.com/p/36031294) 11 | ### [Vue 兼容 ie9 的全面解决方案](https://juejin.im/post/5b2868b46fb9a00e6f65f87e) 12 | ### [用 npm 装包的时候记不住包名怎么办?试试 nqm](https://github.com/libin1991/nqm) 13 | ### [写一个属于你的前端脚手架工具](https://juejin.im/post/5b0e739e518825153e3d5440) 14 | ### [利用whistle调试websocket和socket请求](https://juejin.im/post/5ad6d125f265da239460017e) 15 | ### [在线图片编辑器](https://juejin.im/post/5ad9c9ea51882567105f4f9e) 16 | ### [亲,你的防盗链钥匙,在我手上](https://juejin.im/post/5adc0d03518825673a2022b7) 17 | ### [完善 VSCode 的 Node 自动补全](https://juejin.im/post/5add67986fb9a07ab83da106) 18 | ## [使用顶级 VSCode 扩展来加快开发 JavaScript](http://www.css88.com/archives/9507) 19 | ### [webpack 换肤功能多主题/配色样式打包解决方案](https://blog.hypers.io/2018/04/19/webpack-mutiple-theme-solution/) 20 | ### [二进制数据的操控](https://juejin.im/post/5adca4e0f265da0b767d0fb0) 21 | ### [JavaScript之内存泄漏](https://juejin.im/post/5ad8507cf265da50472fc93c) 22 | ### [Vue SPA项目 + Sentry 实现前端错误监控](https://juejin.im/post/5adb05fef265da0b79647421) 23 | ### [用CSS Houdini画一片星空](https://juejin.im/post/5adc091b51882567105f5586) 24 | ### [clip效果 仿qq空间广告效果](https://github.com/dxiaoqi/canvas-svg-) 25 | ### [如何监听数组变化?](https://juejin.im/post/5ade0e3df265da0b8e7f050b) 26 | ## [mac环境下使用Charles抓包Https请求](https://segmentfault.com/a/1190000005070614) 27 | ## [推荐2个前端工具:Charles和Postman](https://juejin.im/post/5ae73a4ff265da0b71560e7a) 28 | ### [chrome开发者工具各种骚技巧](https://juejin.im/post/5af53823f265da0b75282b0f) 29 | ### [Node 命令行前端自动构建发布系统](https://juejin.im/post/5b0527b0518825428630dc10) 30 | ### [JavaScript 算法与数据结构](https://github.com/trekhleb/javascript-algorithms/blob/master/README.zh-CN.md) 31 | ### [JavaScript中不得不说的断言?](https://juejin.im/post/5b1683bee51d4506d73f176b) 32 | ### [csv和excel读取和下载](https://juejin.im/post/5b1fdbcc5188257d571f2c62) 33 | ### [数字滚动特效](https://github.com/libin1991/number-flip) 34 | ### [前端 WebView 指南之调试篇](https://75team.com/post/webview-debug.html) 35 | ### [html2canvas的踩坑之路](https://juejin.im/post/5b31d98ee51d4558817e14f8) 36 | ### [wasm + ffmpeg实现前端截取视频帧功能](https://juejin.im/post/5b5c82c1e51d4534c34a4caf#heading-5) 37 | ## [js视频转canvas字符画](https://juejin.im/post/5b5ec60d6fb9a04f8a219a1d) 38 | ## [2018年值得关注的10大JavaScript动画库](https://www.zcfy.cc/article/10-javascript-animation-libraries-to-follow-in-2018) 39 | ### [降低代码复杂度神器之code-metrics-loader](https://juejin.im/post/5b83cbe5f265da433c64bf8e) 40 | ### [如何实现前端录音功能](https://juejin.im/post/5b8bf7e3e51d4538c210c6b0) 41 | ### [几个有用的Web API —— audioContext](https://denzel.netlify.com/js/useful_webapis_audiocontext.html?_=193678675665) 42 | ### [几个有用的Web API——全屏模式](https://denzel.netlify.com/js/useful_webapis_fullscreen.html) 43 | ### [六十行代码完成 四则运算 语法解析器](https://juejin.im/post/5b9756d26fb9a05d0f16c097) 44 | ## [“木偶”浏览器](https://juejin.im/post/5b9648e7e51d450e6321e3c5) 45 | # [CSS 变量和 JavaScript 让应用支持动态主题](https://juejin.im/post/5b9528de6fb9a05cf3710e00) 46 | ### [js-xlsx + handsontable + echarts实现excel上传编辑然后显示成图表](https://juejin.im/post/5b924d096fb9a05cf67a6971) 47 | # [javascript模拟鸟群使用cax和threejs渲染引擎](https://juejin.im/post/5b9351226fb9a05d3b334d54) 48 | ### [图像处理的滤镜算法](https://juejin.im/post/5b9e127df265da0a9a395e01) 49 | ### [自动解析 github仓库的目录列表](https://juejin.im/post/5bac98aaf265da0ac7270165) 50 | ### [实现前端弹簧动效](https://juejin.im/post/5bbb67456fb9a05d2c43c66a) 51 | ### [图片上传知识点梳理](https://juejin.im/post/5be023b651882516bc47762e) 52 | ## [H5 移动调试全攻略](http://jartto.wang/2018/11/01/mobile-debug/) 53 | ## [类似淘票票 选座功能(svg)](https://juejin.im/post/5bed39096fb9a049b3478caf) 54 | ## [[译] 你不知道的 console 命令](https://juejin.im/post/5bf64218e51d45194266acb7) 55 | ## [原生HTML + JS + CSS绘制简单折线柱状图](https://juejin.im/post/5bff5fc4518825275318935c) 56 | # [前端项目基于GitLab-CI的持续集成/持续部署(CI/CD)](https://juejin.im/post/5c015f4ae51d453244120d86) 57 | ### [前端开发神器Hype3初体验-可视化、响应式、动效](https://juejin.im/post/5c0a146d5188256f26413f51) 58 | ## [从天猫某活动视频3次请求说起](https://juejin.im/post/5c0e0f75e51d45410c5e1aea) 59 | ### [探索前端黑科技——通过 png 图的 rgba 值缓存数据](https://juejin.im/post/5c24ceeee51d4548ac6f7f61) 60 | ### [谈谈JS中的函数劫持](https://juejin.im/post/5c24cfd8f265da6144201c0a) 61 | ### [广告过滤器是怎么工作的](https://mp.weixin.qq.com/s?__biz=MzAxMDgyNDIyOQ==&mid=2650132697&idx=1&sn=051ceaec71d1ac0ca2d810dddeda25aa&chksm=834b0f93b43c868553783b41cc22944bc31c587f9004e9e0aa6f533c05e0cc87bbb45d6dd7f1&xtrack=1&scene=0&subscene=131&clicktime=1546585933&ascene=7&devicetype=android-25&version=27000034&nettype=WIFI&abtest_cookie=BAABAAoACwATABQABAAmlx4AV5keAJuZHgCcmR4AAAA=&lang=zh_CN&pass_ticket=wMbo7UfLPkZ++A6hVHsxFU8Zt7SiJgt3IVzhQl6MmtEawJuVL98rAz9KNMuwmvDc&wx_header=1) 62 | ### [iPhone刘海屏踩坑记录](https://juejin.im/post/5c32e3186fb9a049ab0dc600) 63 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /javascript进阶/Images/arguments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/arguments.png -------------------------------------------------------------------------------- /javascript进阶/Images/copy/copy1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/copy/copy1.png -------------------------------------------------------------------------------- /javascript进阶/Images/debounce/debounce-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/debounce/debounce-1.gif -------------------------------------------------------------------------------- /javascript进阶/Images/debounce/debounce-4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/debounce/debounce-4.gif -------------------------------------------------------------------------------- /javascript进阶/Images/debounce/debounce-cancel.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/debounce/debounce-cancel.gif -------------------------------------------------------------------------------- /javascript进阶/Images/debounce/debounce.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/debounce/debounce.gif -------------------------------------------------------------------------------- /javascript进阶/Images/debounce/event.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/debounce/event.png -------------------------------------------------------------------------------- /javascript进阶/Images/each/each1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/each/each1.png -------------------------------------------------------------------------------- /javascript进阶/Images/each/each2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/each/each2.png -------------------------------------------------------------------------------- /javascript进阶/Images/extend/extend1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/extend/extend1.png -------------------------------------------------------------------------------- /javascript进阶/Images/prototype1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/prototype1.png -------------------------------------------------------------------------------- /javascript进阶/Images/prototype2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/prototype2.png -------------------------------------------------------------------------------- /javascript进阶/Images/prototype3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/prototype3.png -------------------------------------------------------------------------------- /javascript进阶/Images/prototype4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/prototype4.png -------------------------------------------------------------------------------- /javascript进阶/Images/prototype5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/prototype5.png -------------------------------------------------------------------------------- /javascript进阶/Images/recursion/factorial.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/recursion/factorial.gif -------------------------------------------------------------------------------- /javascript进阶/Images/shuffle/fisher-yates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/shuffle/fisher-yates.png -------------------------------------------------------------------------------- /javascript进阶/Images/shuffle/mathRandom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/shuffle/mathRandom.png -------------------------------------------------------------------------------- /javascript进阶/Images/sort/bubble.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/sort/bubble.gif -------------------------------------------------------------------------------- /javascript进阶/Images/sort/insertion-vs-quick.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/sort/insertion-vs-quick.gif -------------------------------------------------------------------------------- /javascript进阶/Images/sort/insertion.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/sort/insertion.gif -------------------------------------------------------------------------------- /javascript进阶/Images/sort/quick1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/sort/quick1.png -------------------------------------------------------------------------------- /javascript进阶/Images/sort/quick2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/sort/quick2.png -------------------------------------------------------------------------------- /javascript进阶/Images/sort/quick3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/sort/quick3.png -------------------------------------------------------------------------------- /javascript进阶/Images/sort/quickSort-time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/sort/quickSort-time.png -------------------------------------------------------------------------------- /javascript进阶/Images/sort/quicksort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/sort/quicksort.gif -------------------------------------------------------------------------------- /javascript进阶/Images/sort/selection.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/sort/selection.gif -------------------------------------------------------------------------------- /javascript进阶/Images/template/template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/template/template.png -------------------------------------------------------------------------------- /javascript进阶/Images/throttle/throttle1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/throttle/throttle1.gif -------------------------------------------------------------------------------- /javascript进阶/Images/throttle/throttle2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/throttle/throttle2.gif -------------------------------------------------------------------------------- /javascript进阶/Images/throttle/throttle3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/throttle/throttle3.gif -------------------------------------------------------------------------------- /javascript进阶/Images/underscore/new-obj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/underscore/new-obj.png -------------------------------------------------------------------------------- /javascript进阶/Images/xss/sina_xss.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libin1991/libin_Blog/81cd776e9089023a0b709eaf79a2bb12fc62838a/javascript进阶/Images/xss/sina_xss.jpg -------------------------------------------------------------------------------- /javascript进阶/articles/专题系列文章/JavaScript专题之偏函数.md: -------------------------------------------------------------------------------- 1 | # JavaScript专题之偏函数 2 | 3 | ## 定义 4 | 5 | 维基百科中对偏函数 (Partial application) 的定义为: 6 | 7 | > In computer science, partial application (or partial function application) refers to the process of fixing a number of arguments to a function, producing another function of smaller arity. 8 | 9 | 翻译成中文: 10 | 11 | 在计算机科学中,局部应用是指固定一个函数的一些参数,然后产生另一个更小元的函数。 12 | 13 | 什么是元?元是指函数参数的个数,比如一个带有两个参数的函数被称为二元函数。 14 | 15 | 举个简单的例子: 16 | 17 | ```js 18 | function add(a, b) { 19 | return a + b; 20 | } 21 | 22 | // 执行 add 函数,一次传入两个参数即可 23 | add(1, 2) // 3 24 | 25 | // 假设有一个 partial 函数可以做到局部应用 26 | var addOne = partial(add, 1); 27 | 28 | addOne(2) // 3 29 | ``` 30 | 31 | 个人觉得翻译成“局部应用”或许更贴切些,以下全部使用“局部应用”。 32 | 33 | ## 柯里化与局部应用 34 | 35 | 如果看过上一篇文章[《JavaScript专题之柯里化》](https://github.com/mqyqingfeng/Blog/issues/42),实际上你会发现这个例子和柯里化太像了,所以两者到底是有什么区别呢? 36 | 37 | 其实也很明显: 38 | 39 | 柯里化是将一个多参数函数转换成多个单参数函数,也就是将一个 n 元函数转换成 n 个一元函数。 40 | 41 | 局部应用则是固定一个函数的一个或者多个参数,也就是将一个 n 元函数转换成一个 n - x 元函数。 42 | 43 | 如果说两者有什么关系的话,引用 [functional-programming-jargon](https://github.com/hemanth/functional-programming-jargon#partial-application) 中的描述就是: 44 | 45 | > Curried functions are automatically partially applied. 46 | 47 | ## partial 48 | 49 | 我们今天的目的是模仿 underscore 写一个 partial 函数,比起 curry 函数,这个显然简单了很多。 50 | 51 | 也许你在想我们可以直接使用 bind 呐,举个例子: 52 | 53 | ```js 54 | function add(a, b) { 55 | return a + b; 56 | } 57 | 58 | var addOne = add.bind(null, 1); 59 | 60 | addOne(2) // 3 61 | ``` 62 | 63 | 然而使用 bind 我们还是改变了 this 指向,我们要写一个不改变 this 指向的方法。 64 | 65 | ## 第一版 66 | 67 | 根据之前的表述,我们可以尝试着写出第一版: 68 | 69 | ```js 70 | // 第一版 71 | // 似曾相识的代码 72 | function partial(fn) { 73 | var args = [].slice.call(arguments, 1); 74 | return function() { 75 | var newArgs = args.concat([].slice.call(arguments)); 76 | return fn.apply(this, newArgs); 77 | }; 78 | }; 79 | ``` 80 | 81 | 我们来写个 demo 验证下 this 的指向: 82 | 83 | ```js 84 | function add(a, b) { 85 | return a + b + this.value; 86 | } 87 | 88 | // var addOne = add.bind(null, 1); 89 | var addOne = partial(add, 1); 90 | 91 | var value = 1; 92 | var obj = { 93 | value: 2, 94 | addOne: addOne 95 | } 96 | obj.addOne(2); // ??? 97 | // 使用 bind 时,结果为 4 98 | // 使用 partial 时,结果为 5 99 | ``` 100 | 101 | ## 第二版 102 | 103 | 然而正如 curry 函数可以使用占位符一样,我们希望 partial 函数也可以实现这个功能,我们再来写第二版: 104 | 105 | ```js 106 | // 第二版 107 | var _ = {}; 108 | 109 | function partial(fn) { 110 | var args = [].slice.call(arguments, 1); 111 | return function() { 112 | var position = 0, len = args.length; 113 | for(var i = 0; i < len; i++) { 114 | args[i] = args[i] === _ ? arguments[position++] : args[i] 115 | } 116 | while(position < arguments.length) args.push(argumetns[position++]); 117 | return fn.apply(this, args); 118 | }; 119 | }; 120 | ``` 121 | 122 | 我们验证一下: 123 | 124 | ```js 125 | var subtract = function(a, b) { return b - a; }; 126 | subFrom20 = partial(subtract, _, 20); 127 | subFrom20(5); 128 | ``` 129 | 130 | ## 写在最后 131 | 132 | 值得注意的是:underscore 和 lodash 都提供了 partial 函数,但只有 lodash 提供了 curry 函数。 133 | 134 | ## 专题系列 135 | 136 | JavaScript专题系列目录地址:[https://github.com/mqyqingfeng/Blog](https://github.com/mqyqingfeng/Blog)。 137 | 138 | JavaScript专题系列预计写二十篇左右,主要研究日常开发中一些功能点的实现,比如防抖、节流、去重、类型判断、拷贝、最值、扁平、柯里、递归、乱序、排序等,特点是研(chao)究(xi) underscore 和 jQuery 的实现方式。 139 | 140 | 如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎 star,对作者也是一种鼓励。 141 | -------------------------------------------------------------------------------- /javascript进阶/articles/专题系列文章/JavaScript专题之函数记忆.md: -------------------------------------------------------------------------------- 1 | # JavaScript 专题之函数记忆 2 | 3 | ## 定义 4 | 5 | 函数记忆是指将上次的计算结果缓存起来,当下次调用时,如果遇到相同的参数,就直接返回缓存中的数据。 6 | 7 | 举个例子: 8 | 9 | ```js 10 | function add(a, b) { 11 | return a + b; 12 | } 13 | 14 | // 假设 memorize 可以实现函数记忆 15 | var memoizedAdd = memorize(add); 16 | 17 | memoizedAdd(1, 2) // 3 18 | memoizedAdd(1, 2) // 相同的参数,第二次调用时,从缓存中取出数据,而非重新计算一次 19 | ``` 20 | 21 | ## 原理 22 | 23 | 实现这样一个 memorize 函数很简单,原理上只用把参数和对应的结果数据存到一个对象中,调用时,判断参数对应的数据是否存在,存在就返回对应的结果数据。 24 | 25 | ## 第一版 26 | 27 | 我们来写一版: 28 | 29 | ```js 30 | // 第一版 (来自《JavaScript权威指南》) 31 | function memoize(f) { 32 | var cache = {}; 33 | return function(){ 34 | var key = arguments.length + Array.prototype.join.call(arguments, ","); 35 | if (key in cache) { 36 | return cache[key] 37 | } 38 | else return cache[key] = f.apply(this, arguments) 39 | } 40 | } 41 | ``` 42 | 43 | 我们来测试一下: 44 | 45 | ```js 46 | var add = function(a, b, c) { 47 | return a + b + c 48 | } 49 | 50 | var memoizedAdd = memorize(add) 51 | 52 | console.time('use memorize') 53 | for(var i = 0; i < 100000; i++) { 54 | memoizedAdd(1, 2, 3) 55 | } 56 | console.timeEnd('use memorize') 57 | 58 | console.time('not use memorize') 59 | for(var i = 0; i < 100000; i++) { 60 | add(1, 2, 3) 61 | } 62 | console.timeEnd('not use memorize') 63 | ``` 64 | 65 | 在 Chrome 中,使用 memorize 大约耗时 60ms,如果我们不使用函数记忆,大约耗时 1.3 ms 左右。 66 | 67 | ## 注意 68 | 69 | 什么,我们使用了看似高大上的函数记忆,结果却更加耗时,这个例子近乎有 60 倍呢! 70 | 71 | 所以,函数记忆也并不是万能的,你看这个简单的场景,其实并不适合用函数记忆。 72 | 73 | 需要注意的是,函数记忆只是一种编程技巧,本质上是牺牲算法的空间复杂度以换取更优的时间复杂度,在客户端 JavaScript 中代码的执行时间复杂度往往成为瓶颈,因此在大多数场景下,这种牺牲空间换取时间的做法以提升程序执行效率的做法是非常可取的。 74 | 75 | ## 第二版 76 | 77 | 因为第一版使用了 join 方法,我们很容易想到当参数是对象的时候,就会自动调用 toString 方法转换成 `[Object object]`,再拼接字符串作为 key 值。我们写个 demo 验证一下这个问题: 78 | 79 | ```js 80 | var propValue = function(obj){ 81 | return obj.value 82 | } 83 | 84 | var memoizedAdd = memorize(propValue) 85 | 86 | console.log(memoizedAdd({value: 1})) // 1 87 | console.log(memoizedAdd({value: 2})) // 1 88 | ``` 89 | 90 | 两者都返回了 1,显然是有问题的,所以我们看看 underscore 的 memoize 函数是如何实现的: 91 | 92 | ```js 93 | // 第二版 (来自 underscore 的实现) 94 | var memorize = function(func, hasher) { 95 | var memoize = function(key) { 96 | var cache = memoize.cache; 97 | var address = '' + (hasher ? hasher.apply(this, arguments) : key); 98 | if (!cache[address]) { 99 | cache[address] = func.apply(this, arguments); 100 | } 101 | return cache[address]; 102 | }; 103 | memoize.cache = {}; 104 | return memoize; 105 | }; 106 | ``` 107 | 108 | 从这个实现可以看出,underscore 默认使用 function 的第一个参数作为 key,所以如果直接使用 109 | 110 | ```js 111 | var add = function(a, b, c) { 112 | return a + b + c 113 | } 114 | 115 | var memoizedAdd = memorize(add) 116 | 117 | memoizedAdd(1, 2, 3) // 6 118 | memoizedAdd(1, 2, 4) // 6 119 | ``` 120 | 121 | 肯定是有问题的,如果要支持多参数,我们就需要传入 hasher 函数,自定义存储的 key 值。所以我们考虑使用 JSON.stringify: 122 | 123 | ```js 124 | var memoizedAdd = memorize(add, function(){ 125 | var args = Array.prototype.slice.call(arguments) 126 | return JSON.stringify(args) 127 | }) 128 | 129 | console.log(memoizedAdd(1, 2, 3)) // 6 130 | console.log(memoizedAdd(1, 2, 4)) // 7 131 | ``` 132 | 133 | 如果使用 JSON.stringify,参数是对象的问题也可以得到解决,因为存储的是对象序列化后的字符串。 134 | 135 | ## 适用场景 136 | 137 | 我们以斐波那契数列为例: 138 | 139 | ```js 140 | var count = 0; 141 | var fibonacci = function(n){ 142 | count++; 143 | return n < 2? n : fibonacci(n-1) + fibonacci(n-2); 144 | }; 145 | for (var i = 0; i <= 10; i++){ 146 | fibonacci(i) 147 | } 148 | 149 | console.log(count) // 453 150 | ``` 151 | 152 | 我们会发现最后的 count 数为 453,也就是说 fibonacci 函数被调用了 453 次!也许你会想,我只是循环到了 10,为什么就被调用了这么多次,所以我们来具体分析下: 153 | 154 | ```js 155 | 当执行 fib(0) 时,调用 1 次 156 | 157 | 当执行 fib(1) 时,调用 1 次 158 | 159 | 当执行 fib(2) 时,相当于 fib(1) + fib(0) 加上 fib(2) 本身这一次,共 1 + 1 + 1 = 3 次 160 | 161 | 当执行 fib(3) 时,相当于 fib(2) + fib(1) 加上 fib(3) 本身这一次,共 3 + 1 + 1 = 5 次 162 | 163 | 当执行 fib(4) 时,相当于 fib(3) + fib(2) 加上 fib(4) 本身这一次,共 5 + 3 + 1 = 9 次 164 | 165 | 当执行 fib(5) 时,相当于 fib(4) + fib(3) 加上 fib(5) 本身这一次,共 9 + 5 + 1 = 15 次 166 | 167 | 当执行 fib(6) 时,相当于 fib(5) + fib(4) 加上 fib(6) 本身这一次,共 15 + 9 + 1 = 25 次 168 | 169 | 当执行 fib(7) 时,相当于 fib(6) + fib(5) 加上 fib(7) 本身这一次,共 25 + 15 + 1 = 41 次 170 | 171 | 当执行 fib(8) 时,相当于 fib(7) + fib(6) 加上 fib(8) 本身这一次,共 41 + 25 + 1 = 67 次 172 | 173 | 当执行 fib(9) 时,相当于 fib(8) + fib(7) 加上 fib(9) 本身这一次,共 67 + 41 + 1 = 109 次 174 | 175 | 当执行 fib(10) 时,相当于 fib(9) + fib(8) 加上 fib(10) 本身这一次,共 109 + 67 + 1 = 177 次 176 | ``` 177 | 178 | 所以执行的总次数为:177 + 109 + 67 + 41 + 25 + 15 + 9 + 5 + 3 + 1 + 1 = 453 次! 179 | 180 | 如果我们使用函数记忆呢? 181 | 182 | ```js 183 | var count = 0; 184 | var fibonacci = function(n) { 185 | count++; 186 | return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); 187 | }; 188 | 189 | fibonacci = memorize(fibonacci) 190 | 191 | for (var i = 0; i <= 10; i++) { 192 | fibonacci(i) 193 | } 194 | 195 | console.log(count) // 12 196 | ``` 197 | 198 | 我们会发现最后的总次数为 12 次,因为使用了函数记忆,调用次数从 453 次降低为了 12 次! 199 | 200 | 兴奋的同时不要忘记思考:为什么会是 12 次呢? 201 | 202 | 从 0 到 10 的结果各储存一遍,应该是 11 次呐?咦,那多出来的一次是从哪里来的? 203 | 204 | 所以我们还需要认真看下我们的写法,在我们的写法中,其实我们用生成的 fibonacci 函数覆盖了原本了 fibonacci 函数,当我们执行 fibonacci(0) 时,执行一次函数,cache 为 {0: 0},但是当我们执行 fibonacci(2) 的时候,执行 fibonacci(1) + fibonacci(0),因为 fibonacci(0) 的值为 0,`!cache[address]` 的结果为 true,又会执行一次 fibonacci 函数。原来,多出来的那一次是在这里! 205 | 206 | ## 多说一句 207 | 208 | 也许你会觉得在日常开发中又用不到 fibonacci,这个例子感觉实用价值不高呐,其实,这个例子是用来表明一种使用的场景,也就是如果需要大量重复的计算,或者大量计算又依赖于之前的结果,便可以考虑使用函数记忆。而这种场景,当你遇到的时候,你就会知道的。 209 | 210 | ## 专题系列 211 | 212 | JavaScript专题系列目录地址:[https://github.com/mqyqingfeng/Blog](https://github.com/mqyqingfeng/Blog)。 213 | 214 | JavaScript专题系列预计写二十篇左右,主要研究日常开发中一些功能点的实现,比如防抖、节流、去重、类型判断、拷贝、最值、扁平、柯里、递归、乱序、排序等,特点是研(chao)究(xi) underscore 和 jQuery 的实现方式。 215 | 216 | 如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎 star,对作者也是一种鼓励。 217 | -------------------------------------------------------------------------------- /javascript进阶/articles/专题系列文章/JavaScript专题之如何求数组的最大值和最小值.md: -------------------------------------------------------------------------------- 1 | # JavaScript专题之如何求数组的最大值和最小值 2 | 3 | ## 前言 4 | 5 | 取出数组中的最大值或者最小值是开发中常见的需求,但你能想出几种方法来实现这个需求呢? 6 | 7 | ## Math.max 8 | 9 | JavaScript 提供了 Math.max 函数返回一组数中的最大值,用法是: 10 | 11 | ```js 12 | Math.max([value1[,value2, ...]]) 13 | ``` 14 | 15 | 值得注意的是: 16 | 17 | 1. 如果有任一参数不能被转换为数值,则结果为 NaN。 18 | 2. max 是 Math 的静态方法,所以应该像这样使用:Math.max(),而不是作为 Math 实例的方法 (简单的来说,就是不使用 new ) 19 | 3. 如果没有参数,则结果为 `-Infinity` (注意是负无穷大) 20 | 21 | 而我们需要分析的是: 22 | 23 | 1.如果任一参数不能被转换为数值,这就意味着如果参数可以被转换成数字,就是可以进行比较的,比如: 24 | 25 | ```js 26 | Math.max(true, 0) // 1 27 | Math.max(true, '2', null) // 2 28 | Math.max(1, undefined) // NaN 29 | Math.max(1, {}) // NaN 30 | ``` 31 | 32 | 2.如果没有参数,则结果为 -Infinity,对应的,Math.min 函数,如果没有参数,则结果为 Infinity,所以: 33 | 34 | ```js 35 | var min = Math.min(); 36 | var max = Math.max(); 37 | console.log(min > max); 38 | ``` 39 | 40 | 了解了 Math.max 方法,我们以求数组最大值的为例,思考有哪些方法可以实现这个需求。 41 | 42 | ## 原始方法 43 | 44 | 最最原始的方法,莫过于循环遍历一遍: 45 | 46 | ```js 47 | var arr = [6, 4, 1, 8, 2, 11, 23]; 48 | 49 | var result = arr[0]; 50 | for (var i = 1; i < arr.length; i++) { 51 | result = Math.max(result, arr[i]); 52 | } 53 | console.log(result); 54 | ``` 55 | 56 | ## reduce 57 | 58 | 既然是通过遍历数组求出一个最终值,那么我们就可以使用 reduce 方法: 59 | 60 | ```js 61 | var arr = [6, 4, 1, 8, 2, 11, 23]; 62 | 63 | function max(prev, next) { 64 | return Math.max(prev, next); 65 | } 66 | console.log(arr.reduce(max)); 67 | ``` 68 | 69 | ## 排序 70 | 71 | 如果我们先对数组进行一次排序,那么最大值就是最后一个值: 72 | 73 | ```js 74 | var arr = [6, 4, 1, 8, 2, 11, 23]; 75 | 76 | arr.sort(function(a,b){return a - b;}); 77 | console.log(arr[arr.length - 1]) 78 | ``` 79 | 80 | ## eval 81 | 82 | Math.max 支持传多个参数来进行比较,那么我们如何将一个数组转换成参数传进 Math.max 函数呢?eval 便是一种 83 | 84 | ```js 85 | var arr = [6, 4, 1, 8, 2, 11, 23]; 86 | 87 | var max = eval("Math.max(" + arr + ")"); 88 | console.log(max) 89 | ``` 90 | 91 | ## apply 92 | 93 | 使用 apply 是另一种。 94 | 95 | ```js 96 | var arr = [6, 4, 1, 8, 2, 11, 23]; 97 | console.log(Math.max.apply(null, arr)) 98 | ``` 99 | 100 | ## ES6 ... 101 | 102 | 使用 ES6 的扩展运算符: 103 | 104 | ```js 105 | var arr = [6, 4, 1, 8, 2, 11, 23]; 106 | console.log(Math.max(...arr)) 107 | ``` 108 | 109 | 有更多的方法欢迎留言哈~ 110 | 111 | ## 专题系列 112 | 113 | JavaScript专题系列目录地址:[https://github.com/mqyqingfeng/Blog](https://github.com/mqyqingfeng/Blog)。 114 | 115 | JavaScript专题系列预计写二十篇左右,主要研究日常开发中一些功能点的实现,比如防抖、节流、去重、类型判断、拷贝、最值、扁平、柯里、递归、乱序、排序等,特点是研(chao)究(xi) underscore 和 jQuery 的实现方式。 116 | 117 | 如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎 star,对作者也是一种鼓励。 -------------------------------------------------------------------------------- /javascript进阶/articles/专题系列文章/JavaScript专题之惰性函数.md: -------------------------------------------------------------------------------- 1 | # JavaScript专题之惰性函数 2 | 3 | ## 需求 4 | 5 | 我们现在需要写一个 foo 函数,这个函数返回首次调用时的 Date 对象,注意是首次。 6 | 7 | ## 解决一:普通方法 8 | 9 | ```js 10 | var t; 11 | function foo() { 12 | if (t) return t; 13 | t = new Date() 14 | return t; 15 | } 16 | ``` 17 | 18 | 问题有两个,一是污染了全局变量,二是每次调用 foo 的时候都需要进行一次判断。 19 | 20 | ## 解决二:闭包 21 | 22 | 我们很容易想到用闭包避免污染全局变量。 23 | 24 | ```js 25 | var foo = (function() { 26 | var t; 27 | return function() { 28 | if (t) return t; 29 | t = new Date(); 30 | return t; 31 | } 32 | })(); 33 | ``` 34 | 35 | 然而还是没有解决调用时都必须进行一次判断的问题。 36 | 37 | ## 解决三:函数对象 38 | 39 | 函数也是一种对象,利用这个特性,我们也可以解决这个问题。 40 | 41 | ```js 42 | function foo() { 43 | if (foo.t) return foo.t; 44 | foo.t = new Date(); 45 | return foo.t; 46 | } 47 | ``` 48 | 49 | 依旧没有解决调用时都必须进行一次判断的问题。 50 | 51 | ## 解决四:惰性函数 52 | 53 | 不错,惰性函数就是解决每次都要进行判断的这个问题,解决原理很简单,重写函数。 54 | 55 | ```js 56 | var foo = function() { 57 | var t = new Date(); 58 | foo = function() { 59 | return t; 60 | }; 61 | return foo(); 62 | }; 63 | ``` 64 | 65 | ## 更多应用 66 | 67 | DOM 事件添加中,为了兼容现代浏览器和 IE 浏览器,我们需要对浏览器环境进行一次判断: 68 | 69 | ```js 70 | // 简化写法 71 | function addEvent (type, el, fn) { 72 | if (window.addEventListener) { 73 | el.addEventListener(type, fn, false); 74 | } 75 | else if(window.attachEvent){ 76 | el.attachEvent('on' + type, fn); 77 | } 78 | } 79 | ``` 80 | 81 | 问题在于我们每当使用一次 addEvent 时都会进行一次判断。 82 | 83 | 利用惰性函数,我们可以这样做: 84 | 85 | ```js 86 | function addEvent (type, el, fn) { 87 | if (window.addEventListener) { 88 | addEvent = function (type, el, fn) { 89 | el.addEventListener(type, fn, false); 90 | } 91 | } 92 | else if(window.attachEvent){ 93 | addEvent = function (type, el, fn) { 94 | el.attachEvent('on' + type, fn); 95 | } 96 | } 97 | } 98 | ``` 99 | 100 | 当然我们也可以使用闭包的形式: 101 | 102 | ```js 103 | var addEvent = (function(){ 104 | if (window.addEventListener) { 105 | return function (type, el, fn) { 106 | el.addEventListener(type, fn, false); 107 | } 108 | } 109 | else if(window.attachEvent){ 110 | return function (type, el, fn) { 111 | el.attachEvent('on' + type, fn); 112 | } 113 | } 114 | })(); 115 | ``` 116 | 117 | 当我们每次都需要进行条件判断,其实只需要判断一次,接下来的使用方式都不会发生改变的时候,想想是否可以考虑使用惰性函数。 118 | 119 | ## 重要参考 120 | 121 | [Lazy Function Definition Pattern](http://peter.michaux.ca/articles/lazy-function-definition-pattern) 122 | 123 | ## 专题系列 124 | 125 | JavaScript专题系列目录地址:[https://github.com/mqyqingfeng/Blog](https://github.com/mqyqingfeng/Blog)。 126 | 127 | JavaScript专题系列预计写二十篇左右,主要研究日常开发中一些功能点的实现,比如防抖、节流、去重、类型判断、拷贝、最值、扁平、柯里、递归、乱序、排序等,特点是研(chao)究(xi) underscore 和 jQuery 的实现方式。 128 | 129 | 如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎 star,对作者也是一种鼓励。 -------------------------------------------------------------------------------- /javascript进阶/articles/专题系列文章/JavaScript专题之深浅拷贝.md: -------------------------------------------------------------------------------- 1 | # JavaScript专题之深浅拷贝 2 | 3 | ## 前言 4 | 5 | 拷贝也是面试经典呐! 6 | 7 | ## 数组的浅拷贝 8 | 9 | 如果是数组,我们可以利用数组的一些方法比如:slice、concat 返回一个新数组的特性来实现拷贝。 10 | 11 | 比如: 12 | 13 | ```js 14 | var arr = ['old', 1, true, null, undefined]; 15 | 16 | var new_arr = arr.concat(); 17 | 18 | new_arr[0] = 'new'; 19 | 20 | console.log(arr) // ["old", 1, true, null, undefined] 21 | console.log(new_arr) // ["new", 1, true, null, undefined] 22 | ``` 23 | 24 | 用 slice 可以这样做: 25 | 26 | ```js 27 | var new_arr = arr.slice(); 28 | ``` 29 | 30 | 但是如果数组嵌套了对象或者数组的话,比如: 31 | 32 | ```js 33 | var arr = [{old: 'old'}, ['old']]; 34 | 35 | var new_arr = arr.concat(); 36 | 37 | arr[0].old = 'new'; 38 | arr[1][0] = 'new'; 39 | 40 | console.log(arr) // [{old: 'new'}, ['new']] 41 | console.log(new_arr) // [{old: 'new'}, ['new']] 42 | ``` 43 | 44 | 我们会发现,无论是新数组还是旧数组都发生了变化,也就是说使用 concat 方法,克隆的并不彻底。 45 | 46 | 如果数组元素是基本类型,就会拷贝一份,互不影响,而如果是对象或者数组,就会只拷贝对象和数组的引用,这样我们无论在新旧数组进行了修改,两者都会发生变化。 47 | 48 | 我们把这种复制引用的拷贝方法称之为浅拷贝,与之对应的就是深拷贝,深拷贝就是指完全的拷贝一个对象,即使嵌套了对象,两者也相互分离,修改一个对象的属性,也不会影响另一个。 49 | 50 | 所以我们可以看出使用 concat 和 slice 是一种浅拷贝。 51 | 52 | ## 数组的深拷贝 53 | 54 | 那如何深拷贝一个数组呢?这里介绍一个技巧,不仅适用于数组还适用于对象!那就是: 55 | 56 | ```js 57 | var arr = ['old', 1, true, ['old1', 'old2'], {old: 1}] 58 | 59 | var new_arr = JSON.parse( JSON.stringify(arr) ); 60 | 61 | console.log(new_arr); 62 | ``` 63 | 64 | 是一个简单粗暴的好方法,就是有一个问题,不能拷贝函数,我们做个试验: 65 | 66 | ```js 67 | var arr = [function(){ 68 | console.log(a) 69 | }, { 70 | b: function(){ 71 | console.log(b) 72 | } 73 | }] 74 | 75 | var new_arr = JSON.parse(JSON.stringify(arr)); 76 | 77 | console.log(new_arr); 78 | ``` 79 | 80 | 我们会发现 new_arr 变成了: 81 | 82 | ![不能拷贝函数](https://github.com/mqyqingfeng/Blog/raw/master/Images/copy/copy1.png) 83 | 84 | ## 浅拷贝的实现 85 | 86 | 以上三个方法 concat、slice、JSON.stringify 都算是技巧类,可以根据实际项目情况选择使用,接下来我们思考下如何实现一个对象或者数组的浅拷贝。 87 | 88 | 想一想,好像很简单,遍历对象,然后把属性和属性值都放在一个新的对象不就好了~ 89 | 90 | 嗯,就是这么简单,注意几个小点就可以了: 91 | 92 | ```js 93 | var shallowCopy = function(obj) { 94 | // 只拷贝对象 95 | if (typeof obj !== 'object') return; 96 | // 根据obj的类型判断是新建一个数组还是对象 97 | var newObj = obj instanceof Array ? [] : {}; 98 | // 遍历obj,并且判断是obj的属性才拷贝 99 | for (var key in obj) { 100 | if (obj.hasOwnProperty(key)) { 101 | newObj[key] = obj[key]; 102 | } 103 | } 104 | return newObj; 105 | } 106 | ``` 107 | 108 | ## 深拷贝的实现 109 | 110 | 那如何实现一个深拷贝呢?说起来也好简单,我们在拷贝的时候判断一下属性值的类型,如果是对象,我们递归调用深拷贝函数不就好了~ 111 | 112 | ```js 113 | var deepCopy = function(obj) { 114 | if (typeof obj !== 'object') return; 115 | var newObj = obj instanceof Array ? [] : {}; 116 | for (var key in obj) { 117 | if (obj.hasOwnProperty(key)) { 118 | newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]; 119 | } 120 | } 121 | return newObj; 122 | } 123 | ``` 124 | 125 | ## 性能问题 126 | 127 | 尽管使用深拷贝会完全的克隆一个新对象,不会产生副作用,但是深拷贝因为使用递归,性能会不如浅拷贝,在开发中,还是要根据实际情况进行选择。 128 | 129 | ## 下期预告 130 | 131 | 难道到这里就结束了?是的。然而本篇实际上是一个铺垫,我们真正要看的是 jquery 的 extend 函数的实现,下一篇,我们会讲一讲如何从零实现一个 jquery 的 extend 函数。 132 | 133 | ## 专题系列 134 | 135 | JavaScript专题系列目录地址:[https://github.com/mqyqingfeng/Blog](https://github.com/mqyqingfeng/Blog)。 136 | 137 | JavaScript专题系列预计写二十篇左右,主要研究日常开发中一些功能点的实现,比如防抖、节流、去重、类型判断、拷贝、最值、扁平、柯里、递归、乱序、排序等,特点是研(chao)究(xi) underscore 和 jQuery 的实现方式。 138 | 139 | 如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎 star,对作者也是一种鼓励。 140 | -------------------------------------------------------------------------------- /javascript进阶/articles/深入系列文章/JavaScript深入之new的模拟实现.md: -------------------------------------------------------------------------------- 1 | # JavaScript深入之new的模拟实现 2 | 3 | > JavaScript深入系列第十二篇,通过new的模拟实现,带大家揭开使用new获得构造函数实例的真相 4 | 5 | ## new 6 | 7 | 一句话介绍 new: 8 | 9 | > new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象类型之一 10 | 11 | 也许有点难懂,我们在模拟 new 之前,先看看 new 实现了哪些功能。 12 | 13 | 举个例子: 14 | 15 | ```js 16 | // Otaku 御宅族,简称宅 17 | function Otaku (name, age) { 18 | this.name = name; 19 | this.age = age; 20 | 21 | this.habit = 'Games'; 22 | } 23 | 24 | // 因为缺乏锻炼的缘故,身体强度让人担忧 25 | Otaku.prototype.strength = 60; 26 | 27 | Otaku.prototype.sayYourName = function () { 28 | console.log('I am ' + this.name); 29 | } 30 | 31 | var person = new Otaku('Kevin', '18'); 32 | 33 | console.log(person.name) // Kevin 34 | console.log(person.habit) // Games 35 | console.log(person.strength) // 60 36 | 37 | person.sayYourName(); // I am Kevin 38 | ``` 39 | 40 | 从这个例子中,我们可以看到,实例 person 可以: 41 | 42 | 1. 访问到 Otaku 构造函数里的属性 43 | 2. 访问到 Otaku.prototype 中的属性 44 | 45 | 接下来,我们可以尝试着模拟一下了。 46 | 47 | 因为 new 是关键字,所以无法像 bind 函数一样直接覆盖,所以我们写一个函数,命名为 objectFactory,来模拟 new 的效果。用的时候是这样的: 48 | 49 | ```js 50 | function Otaku () { 51 | …… 52 | } 53 | 54 | // 使用 new 55 | var person = new Otaku(……); 56 | // 使用 objectFactory 57 | var person = objectFactory(Otaku, ……) 58 | ``` 59 | 60 | ## 初步实现 61 | 62 | 分析: 63 | 64 | 因为 new 的结果是一个新对象,所以在模拟实现的时候,我们也要建立一个新对象,假设这个对象叫 obj,因为 obj 会具有 Otaku 构造函数里的属性,想想经典继承的例子,我们可以使用 Otaku.apply(obj, arguments)来给 obj 添加新的属性。 65 | 66 | 在 JavaScript 深入系列第一篇中,我们便讲了原型与原型链,我们知道实例的 \_\_proto\_\_ 属性会指向构造函数的 prototype,也正是因为建立起这样的关系,实例可以访问原型上的属性。 67 | 68 | 现在,我们可以尝试着写第一版了: 69 | 70 | ```js 71 | // 第一版代码 72 | function objectFactory() { 73 | 74 | var obj = new Object(), 75 | 76 | Constructor = [].shift.call(arguments); 77 | 78 | obj.__proto__ = Constructor.prototype; 79 | 80 | Constructor.apply(obj, arguments); 81 | 82 | return obj; 83 | 84 | }; 85 | ``` 86 | 87 | 在这一版中,我们: 88 | 89 | 1. 用new Object() 的方式新建了一个对象 obj 90 | 2. 取出第一个参数,就是我们要传入的构造函数。此外因为 shift 会修改原数组,所以 arguments 会被去除第一个参数 91 | 3. 将 obj 的原型指向构造函数,这样 obj 就可以访问到构造函数原型中的属性 92 | 4. 使用 apply,改变构造函数 this 的指向到新建的对象,这样 obj 就可以访问到构造函数中的属性 93 | 5. 返回 obj 94 | 95 | 更多关于: 96 | 97 | 原型与原型链,可以看[《JavaScript深入之从原型到原型链》](https://github.com/mqyqingfeng/Blog/issues/2) 98 | 99 | apply,可以看[《JavaScript深入之call和apply的模拟实现》](https://github.com/mqyqingfeng/Blog/issues/11) 100 | 101 | 经典继承,可以看[《JavaScript深入之继承》](https://github.com/mqyqingfeng/Blog/issues/16) 102 | 103 | 复制以下的代码,到浏览器中,我们可以做一下测试: 104 | 105 | ```js 106 | function Otaku (name, age) { 107 | this.name = name; 108 | this.age = age; 109 | 110 | this.habit = 'Games'; 111 | } 112 | 113 | Otaku.prototype.strength = 60; 114 | 115 | Otaku.prototype.sayYourName = function () { 116 | console.log('I am ' + this.name); 117 | } 118 | 119 | function objectFactory() { 120 | var obj = new Object(), 121 | Constructor = [].shift.call(arguments); 122 | obj.__proto__ = Constructor.prototype; 123 | Constructor.apply(obj, arguments); 124 | return obj; 125 | }; 126 | 127 | var person = objectFactory(Otaku, 'Kevin', '18') 128 | 129 | console.log(person.name) // Kevin 130 | console.log(person.habit) // Games 131 | console.log(person.strength) // 60 132 | 133 | person.sayYourName(); // I am Kevin 134 | ``` 135 | 136 | []\~( ̄▽ ̄)\~** 137 | 138 | ## 返回值效果实现 139 | 140 | 接下来我们再来看一种情况,假如构造函数有返回值,举个例子: 141 | 142 | ```js 143 | function Otaku (name, age) { 144 | this.strength = 60; 145 | this.age = age; 146 | 147 | return { 148 | name: name, 149 | habit: 'Games' 150 | } 151 | } 152 | 153 | var person = new Otaku('Kevin', '18'); 154 | 155 | console.log(person.name) // Kevin 156 | console.log(person.habit) // Games 157 | console.log(person.strength) // undefined 158 | console.log(person.age) // undefined 159 | 160 | ``` 161 | 162 | 在这个例子中,构造函数返回了一个对象,在实例 person 中只能访问返回的对象中的属性。 163 | 164 | 而且还要注意一点,在这里我们是返回了一个对象,假如我们只是返回一个基本类型的值呢? 165 | 166 | 再举个例子: 167 | 168 | ```js 169 | function Otaku (name, age) { 170 | this.strength = 60; 171 | this.age = age; 172 | 173 | return 'handsome boy'; 174 | } 175 | 176 | var person = new Otaku('Kevin', '18'); 177 | 178 | console.log(person.name) // undefined 179 | console.log(person.habit) // undefined 180 | console.log(person.strength) // 60 181 | console.log(person.age) // 18 182 | ``` 183 | 184 | 结果完全颠倒过来,这次尽管有返回值,但是相当于没有返回值进行处理。 185 | 186 | 所以我们还需要判断返回的值是不是一个对象,如果是一个对象,我们就返回这个对象,如果没有,我们该返回什么就返回什么。 187 | 188 | 再来看第二版的代码,也是最后一版的代码: 189 | 190 | ```js 191 | // 第二版的代码 192 | function objectFactory() { 193 | 194 | var obj = new Object(), 195 | 196 | Constructor = [].shift.call(arguments); 197 | 198 | obj.__proto__ = Constructor.prototype; 199 | 200 | var ret = Constructor.apply(obj, arguments); 201 | 202 | return typeof ret === 'object' ? ret : obj; 203 | 204 | }; 205 | ``` 206 | 207 | ## 下一篇文章 208 | 209 | [JavaScript深入之类数组对象与arguments](https://github.com/mqyqingfeng/Blog/issues/14) 210 | 211 | ## 相关链接 212 | 213 | [《JavaScript深入之从原型到原型链》](https://github.com/mqyqingfeng/Blog/issues/2) 214 | 215 | [《JavaScript深入之call和apply的模拟实现》](https://github.com/mqyqingfeng/Blog/issues/11) 216 | 217 | [《JavaScript深入之继承》](https://github.com/mqyqingfeng/Blog/issues/16) 218 | 219 | ## 深入系列 220 | 221 | JavaScript深入系列目录地址:[https://github.com/mqyqingfeng/Blog](https://github.com/mqyqingfeng/Blog)。 222 | 223 | JavaScript深入系列预计写十五篇左右,旨在帮大家捋顺JavaScript底层知识,重点讲解如原型、作用域、执行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、继承等难点概念。 224 | 225 | 如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎star,对作者也是一种鼓励。 -------------------------------------------------------------------------------- /javascript进阶/articles/深入系列文章/JavaScript深入之从原型到原型链.md: -------------------------------------------------------------------------------- 1 | # JavaScript深入之从原型到原型链 2 | 3 | >JavaScript深入系列的第一篇,从原型与原型链开始讲起,如果你想知道构造函数的实例的原型,原型的原型,原型的原型的原型是什么,就来看看这篇文章吧。 4 | 5 | ## 构造函数创建对象 6 | 7 | 我们先使用构造函数创建一个对象: 8 | 9 | ```js 10 | function Person() { 11 | 12 | } 13 | var person = new Person(); 14 | person.name = 'Kevin'; 15 | console.log(person.name) // Kevin 16 | ``` 17 | 18 | 在这个例子中,Person 就是一个构造函数,我们使用 new 创建了一个实例对象 person。 19 | 20 | 很简单吧,接下来进入正题: 21 | 22 | ## prototype 23 | 24 | 每个函数都有一个 prototype 属性,就是我们经常在各种例子中看到的那个 prototype ,比如: 25 | 26 | ```js 27 | function Person() { 28 | 29 | } 30 | // 虽然写在注释里,但是你要注意: 31 | // prototype是函数才会有的属性 32 | Person.prototype.name = 'Kevin'; 33 | var person1 = new Person(); 34 | var person2 = new Person(); 35 | console.log(person1.name) // Kevin 36 | console.log(person2.name) // Kevin 37 | ``` 38 | 39 | 那这个函数的 prototype 属性到底指向的是什么呢?是这个函数的原型吗? 40 | 41 | 其实,函数的 prototype 属性指向了一个对象,这个对象正是调用该构造函数而创建的**实例**的原型,也就是这个例子中的 person1 和 person2 的原型。 42 | 43 | 那什么是原型呢?你可以这样理解:每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。 44 | 45 | 让我们用一张图表示构造函数和实例原型之间的关系: 46 | 47 | ![构造函数和实例原型的关系图](https://github.com/mqyqingfeng/Blog/raw/master/Images/prototype1.png) 48 | 49 | 在这张图中我们用 Object.prototype 表示实例原型。 50 | 51 | 那么我们该怎么表示实例与实例原型,也就是 person 和 Person.prototype 之间的关系呢,这时候我们就要讲到第二个属性: 52 | 53 | ## \_\_proto\_\_ 54 | 55 | 这是每一个JavaScript对象(除了 null )都具有的一个属性,叫\_\_proto\_\_,这个属性会指向该对象的原型。 56 | 57 | 为了证明这一点,我们可以在火狐或者谷歌中输入: 58 | 59 | ```js 60 | function Person() { 61 | 62 | } 63 | var person = new Person(); 64 | console.log(person.__proto__ === Person.prototype); // true 65 | ``` 66 | 67 | 于是我们更新下关系图: 68 | 69 | ![实例与实例原型的关系图](https://github.com/mqyqingfeng/Blog/raw/master/Images/prototype2.png) 70 | 71 | 既然实例对象和构造函数都可以指向原型,那么原型是否有属性指向构造函数或者实例呢? 72 | 73 | ## constructor 74 | 75 | 指向实例倒是没有,因为一个构造函数可以生成多个实例,但是原型指向构造函数倒是有的,这就要讲到第三个属性:constructor,每个原型都有一个 constructor 属性指向关联的构造函数。 76 | 77 | 为了验证这一点,我们可以尝试: 78 | 79 | ```js 80 | function Person() { 81 | 82 | } 83 | console.log(Person === Person.prototype.constructor); // true 84 | ``` 85 | 86 | 所以再更新下关系图: 87 | 88 | ![实例原型与构造函数的关系图](https://github.com/mqyqingfeng/Blog/raw/master/Images/prototype3.png) 89 | 90 | 综上我们已经得出: 91 | 92 | ```js 93 | function Person() { 94 | 95 | } 96 | 97 | var person = new Person(); 98 | 99 | console.log(person.__proto__ == Person.prototype) // true 100 | console.log(Person.prototype.constructor == Person) // true 101 | // 顺便学习一个ES5的方法,可以获得对象的原型 102 | console.log(Object.getPrototypeOf(person) === Person.prototype) // true 103 | ``` 104 | 105 | 了解了构造函数、实例原型、和实例之间的关系,接下来我们讲讲实例和原型的关系: 106 | 107 | ## 实例与原型 108 | 109 | 当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。 110 | 111 | 举个例子: 112 | 113 | ```js 114 | function Person() { 115 | 116 | } 117 | 118 | Person.prototype.name = 'Kevin'; 119 | 120 | var person = new Person(); 121 | 122 | person.name = 'Daisy'; 123 | console.log(person.name) // Daisy 124 | 125 | delete person.name; 126 | console.log(person.name) // Kevin 127 | ``` 128 | 129 | 在这个例子中,我们给实例对象 person 添加了 name 属性,当我们打印 person.name 的时候,结果自然为 Daisy。 130 | 131 | 但是当我们删除了 person 的 name 属性时,读取 person.name,从 person 对象中找不到 name 属性就会从 person 的原型也就是 person.\_\_proto\_\_ ,也就是 Person.prototype中查找,幸运的是我们找到了 name 属性,结果为 Kevin。 132 | 133 | 但是万一还没有找到呢?原型的原型又是什么呢? 134 | 135 | ## 原型的原型 136 | 137 | 在前面,我们已经讲了原型也是一个对象,既然是对象,我们就可以用最原始的方式创建它,那就是: 138 | 139 | ```js 140 | var obj = new Object(); 141 | obj.name = 'Kevin' 142 | console.log(obj.name) // Kevin 143 | ``` 144 | 145 | 所以原型对象是通过 Object 构造函数生成的,结合之前所讲,实例的 \_\_proto\_\_ 指向构造函数的 prototype ,所以我们再更新下关系图: 146 | 147 | ![原型的原型关系图](https://github.com/mqyqingfeng/Blog/raw/master/Images/prototype4.png) 148 | 149 | ## 原型链 150 | 151 | 那 Object.prototype 的原型呢? 152 | 153 | null,我们可以打印: 154 | 155 | ```js 156 | console.log(Object.prototype.__proto__ === null) // true 157 | ``` 158 | 159 | 然而 null 究竟代表了什么呢? 160 | 161 | 引用阮一峰老师的 [《undefined与null的区别》](http://www.ruanyifeng.com/blog/2014/03/undefined-vs-null.html) 就是: 162 | 163 | > null 表示“没有对象”,即该处不应该有值。 164 | 165 | 所以 Object.prototype.\_\_proto\_\_ 的值为 null 跟 Object.prototype 没有原型,其实表达了一个意思。 166 | 167 | 所以查找属性的时候查到 Object.prototype 就可以停止查找了。 168 | 169 | 最后一张关系图也可以更新为: 170 | 171 | ![原型链示意图](https://github.com/mqyqingfeng/Blog/raw/master/Images/prototype5.png) 172 | 173 | 顺便还要说一下,图中由相互关联的原型组成的链状结构就是原型链,也就是蓝色的这条线。 174 | 175 | ## 补充 176 | 177 | 最后,补充三点大家可能不会注意的地方: 178 | 179 | ### constructor 180 | 181 | 首先是 constructor 属性,我们看个例子: 182 | 183 | ```js 184 | function Person() { 185 | 186 | } 187 | var person = new Person(); 188 | console.log(person.constructor === Person); // true 189 | ``` 190 | 191 | 当获取 person.constructor 时,其实 person 中并没有 constructor 属性,当不能读取到constructor 属性时,会从 person 的原型也就是 Person.prototype 中读取,正好原型中有该属性,所以: 192 | 193 | ```js 194 | person.constructor === Person.prototype.constructor 195 | ``` 196 | 197 | ### \_\_proto\_\_ 198 | 199 | 其次是 \_\_proto\_\_ ,绝大部分浏览器都支持这个非标准的方法访问原型,然而它并不存在于 Person.prototype 中,实际上,它是来自于 Object.prototype ,与其说是一个属性,不如说是一个 getter/setter,当使用 obj.\_\_proto\_\_ 时,可以理解成返回了 Object.getPrototypeOf(obj)。 200 | 201 | ### 真的是继承吗? 202 | 203 | 最后是关于继承,前面我们讲到“每一个对象都会从原型‘继承’属性”,实际上,继承是一个十分具有迷惑性的说法,引用《你不知道的JavaScript》中的话,就是: 204 | 205 | 继承意味着复制操作,然而 JavaScript 默认并不会复制对象的属性,相反,JavaScript 只是在两个对象之间创建一个关联,这样,一个对象就可以通过委托访问另一个对象的属性和函数,所以与其叫继承,委托的说法反而更准确些。 206 | 207 | ## 下一篇文章 208 | 209 | [JavaScript深入之词法作用域和动态作用域](https://github.com/mqyqingfeng/Blog/issues/3) 210 | 211 | ## 深入系列 212 | 213 | JavaScript深入系列目录地址:[https://github.com/mqyqingfeng/Blog](https://github.com/mqyqingfeng/Blog)。 214 | 215 | JavaScript深入系列预计写十五篇左右,旨在帮大家捋顺JavaScript底层知识,重点讲解如原型、作用域、执行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、继承等难点概念。 216 | 217 | 如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎star,对作者也是一种鼓励。 -------------------------------------------------------------------------------- /javascript进阶/articles/深入系列文章/JavaScript深入之作用域链.md: -------------------------------------------------------------------------------- 1 | # JavaScript深入之作用域链 2 | 3 | >JavaScript深入系列第五篇,讲述作用链的创建过程,最后结合着变量对象,执行上下文栈,让我们一起捋一捋函数创建和执行的过程中到底发生了什么? 4 | 5 | ## 前言 6 | 7 | 在[《JavaScript深入之执行上下文栈》](https://github.com/mqyqingfeng/Blog/issues/4)中讲到,当JavaScript代码执行一段可执行代码(executable code)时,会创建对应的执行上下文(execution context)。 8 | 9 | 对于每个执行上下文,都有三个重要属性: 10 | 11 | * 变量对象(Variable object,VO) 12 | * 作用域链(Scope chain) 13 | * this 14 | 15 | 今天重点讲讲作用域链。 16 | 17 | ## 作用域链 18 | 19 | 在[《JavaScript深入之变量对象》](https://github.com/mqyqingfeng/Blog/issues/5)中讲到,当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级(词法层面上的父级)执行上下文的变量对象中查找,一直找到全局上下文的变量对象,也就是全局对象。这样由多个执行上下文的变量对象构成的链表就叫做作用域链。 20 | 21 | 下面,让我们以一个函数的创建和激活两个时期来讲解作用域链是如何创建和变化的。 22 | 23 | ## 函数创建 24 | 25 | 在[《JavaScript深入之词法作用域和动态作用域》](https://github.com/mqyqingfeng/Blog/issues/3)中讲到,函数的作用域在函数定义的时候就决定了。 26 | 27 | 这是因为函数有一个内部属性 [[scope]],当函数创建的时候,就会保存所有父变量对象到其中,你可以理解 [[scope]] 就是所有父变量对象的层级链,但是注意:[[scope]] 并不代表完整的作用域链! 28 | 29 | 举个例子: 30 | 31 | ```js 32 | 33 | function foo() { 34 | function bar() { 35 | ... 36 | } 37 | } 38 | 39 | ``` 40 | 41 | 函数创建时,各自的[[scope]]为: 42 | 43 | ```js 44 | 45 | foo.[[scope]] = [ 46 | globalContext.VO 47 | ]; 48 | 49 | bar.[[scope]] = [ 50 | fooContext.AO, 51 | globalContext.VO 52 | ]; 53 | 54 | ``` 55 | 56 | ## 函数激活 57 | 58 | 当函数激活时,进入函数上下文,创建 VO/AO 后,就会将活动对象添加到作用链的前端。 59 | 60 | 这时候执行上下文的作用域链,我们命名为 Scope: 61 | 62 | ```js 63 | 64 | Scope = [AO].concat([[Scope]]); 65 | 66 | ``` 67 | 68 | 至此,作用域链创建完毕。 69 | 70 | ## 捋一捋 71 | 72 | 以下面的例子为例,结合着之前讲的变量对象和执行上下文栈,我们来总结一下函数执行上下文中作用域链和变量对象的创建过程: 73 | 74 | ```js 75 | var scope = "global scope"; 76 | function checkscope(){ 77 | var scope2 = 'local scope'; 78 | return scope2; 79 | } 80 | checkscope(); 81 | ``` 82 | 83 | 执行过程如下: 84 | 85 | 1.checkscope 函数被创建,保存作用域链到 内部属性[[scope]] 86 | 87 | ```js 88 | checkscope.[[scope]] = [ 89 | globalContext.VO 90 | ]; 91 | ``` 92 | 93 | 2.执行 checkscope 函数,创建 checkscope 函数执行上下文,checkscope 函数执行上下文被压入执行上下文栈 94 | 95 | ```js 96 | ECStack = [ 97 | checkscopeContext, 98 | globalContext 99 | ]; 100 | ``` 101 | 102 | 3.checkscope 函数并不立刻执行,开始做准备工作,第一步:复制函数[[scope]]属性创建作用域链 103 | 104 | ```js 105 | checkscopeContext = { 106 | Scope: checkscope.[[scope]], 107 | } 108 | ``` 109 | 110 | 4.第二步:用 arguments 创建活动对象,随后初始化活动对象,加入形参、函数声明、变量声明 111 | 112 | ```js 113 | checkscopeContext = { 114 | AO: { 115 | arguments: { 116 | length: 0 117 | }, 118 | scope2: undefined 119 | } 120 | } 121 | ``` 122 | 123 | 5.第三步:将活动对象压入 checkscope 作用域链顶端 124 | 125 | ```js 126 | checkscopeContext = { 127 | AO: { 128 | arguments: { 129 | length: 0 130 | }, 131 | scope2: undefined 132 | }, 133 | Scope: [AO, [[Scope]]] 134 | } 135 | ``` 136 | 137 | 6.准备工作做完,开始执行函数,随着函数的执行,修改 AO 的属性值 138 | 139 | ```js 140 | checkscopeContext = { 141 | AO: { 142 | arguments: { 143 | length: 0 144 | }, 145 | scope2: 'local scope' 146 | }, 147 | Scope: [AO, [[Scope]]] 148 | } 149 | ``` 150 | 151 | 7.查找到 scope2 的值,返回后函数执行完毕,函数上下文从执行上下文栈中弹出 152 | 153 | ```js 154 | ECStack = [ 155 | globalContext 156 | ]; 157 | ``` 158 | 159 | ## 下一篇文章 160 | 161 | [《JavaScript深入之从ECMAScript规范解读this》](https://github.com/mqyqingfeng/Blog/issues/7) 162 | 163 | ## 本文相关链接 164 | 165 | [《JavaScript深入之词法作用域和动态作用域》](https://github.com/mqyqingfeng/Blog/issues/3) 166 | 167 | [《JavaScript深入之执行上下文栈》](https://github.com/mqyqingfeng/Blog/issues/4) 168 | 169 | [《JavaScript深入之变量对象》](https://github.com/mqyqingfeng/Blog/issues/5) 170 | 171 | ## 深入系列 172 | 173 | JavaScript深入系列目录地址:[https://github.com/mqyqingfeng/Blog](https://github.com/mqyqingfeng/Blog)。 174 | 175 | JavaScript深入系列预计写十五篇左右,旨在帮大家捋顺JavaScript底层知识,重点讲解如原型、作用域、执行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、继承等难点概念。 176 | 177 | 如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎star,对作者也是一种鼓励。 178 | -------------------------------------------------------------------------------- /javascript进阶/articles/深入系列文章/JavaScript深入之参数按值传递.md: -------------------------------------------------------------------------------- 1 | # JavaScript深入之参数按值传递 2 | 3 | > JavaScript深入系列第九篇,除了按值传递、引用传递,还有第三种传递方式 —— 按共享传递 4 | 5 | ## 定义 6 | 7 | 在《JavaScript高级程序设计》第三版 4.1.3,讲到传递参数: 8 | 9 | >ECMAScript中所有函数的参数都是按值传递的。 10 | 11 | 什么是按值传递呢? 12 | 13 | >也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。 14 | 15 | ## 按值传递 16 | 17 | 举个简单的例子: 18 | 19 | ```js 20 | var value = 1; 21 | function foo(v) { 22 | v = 2; 23 | console.log(v); //2 24 | } 25 | foo(value); 26 | console.log(value) // 1 27 | ``` 28 | 29 | 很好理解,当传递 value 到函数 foo 中,相当于拷贝了一份 value,假设拷贝的这份叫 _value,函数中修改的都是 _value 的值,而不会影响原来的 value 值。 30 | 31 | ## 引用传递 32 | 33 | 拷贝虽然很好理解,但是当值是一个复杂的数据结构的时候,拷贝就会产生性能上的问题。 34 | 35 | 所以还有另一种传递方式叫做按引用传递。 36 | 37 | 所谓按引用传递,就是传递对象的引用,函数内部对参数的任何改变都会影响该对象的值,因为两者引用的是同一个对象。 38 | 39 | 举个例子: 40 | 41 | ```js 42 | var obj = { 43 | value: 1 44 | }; 45 | function foo(o) { 46 | o.value = 2; 47 | console.log(o.value); //2 48 | } 49 | foo(obj); 50 | console.log(obj.value) // 2 51 | ``` 52 | 53 | 哎,不对啊,连我们的红宝书都说了 ECMAScript 中所有函数的参数都是按值传递的,这怎么能按引用传递成功呢? 54 | 55 | 而这究竟是不是引用传递呢? 56 | 57 | ## 第三种传递方式 58 | 59 | 不急,让我们再看个例子: 60 | 61 | ```js 62 | var obj = { 63 | value: 1 64 | }; 65 | function foo(o) { 66 | o = 2; 67 | console.log(o); //2 68 | } 69 | foo(obj); 70 | console.log(obj.value) // 1 71 | ``` 72 | 73 | 如果 JavaScript 采用的是引用传递,外层的值也会被修改呐,这怎么又没被改呢?所以真的不是引用传递吗? 74 | 75 | 这就要讲到其实还有第三种传递方式,叫按共享传递。 76 | 77 | 而共享传递是指,在传递对象的时候,传递对象的引用的副本。 78 | 79 | **注意: 按引用传递是传递对象的引用,而按共享传递是传递对象的引用的副本!** 80 | 81 | 所以修改 o.value,可以通过引用找到原值,但是直接修改 o,并不会修改原值。所以第二个和第三个例子其实都是按共享传递。 82 | 83 | 最后,你可以这样理解: 84 | 85 | 参数如果是基本类型是按值传递,如果是引用类型按共享传递。 86 | 87 | 但是因为拷贝副本也是一种值的拷贝,所以在高程中也直接认为是按值传递了。 88 | 89 | 所以,高程,谁叫你是红宝书嘞! 90 | 91 | ## 下一篇文章 92 | 93 | [JavaScript深入之call和apply的模拟实现](https://github.com/mqyqingfeng/Blog/issues/11) 94 | 95 | ## 深入系列 96 | 97 | JavaScript深入系列目录地址:[https://github.com/mqyqingfeng/Blog](https://github.com/mqyqingfeng/Blog)。 98 | 99 | JavaScript深入系列预计写十五篇左右,旨在帮大家捋顺JavaScript底层知识,重点讲解如原型、作用域、执行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、继承等难点概念。 100 | 101 | 如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎star,对作者也是一种鼓励。 102 | -------------------------------------------------------------------------------- /javascript进阶/articles/深入系列文章/JavaScript深入之变量对象.md: -------------------------------------------------------------------------------- 1 | # JavaScript深入之变量对象 2 | 3 | >JavaScript深入系列第四篇,具体讲解执行上下文中的变量对象与活动对象。全局上下文下的变量对象是什么?函数上下文下的活动对象是如何分析和执行的?还有两个思考题帮你加深印象,快来看看吧! 4 | 5 | ## 前言 6 | 7 | 在上篇[《JavaScript深入之执行上下文栈》](https://github.com/mqyqingfeng/Blog/issues/4)中讲到,当 JavaScript 代码执行一段可执行代码(executable code)时,会创建对应的执行上下文(execution context)。 8 | 9 | 对于每个执行上下文,都有三个重要属性: 10 | 11 | * 变量对象(Variable object,VO) 12 | * 作用域链(Scope chain) 13 | * this 14 | 15 | 今天重点讲讲创建变量对象的过程。 16 | 17 | ## 变量对象 18 | 19 | 变量对象是与执行上下文相关的数据作用域,存储了在上下文中定义的变量和函数声明。 20 | 21 | 因为不同执行上下文下的变量对象稍有不同,所以我们来聊聊全局上下文下的变量对象和函数上下文下的变量对象。 22 | 23 | ## 全局上下文 24 | 25 | 我们先了解一个概念,叫全局对象。在 [W3School](http://www.w3school.com.cn/jsref/jsref_obj_global.asp) 中也有介绍: 26 | 27 | >全局对象是预定义的对象,作为 JavaScript 的全局函数和全局属性的占位符。通过使用全局对象,可以访问所有其他所有预定义的对象、函数和属性。 28 | 29 | >在顶层 JavaScript 代码中,可以用关键字 this 引用全局对象。因为全局对象是作用域链的头,这意味着所有非限定性的变量和函数名都会作为该对象的属性来查询。 30 | 31 | >例如,当JavaScript 代码引用 parseInt() 函数时,它引用的是全局对象的 parseInt 属性。全局对象是作用域链的头,还意味着在顶层 JavaScript 代码中声明的所有变量都将成为全局对象的属性。 32 | 33 | 如果看的不是很懂的话,容我再来介绍下全局对象: 34 | 35 | 1.可以通过 this 引用,在客户端 JavaScript 中,全局对象就是 Window 对象。 36 | 37 | ```js 38 | console.log(this); 39 | ``` 40 | 41 | 2.全局对象是由 Object 构造函数实例化的一个对象。 42 | 43 | ```js 44 | console.log(this instanceof Object); 45 | ``` 46 | 47 | 3.预定义了一堆,嗯,一大堆函数和属性。 48 | 49 | ```js 50 | // 都能生效 51 | console.log(Math.random()); 52 | console.log(this.Math.random()); 53 | ``` 54 | 55 | 4.作为全局变量的宿主。 56 | 57 | ```js 58 | var a = 1; 59 | console.log(this.a); 60 | ``` 61 | 62 | 5.客户端 JavaScript 中,全局对象有 window 属性指向自身。 63 | 64 | ```js 65 | var a = 1; 66 | console.log(window.a); 67 | 68 | this.window.b = 2; 69 | console.log(this.b); 70 | ``` 71 | 72 | 花了一个大篇幅介绍全局对象,其实就想说: 73 | 74 | 全局上下文中的变量对象就是全局对象呐! 75 | 76 | ## 函数上下文 77 | 78 | 在函数上下文中,我们用活动对象(activation object, AO)来表示变量对象。 79 | 80 | 活动对象和变量对象其实是一个东西,只是变量对象是规范上的或者说是引擎实现上的,不可在 JavaScript 环境中访问,只有到当进入一个执行上下文中,这个执行上下文的变量对象才会被激活,所以才叫 activation object 呐,而只有被激活的变量对象,也就是活动对象上的各种属性才能被访问。 81 | 82 | 活动对象是在进入函数上下文时刻被创建的,它通过函数的 arguments 属性初始化。arguments 属性值是 Arguments 对象。 83 | 84 | ## 执行过程 85 | 86 | 执行上下文的代码会分成两个阶段进行处理:分析和执行,我们也可以叫做: 87 | 88 | 1. 进入执行上下文 89 | 2. 代码执行 90 | 91 | ### 进入执行上下文 92 | 93 | 当进入执行上下文时,这时候还没有执行代码, 94 | 95 | 变量对象会包括: 96 | 97 | 1. 函数的所有形参 (如果是函数上下文) 98 | * 由名称和对应值组成的一个变量对象的属性被创建 99 | * 没有实参,属性值设为 undefined 100 | 101 | 2. 函数声明 102 | * 由名称和对应值(函数对象(function-object))组成一个变量对象的属性被创建 103 | * 如果变量对象已经存在相同名称的属性,则完全替换这个属性 104 | 105 | 3. 变量声明 106 | * 由名称和对应值(undefined)组成一个变量对象的属性被创建; 107 | * 如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性 108 | 109 | 举个例子: 110 | 111 | ```js 112 | function foo(a) { 113 | var b = 2; 114 | function c() {} 115 | var d = function() {}; 116 | 117 | b = 3; 118 | 119 | } 120 | 121 | foo(1); 122 | ``` 123 | 124 | 在进入执行上下文后,这时候的 AO 是: 125 | 126 | ```js 127 | AO = { 128 | arguments: { 129 | 0: 1, 130 | length: 1 131 | }, 132 | a: 1, 133 | b: undefined, 134 | c: reference to function c(){}, 135 | d: undefined 136 | } 137 | ``` 138 | 139 | ### 代码执行 140 | 141 | 在代码执行阶段,会顺序执行代码,根据代码,修改变量对象的值 142 | 143 | 还是上面的例子,当代码执行完后,这时候的 AO 是: 144 | 145 | ```js 146 | AO = { 147 | arguments: { 148 | 0: 1, 149 | length: 1 150 | }, 151 | a: 1, 152 | b: 3, 153 | c: reference to function c(){}, 154 | d: reference to FunctionExpression "d" 155 | } 156 | ``` 157 | 158 | 到这里变量对象的创建过程就介绍完了,让我们简洁的总结我们上述所说: 159 | 160 | 1. 全局上下文的变量对象初始化是全局对象 161 | 162 | 2. 函数上下文的变量对象初始化只包括 Arguments 对象 163 | 164 | 3. 在进入执行上下文时会给变量对象添加形参、函数声明、变量声明等初始的属性值 165 | 166 | 4. 在代码执行阶段,会再次修改变量对象的属性值 167 | 168 | ## 思考题 169 | 170 | 最后让我们看几个例子: 171 | 172 | 1.第一题 173 | 174 | ```js 175 | function foo() { 176 | console.log(a); 177 | a = 1; 178 | } 179 | 180 | foo(); // ??? 181 | 182 | function bar() { 183 | a = 1; 184 | console.log(a); 185 | } 186 | bar(); // ??? 187 | ``` 188 | 189 | 第一段会报错:`Uncaught ReferenceError: a is not defined`。 190 | 191 | 第二段会打印:`1`。 192 | 193 | 这是因为函数中的 "a" 并没有通过 var 关键字声明,所有不会被存放在 AO 中。 194 | 195 | 第一段执行 console 的时候, AO 的值是: 196 | 197 | ```js 198 | AO = { 199 | arguments: { 200 | length: 0 201 | } 202 | } 203 | ``` 204 | 205 | 没有 a 的值,然后就会到全局去找,全局也没有,所以会报错。 206 | 207 | 当第二段执行 console 的时候,全局对象已经被赋予了 a 属性,这时候就可以从全局找到 a 的值,所以会打印 1。 208 | 209 | 2.第二题 210 | 211 | ```js 212 | console.log(foo); 213 | 214 | function foo(){ 215 | console.log("foo"); 216 | } 217 | 218 | var foo = 1; 219 | ``` 220 | 221 | 会打印函数,而不是 undefined 。 222 | 223 | 这是因为在进入执行上下文时,首先会处理函数声明,其次会处理变量声明,如果如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性。 224 | 225 | ## 下一篇文章 226 | 227 | [《JavaScript深入之作用域链》](https://github.com/mqyqingfeng/Blog/issues/6) 228 | 229 | ## 本文相关链接 230 | 231 | [《JavaScript深入之执行上下文栈》](https://github.com/mqyqingfeng/Blog/issues/4) 232 | 233 | ## 深入系列 234 | 235 | JavaScript深入系列目录地址:[https://github.com/mqyqingfeng/Blog](https://github.com/mqyqingfeng/Blog)。 236 | 237 | JavaScript深入系列预计写十五篇左右,旨在帮大家捋顺JavaScript底层知识,重点讲解如原型、作用域、执行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、继承等难点概念。 238 | 239 | 如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎star,对作者也是一种鼓励。 -------------------------------------------------------------------------------- /javascript进阶/articles/深入系列文章/JavaScript深入之执行上下文.md: -------------------------------------------------------------------------------- 1 | # JavaScript深入之执行上下文 2 | 3 | >JavaScript深入系列第七篇,结合之前所讲的四篇文章,以权威指南的demo为例,具体讲解当函数执行的时候,执行上下文栈、变量对象、作用域链是如何变化的。 4 | 5 | # 前言 6 | 7 | 在[《JavaScript深入之执行上下文栈》](https://github.com/mqyqingfeng/Blog/issues/4)中讲到,当 JavaScript 代码执行一段可执行代码(executable code)时,会创建对应的执行上下文(execution contexts)。 8 | 9 | 对于每个执行上下文,都有三个重要属性: 10 | 11 | * 变量对象(Variable object,VO) 12 | * 作用域链(Scope chain) 13 | * this 14 | 15 | 然后分别在[《JavaScript深入之变量对象》](https://github.com/mqyqingfeng/Blog/issues/5)、[《JavaScript深入之作用域链》](https://github.com/mqyqingfeng/Blog/issues/6)、[《JavaScript深入之从ECMAScript规范解读this》](https://github.com/mqyqingfeng/Blog/issues/7)中讲解了这三个属性。 16 | 17 | 阅读本文前,如果对以上的概念不是很清楚,希望先阅读这些文章。 18 | 19 | 因为,这一篇,我们会结合着所有内容,讲讲执行上下文的具体处理过程。 20 | 21 | ## 思考题 22 | 23 | 在[《JavaScript深入之词法作用域和动态作用域》](https://github.com/mqyqingfeng/Blog/issues/3)中,提出这样一道思考题: 24 | 25 | ```js 26 | var scope = "global scope"; 27 | function checkscope(){ 28 | var scope = "local scope"; 29 | function f(){ 30 | return scope; 31 | } 32 | return f(); 33 | } 34 | checkscope(); 35 | ``` 36 | 37 | ```js 38 | var scope = "global scope"; 39 | function checkscope(){ 40 | var scope = "local scope"; 41 | function f(){ 42 | return scope; 43 | } 44 | return f; 45 | } 46 | checkscope()(); 47 | ``` 48 | 49 | 两段代码都会打印'local scope'。虽然两段代码执行的结果一样,但是两段代码究竟有哪些不同呢? 50 | 51 | 紧接着就在下一篇[《JavaScript深入之执行上下文栈》](https://github.com/mqyqingfeng/Blog/issues/4)中,讲到了两者的区别在于执行上下文栈的变化不一样,然而,如果是这样笼统的回答,依然显得不够详细,本篇就会详细的解析执行上下文栈和执行上下文的具体变化过程。 52 | 53 | ## 具体执行分析 54 | 55 | 我们分析第一段代码: 56 | 57 | ```js 58 | var scope = "global scope"; 59 | function checkscope(){ 60 | var scope = "local scope"; 61 | function f(){ 62 | return scope; 63 | } 64 | return f(); 65 | } 66 | checkscope(); 67 | ``` 68 | 69 | 执行过程如下: 70 | 71 | 1.执行全局代码,创建全局执行上下文,全局上下文被压入执行上下文栈 72 | 73 | ```js 74 | ECStack = [ 75 | globalContext 76 | ]; 77 | ``` 78 | 79 | 2.全局上下文初始化 80 | 81 | ```js 82 | globalContext = { 83 | VO: [global, scope, checkscope], 84 | Scope: [globalContext.VO], 85 | this: globalContext.VO 86 | } 87 | ``` 88 | 89 | 2.初始化的同时,checkscope 函数被创建,保存作用域链到函数的内部属性[[scope]] 90 | 91 | ```js 92 | checkscope.[[scope]] = [ 93 | globalContext.VO 94 | ]; 95 | ``` 96 | 97 | 3.执行 checkscope 函数,创建 checkscope 函数执行上下文,checkscope 函数执行上下文被压入执行上下文栈 98 | 99 | ```js 100 | ECStack = [ 101 | checkscopeContext, 102 | globalContext 103 | ]; 104 | ``` 105 | 106 | 4.checkscope 函数执行上下文初始化: 107 | 108 | 1. 复制函数 [[scope]] 属性创建作用域链, 109 | 2. 用 arguments 创建活动对象, 110 | 3. 初始化活动对象,即加入形参、函数声明、变量声明, 111 | 4. 将活动对象压入 checkscope 作用域链顶端。 112 | 113 | 同时 f 函数被创建,保存作用域链到 f 函数的内部属性[[scope]] 114 | 115 | ```js 116 | checkscopeContext = { 117 | AO: { 118 | arguments: { 119 | length: 0 120 | }, 121 | scope: undefined, 122 | f: reference to function f(){} 123 | }, 124 | Scope: [AO, globalContext.VO], 125 | this: undefined 126 | } 127 | ``` 128 | 129 | 5.执行 f 函数,创建 f 函数执行上下文,f 函数执行上下文被压入执行上下文栈 130 | 131 | ```js 132 | ECStack = [ 133 | fContext, 134 | checkscopeContext, 135 | globalContext 136 | ]; 137 | ``` 138 | 139 | 6.f 函数执行上下文初始化, 以下跟第 4 步相同: 140 | 141 | 1. 复制函数 [[scope]] 属性创建作用域链 142 | 2. 用 arguments 创建活动对象 143 | 3. 初始化活动对象,即加入形参、函数声明、变量声明 144 | 4. 将活动对象压入 f 作用域链顶端 145 | 146 | ```js 147 | fContext = { 148 | AO: { 149 | arguments: { 150 | length: 0 151 | } 152 | }, 153 | Scope: [AO, checkscopeContext.AO, globalContext.VO], 154 | this: undefined 155 | } 156 | ``` 157 | 158 | 7.f 函数执行,沿着作用域链查找 scope 值,返回 scope 值 159 | 160 | 8.f 函数执行完毕,f 函数上下文从执行上下文栈中弹出 161 | 162 | ```js 163 | ECStack = [ 164 | checkscopeContext, 165 | globalContext 166 | ]; 167 | ``` 168 | 169 | 9.checkscope 函数执行完毕,checkscope 执行上下文从执行上下文栈中弹出 170 | 171 | ```js 172 | ECStack = [ 173 | globalContext 174 | ]; 175 | ``` 176 | 177 | 第二段代码就留给大家去尝试模拟它的执行过程。 178 | 179 | ```js 180 | var scope = "global scope"; 181 | function checkscope(){ 182 | var scope = "local scope"; 183 | function f(){ 184 | return scope; 185 | } 186 | return f; 187 | } 188 | checkscope()(); 189 | ``` 190 | 191 | 不过,在下一篇《JavaScript深入之闭包》中也会提及这段代码的执行过程。 192 | 193 | ## 下一篇文章 194 | 195 | [《JavaScript深入之闭包》](https://github.com/mqyqingfeng/Blog/issues/9) 196 | 197 | ## 相关链接 198 | 199 | [《JavaScript深入之词法作用域和动态作用域》](https://github.com/mqyqingfeng/Blog/issues/3) 200 | 201 | [《JavaScript深入之执行上下文栈》](https://github.com/mqyqingfeng/Blog/issues/4) 202 | 203 | [《JavaScript深入之变量对象》](https://github.com/mqyqingfeng/Blog/issues/5) 204 | 205 | [《JavaScript深入之作用域链》](https://github.com/mqyqingfeng/Blog/issues/6) 206 | 207 | [《JavaScript深入之从ECMAScript规范解读this》](https://github.com/mqyqingfeng/Blog/issues/7) 208 | 209 | ## 重要参考 210 | 211 | [《一道js面试题引发的思考》](https://github.com/kuitos/kuitos.github.io/issues/18) 212 | 213 | 本文写的太好,给了我很多启发。感激不尽! 214 | 215 | ## 深入系列 216 | 217 | JavaScript深入系列目录地址:[https://github.com/mqyqingfeng/Blog](https://github.com/mqyqingfeng/Blog)。 218 | 219 | JavaScript深入系列预计写十五篇左右,旨在帮大家捋顺JavaScript底层知识,重点讲解如原型、作用域、执行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、继承等难点概念。 220 | 221 | 如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎star,对作者也是一种鼓励。 -------------------------------------------------------------------------------- /javascript进阶/articles/深入系列文章/JavaScript深入之执行上下文栈.md: -------------------------------------------------------------------------------- 1 | # JavaScript深入之执行上下文栈 2 | 3 | >JavaScript深入系列第三篇,讲解执行上下文栈的是如何执行的,也回答了第二篇中的略难的思考题。 4 | 5 | ## 顺序执行? 6 | 7 | 如果要问到 JavaScript 代码执行顺序的话,想必写过 JavaScript 的开发者都会有个直观的印象,那就是顺序执行,毕竟: 8 | 9 | ```js 10 | var foo = function () { 11 | 12 | console.log('foo1'); 13 | 14 | } 15 | 16 | foo(); // foo1 17 | 18 | var foo = function () { 19 | 20 | console.log('foo2'); 21 | 22 | } 23 | 24 | foo(); // foo2 25 | ``` 26 | 27 | 然而去看这段代码: 28 | 29 | ```js 30 | 31 | function foo() { 32 | 33 | console.log('foo1'); 34 | 35 | } 36 | 37 | foo(); // foo2 38 | 39 | function foo() { 40 | 41 | console.log('foo2'); 42 | 43 | } 44 | 45 | foo(); // foo2 46 | 47 | ``` 48 | 49 | 打印的结果却是两个 `foo2`。 50 | 51 | 刷过面试题的都知道这是因为 JavaScript 引擎并非一行一行地分析和执行程序,而是一段一段地分析执行。当执行一段代码的时候,会进行一个“准备工作”,比如第一个例子中的变量提升,和第二个例子中的函数提升。 52 | 53 | 但是本文真正想让大家思考的是:这个“一段一段”中的“段”究竟是怎么划分的呢? 54 | 55 | 到底JavaScript引擎遇到一段怎样的代码时才会做“准备工作”呢? 56 | 57 | ## 可执行代码 58 | 59 | 这就要说到 JavaScript 的可执行代码(executable code)的类型有哪些了? 60 | 61 | 其实很简单,就三种,全局代码、函数代码、eval代码。 62 | 63 | 举个例子,当执行到一个函数的时候,就会进行准备工作,这里的“准备工作”,让我们用个更专业一点的说法,就叫做"执行上下文(execution context)"。 64 | 65 | ## 执行上下文栈 66 | 67 | 接下来问题来了,我们写的函数多了去了,如何管理创建的那么多执行上下文呢? 68 | 69 | 所以 JavaScript 引擎创建了执行上下文栈(Execution context stack,ECS)来管理执行上下文 70 | 71 | 为了模拟执行上下文栈的行为,让我们定义执行上下文栈是一个数组: 72 | 73 | ```js 74 | ECStack = []; 75 | ``` 76 | 77 | 试想当 JavaScript 开始要解释执行代码的时候,最先遇到的就是全局代码,所以初始化的时候首先就会向执行上下文栈压入一个全局执行上下文,我们用 globalContext 表示它,并且只有当整个应用程序结束的时候,ECStack 才会被清空,所以 ECStack 最底部永远有个 globalContext: 78 | 79 | ```js 80 | ECStack = [ 81 | globalContext 82 | ]; 83 | ``` 84 | 85 | 现在 JavaScript 遇到下面的这段代码了: 86 | 87 | ```js 88 | function fun3() { 89 | console.log('fun3') 90 | } 91 | 92 | function fun2() { 93 | fun3(); 94 | } 95 | 96 | function fun1() { 97 | fun2(); 98 | } 99 | 100 | fun1(); 101 | ``` 102 | 103 | 当执行一个函数的时候,就会创建一个执行上下文,并且压入执行上下文栈,当函数执行完毕的时候,就会将函数的执行上下文从栈中弹出。知道了这样的工作原理,让我们来看看如何处理上面这段代码: 104 | 105 | ```js 106 | // 伪代码 107 | 108 | // fun1() 109 | ECStack.push( functionContext); 110 | 111 | // fun1中竟然调用了fun2,还要创建fun2的执行上下文 112 | ECStack.push( functionContext); 113 | 114 | // 擦,fun2还调用了fun3! 115 | ECStack.push( functionContext); 116 | 117 | // fun3执行完毕 118 | ECStack.pop(); 119 | 120 | // fun2执行完毕 121 | ECStack.pop(); 122 | 123 | // fun1执行完毕 124 | ECStack.pop(); 125 | 126 | // javascript接着执行下面的代码,但是ECStack底层永远有个globalContext 127 | ``` 128 | 129 | ## 解答思考题 130 | 131 | 好啦,现在我们已经了解了执行上下文栈是如何处理执行上下文的,所以让我们看看上篇文章[《JavaScript深入之词法作用域和动态作用域》](https://github.com/mqyqingfeng/Blog/issues/3)最后的问题: 132 | 133 | ```js 134 | var scope = "global scope"; 135 | function checkscope(){ 136 | var scope = "local scope"; 137 | function f(){ 138 | return scope; 139 | } 140 | return f(); 141 | } 142 | checkscope(); 143 | ``` 144 | 145 | ```js 146 | var scope = "global scope"; 147 | function checkscope(){ 148 | var scope = "local scope"; 149 | function f(){ 150 | return scope; 151 | } 152 | return f; 153 | } 154 | checkscope()(); 155 | ``` 156 | 157 | 两段代码执行的结果一样,但是两段代码究竟有哪些不同呢? 158 | 159 | 答案就是执行上下文栈的变化不一样。 160 | 161 | 让我们模拟第一段代码: 162 | 163 | ```js 164 | ECStack.push( functionContext); 165 | ECStack.push( functionContext); 166 | ECStack.pop(); 167 | ECStack.pop(); 168 | ``` 169 | 170 | 让我们模拟第二段代码: 171 | 172 | ```js 173 | ECStack.push( functionContext); 174 | ECStack.pop(); 175 | ECStack.push( functionContext); 176 | ECStack.pop(); 177 | ``` 178 | 179 | 是不是有些不同呢? 180 | 181 | 当然了,这样概括的回答执行上下文栈的变化不同,是不是依然有一种意犹未尽的感觉呢,为了更详细讲解两个函数执行上的区别,我们需要探究一下执行上下文到底包含了哪些内容,所以欢迎阅读下一篇《JavaScript深入之变量对象》。 182 | 183 | ## 下一篇文章 184 | 185 | [《JavaScript深入之变量对象》](https://github.com/mqyqingfeng/Blog/issues/5) 186 | 187 | ## 深入系列 188 | 189 | JavaScript深入系列目录地址:[https://github.com/mqyqingfeng/Blog](https://github.com/mqyqingfeng/Blog)。 190 | 191 | JavaScript深入系列预计写十五篇左右,旨在帮大家捋顺JavaScript底层知识,重点讲解如原型、作用域、执行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、继承等难点概念。 192 | 193 | 如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎star,对作者也是一种鼓励。 194 | -------------------------------------------------------------------------------- /javascript进阶/articles/深入系列文章/JavaScript深入之类数组对象与arguments.md: -------------------------------------------------------------------------------- 1 | # JavaScript深入之类数组对象与arguments 2 | 3 | >JavaScript深入系列第十三篇,讲解类数组对象与对象的相似与差异以及arguments的注意要点 4 | 5 | ## 类数组对象 6 | 7 | 所谓的类数组对象: 8 | 9 | >拥有一个 length 属性和若干索引属性的对象 10 | 11 | 举个例子: 12 | 13 | ```js 14 | var array = ['name', 'age', 'sex']; 15 | 16 | var arrayLike = { 17 | 0: 'name', 18 | 1: 'age', 19 | 2: 'sex', 20 | length: 3 21 | } 22 | ``` 23 | 24 | 即便如此,为什么叫做类数组对象呢? 25 | 26 | 那让我们从读写、获取长度、遍历三个方面看看这两个对象。 27 | 28 | ## 读写 29 | 30 | ```js 31 | console.log(array[0]); // name 32 | console.log(arrayLike[0]); // name 33 | 34 | array[0] = 'new name'; 35 | arrayLike[0] = 'new name'; 36 | ``` 37 | 38 | ## 长度 39 | 40 | ```js 41 | console.log(array.length); // 3 42 | console.log(arrayLike.length); // 3 43 | ``` 44 | 45 | ## 遍历 46 | 47 | ```js 48 | for(var i = 0, len = array.length; i < len; i++) { 49 | …… 50 | } 51 | for(var i = 0, len = arrayLike.length; i < len; i++) { 52 | …… 53 | } 54 | ``` 55 | 56 | 是不是很像? 57 | 58 | 那类数组对象可以使用数组的方法吗?比如: 59 | 60 | ```js 61 | arrayLike.push('4'); 62 | ``` 63 | 64 | 然而上述代码会报错: arrayLike.push is not a function 65 | 66 | 所以终归还是类数组呐…… 67 | 68 | ## 调用数组方法 69 | 70 | 如果类数组就是任性的想用数组的方法怎么办呢? 71 | 72 | 既然无法直接调用,我们可以用 Function.call 间接调用: 73 | 74 | ```js 75 | var arrayLike = {0: 'name', 1: 'age', 2: 'sex', length: 3 } 76 | 77 | Array.prototype.join.call(arrayLike, '&'); // name&age&sex 78 | 79 | Array.prototype.slice.call(arrayLike, 0); // ["name", "age", "sex"] 80 | // slice可以做到类数组转数组 81 | 82 | Array.prototype.map.call(arrayLike, function(item){ 83 | return item.toUpperCase(); 84 | }); 85 | // ["NAME", "AGE", "SEX"] 86 | ``` 87 | 88 | ## 类数组转对象 89 | 90 | 在上面的例子中已经提到了一种类数组转数组的方法,再补充三个: 91 | 92 | ```js 93 | var arrayLike = {0: 'name', 1: 'age', 2: 'sex', length: 3 } 94 | // 1. slice 95 | Array.prototype.slice.call(arrayLike); // ["name", "age", "sex"] 96 | // 2. splice 97 | Array.prototype.splice.call(arrayLike, 0); // ["name", "age", "sex"] 98 | // 3. ES6 Array.from 99 | Array.from(arrayLike); // ["name", "age", "sex"] 100 | // 4. apply 101 | Array.prototype.concat.apply([], arrayLike) 102 | ``` 103 | 104 | 那么为什么会讲到类数组对象呢?以及类数组有什么应用吗? 105 | 106 | 要说到类数组对象,Arguments 对象就是一个类数组对象。在客户端 JavaScript 中,一些 DOM 方法(document.getElementsByTagName()等)也返回类数组对象。 107 | 108 | ## Arguments对象 109 | 110 | 接下来重点讲讲 Arguments 对象。 111 | 112 | Arguments 对象只定义在函数体中,包括了函数的参数和其他属性。在函数体中,arguments 指代该函数的 Arguments 对象。 113 | 114 | 举个例子: 115 | 116 | ```js 117 | function foo(name, age, sex) { 118 | console.log(arguments); 119 | } 120 | 121 | foo('name', 'age', 'sex') 122 | ``` 123 | 124 | 打印结果如下: 125 | 126 | ![arguments](https://github.com/mqyqingfeng/Blog/raw/master/Images/arguments.png) 127 | 128 | 我们可以看到除了类数组的索引属性和length属性之外,还有一个callee属性,接下来我们一个一个介绍。 129 | 130 | ## length属性 131 | 132 | Arguments对象的length属性,表示实参的长度,举个例子: 133 | 134 | ```js 135 | function foo(b, c, d){ 136 | console.log("实参的长度为:" + arguments.length) 137 | } 138 | 139 | console.log("形参的长度为:" + foo.length) 140 | 141 | foo(1) 142 | 143 | // 形参的长度为:3 144 | // 实参的长度为:1 145 | ``` 146 | 147 | ## callee属性 148 | 149 | Arguments 对象的 callee 属性,通过它可以调用函数自身。 150 | 151 | 讲个闭包经典面试题使用 callee 的解决方法: 152 | 153 | ```js 154 | var data = []; 155 | 156 | for (var i = 0; i < 3; i++) { 157 | (data[i] = function () { 158 | console.log(arguments.callee.i) 159 | }).i = i; 160 | } 161 | 162 | data[0](); 163 | data[1](); 164 | data[2](); 165 | 166 | // 0 167 | // 1 168 | // 2 169 | ``` 170 | 171 | 接下来讲讲 arguments 对象的几个注意要点: 172 | 173 | ## arguments 和对应参数的绑定 174 | 175 | ```js 176 | function foo(name, age, sex, hobbit) { 177 | 178 | console.log(name, arguments[0]); // name name 179 | 180 | // 改变形参 181 | name = 'new name'; 182 | 183 | console.log(name, arguments[0]); // new name new name 184 | 185 | // 改变arguments 186 | arguments[1] = 'new age'; 187 | 188 | console.log(age, arguments[1]); // new age new age 189 | 190 | // 测试未传入的是否会绑定 191 | console.log(sex); // undefined 192 | 193 | sex = 'new sex'; 194 | 195 | console.log(sex, arguments[2]); // new sex undefined 196 | 197 | arguments[3] = 'new hobbit'; 198 | 199 | console.log(hobbit, arguments[3]); // undefined new hobbit 200 | 201 | } 202 | 203 | foo('name', 'age') 204 | ``` 205 | 206 | 传入的参数,实参和 arguments 的值会共享,当没有传入时,实参与 arguments 值不会共享 207 | 208 | 除此之外,以上是在非严格模式下,如果是在严格模式下,实参和 arguments 是不会共享的。 209 | 210 | ## 传递参数 211 | 212 | 将参数从一个函数传递到另一个函数 213 | 214 | ```js 215 | // 使用 apply 将 foo 的参数传递给 bar 216 | function foo() { 217 | bar.apply(this, arguments); 218 | } 219 | function bar(a, b, c) { 220 | console.log(a, b, c); 221 | } 222 | 223 | foo(1, 2, 3) 224 | ``` 225 | 226 | ## 强大的ES6 227 | 228 | 使用ES6的 ... 运算符,我们可以轻松转成数组。 229 | 230 | ```js 231 | function func(...arguments) { 232 | console.log(arguments); // [1, 2, 3] 233 | } 234 | 235 | func(1, 2, 3); 236 | ``` 237 | 238 | ## 应用 239 | 240 | arguments的应用其实很多,在下个系列,也就是 JavaScript 专题系列中,我们会在 jQuery 的 extend 实现、函数柯里化、递归等场景看见 arguments 的身影。这篇文章就不具体展开了。 241 | 242 | 如果要总结这些场景的话,暂时能想到的包括: 243 | 244 | 1. 参数不定长 245 | 2. 函数柯里化 246 | 3. 递归调用 247 | 4. 函数重载 248 | ... 249 | 250 | 欢迎留言回复。 251 | 252 | ## 下一篇文章 253 | 254 | [JavaScript深入之创建对象的多种方式以及优缺点](https://github.com/mqyqingfeng/Blog/issues/15) 255 | 256 | ## 深入系列 257 | 258 | JavaScript深入系列目录地址:[https://github.com/mqyqingfeng/Blog](https://github.com/mqyqingfeng/Blog)。 259 | 260 | JavaScript深入系列预计写十五篇左右,旨在帮大家捋顺JavaScript底层知识,重点讲解如原型、作用域、执行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、继承等难点概念。 261 | 262 | 如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎star,对作者也是一种鼓励。 -------------------------------------------------------------------------------- /javascript进阶/articles/深入系列文章/JavaScript深入之词法作用域和动态作用域.md: -------------------------------------------------------------------------------- 1 | # JavaScript深入之词法作用域和动态作用域 2 | 3 | >JavaScript深入系列的第二篇,JavaScript采用词法作用域,什么语言采用了动态作用域?两者的区别又是什么?还有一个略难的思考题,快来看看吧。 4 | 5 | ## 作用域 6 | 7 | 作用域是指程序源代码中定义变量的区域。 8 | 9 | 作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。 10 | 11 | JavaScript 采用词法作用域(lexical scoping),也就是静态作用域。 12 | 13 | ## 静态作用域与动态作用域 14 | 15 | 因为 JavaScript 采用的是词法作用域,函数的作用域在函数定义的时候就决定了。 16 | 17 | 而与词法作用域相对的是动态作用域,函数的作用域是在函数调用的时候才决定的。 18 | 19 | 让我们认真看个例子就能明白之间的区别: 20 | 21 | ```js 22 | var value = 1; 23 | 24 | function foo() { 25 | console.log(value); 26 | } 27 | 28 | function bar() { 29 | var value = 2; 30 | foo(); 31 | } 32 | 33 | bar(); 34 | 35 | // 结果是 ??? 36 | ``` 37 | 38 | 假设JavaScript采用静态作用域,让我们分析下执行过程: 39 | 40 | 执行 foo 函数,先从 foo 函数内部查找是否有局部变量 value,如果没有,就根据书写的位置,查找上面一层的代码,也就是 value 等于 1,所以结果会打印 1。 41 | 42 | 假设JavaScript采用动态作用域,让我们分析下执行过程: 43 | 44 | 执行 foo 函数,依然是从 foo 函数内部查找是否有局部变量 value。如果没有,就从调用函数的作用域,也就是 bar 函数内部查找 value 变量,所以结果会打印 2。 45 | 46 | 前面我们已经说了,JavaScript采用的是静态作用域,所以这个例子的结果是 1。 47 | 48 | ## 动态作用域 49 | 50 | 也许你会好奇什么语言是动态作用域? 51 | 52 | bash 就是动态作用域,不信的话,把下面的脚本存成例如 scope.bash,然后进入相应的目录,用命令行执行 `bash ./scope.bash`,看看打印的值是多少。 53 | 54 | ```bash 55 | value=1 56 | function foo () { 57 | echo $value; 58 | } 59 | function bar () { 60 | local value=2; 61 | foo; 62 | } 63 | bar 64 | ``` 65 | 66 | 这个文件也可以在[github博客仓库](https://github.com/mqyqingfeng/Blog/blob/master/demos/scope/scope.bash)中找到。 67 | 68 | ## 思考题 69 | 70 | 最后,让我们看一个《JavaScript权威指南》中的例子: 71 | 72 | ```js 73 | var scope = "global scope"; 74 | function checkscope(){ 75 | var scope = "local scope"; 76 | function f(){ 77 | return scope; 78 | } 79 | return f(); 80 | } 81 | checkscope(); 82 | ``` 83 | 84 | ```js 85 | var scope = "global scope"; 86 | function checkscope(){ 87 | var scope = "local scope"; 88 | function f(){ 89 | return scope; 90 | } 91 | return f; 92 | } 93 | checkscope()(); 94 | ``` 95 | 96 | 猜猜两段代码各自的执行结果是多少? 97 | 98 | 这里直接告诉大家结果,两段代码都会打印:`local scope`。 99 | 100 | 原因也很简单,因为JavaScript采用的是词法作用域,函数的作用域基于函数创建的位置。 101 | 102 | 而引用《JavaScript权威指南》的回答就是: 103 | 104 | JavaScript 函数的执行用到了作用域链,这个作用域链是在函数定义的时候创建的。嵌套的函数 f() 定义在这个作用域链里,其中的变量 scope 一定是局部变量,不管何时何地执行函数 f(),这种绑定在执行 f() 时依然有效。 105 | 106 | 但是在这里真正想让大家思考的是: 107 | 108 | 虽然两段代码执行的结果一样,但是两段代码究竟有哪些不同呢? 109 | 110 | 如果要回答这个问题,就要牵涉到很多的内容,词法作用域只是其中的一小部分,让我们期待下一篇文章————《JavaScript深入之执行上下文栈》。 111 | 112 | ## 下一篇文章 113 | 114 | [JavaScript深入之执行上下文栈](https://github.com/mqyqingfeng/Blog/issues/4) 115 | 116 | ## 深入系列 117 | 118 | JavaScript深入系列目录地址:[https://github.com/mqyqingfeng/Blog](https://github.com/mqyqingfeng/Blog)。 119 | 120 | JavaScript深入系列预计写十五篇左右,旨在帮大家捋顺JavaScript底层知识,重点讲解如原型、作用域、执行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、继承等难点概念。 121 | 122 | 如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎star,对作者也是一种鼓励。 123 | 124 | -------------------------------------------------------------------------------- /javascript进阶/articles/深入系列文章/JavaScript深入之闭包.md: -------------------------------------------------------------------------------- 1 | # JavaScript深入之闭包 2 | 3 | > JavaScript深入系列第八篇,介绍理论上的闭包和实践上的闭包,以及从作用域链的角度解析经典的闭包题。 4 | 5 | ## 定义 6 | 7 | MDN 对闭包的定义为: 8 | 9 | >闭包是指那些能够访问自由变量的函数。 10 | 11 | 那什么是自由变量呢? 12 | 13 | >自由变量是指在函数中使用的,但既不是函数参数也不是函数的局部变量的变量。 14 | 15 | 由此,我们可以看出闭包共有两部分组成: 16 | 17 | >闭包 = 函数 + 函数能够访问的自由变量 18 | 19 | 举个例子: 20 | 21 | ```js 22 | var a = 1; 23 | 24 | function foo() { 25 | console.log(a); 26 | } 27 | 28 | foo(); 29 | ``` 30 | 31 | foo 函数可以访问变量 a,但是 a 既不是 foo 函数的局部变量,也不是 foo 函数的参数,所以 a 就是自由变量。 32 | 33 | 那么,函数 foo + foo 函数访问的自由变量 a 不就是构成了一个闭包嘛…… 34 | 35 | 还真是这样的! 36 | 37 | 所以在《JavaScript权威指南》中就讲到:从技术的角度讲,所有的JavaScript函数都是闭包。 38 | 39 | 咦,这怎么跟我们平时看到的讲到的闭包不一样呢!? 40 | 41 | 别着急,这是理论上的闭包,其实还有一个实践角度上的闭包,让我们看看汤姆大叔翻译的关于闭包的文章中的定义: 42 | 43 | ECMAScript中,闭包指的是: 44 | 45 | 1. 从理论角度:所有的函数。因为它们都在创建的时候就将上层上下文的数据保存起来了。哪怕是简单的全局变量也是如此,因为函数中访问全局变量就相当于是在访问自由变量,这个时候使用最外层的作用域。 46 | 2. 从实践角度:以下函数才算是闭包: 47 | 1. 即使创建它的上下文已经销毁,它仍然存在(比如,内部函数从父函数中返回) 48 | 2. 在代码中引用了自由变量 49 | 50 | 接下来就来讲讲实践上的闭包。 51 | 52 | ## 分析 53 | 54 | 让我们先写个例子,例子依然是来自《JavaScript权威指南》,稍微做点改动: 55 | 56 | ```js 57 | var scope = "global scope"; 58 | function checkscope(){ 59 | var scope = "local scope"; 60 | function f(){ 61 | return scope; 62 | } 63 | return f; 64 | } 65 | 66 | var foo = checkscope(); 67 | foo(); 68 | ``` 69 | 70 | 首先我们要分析一下这段代码中执行上下文栈和执行上下文的变化情况。 71 | 72 | 另一个与这段代码相似的例子,在[《JavaScript深入之执行上下文》](https://github.com/mqyqingfeng/Blog/issues/8)中有着非常详细的分析。如果看不懂以下的执行过程,建议先阅读这篇文章。 73 | 74 | 这里直接给出简要的执行过程: 75 | 76 | 1. 进入全局代码,创建全局执行上下文,全局执行上下文压入执行上下文栈 77 | 2. 全局执行上下文初始化 78 | 3. 执行 checkscope 函数,创建 checkscope 函数执行上下文,checkscope 执行上下文被压入执行上下文栈 79 | 4. checkscope 执行上下文初始化,创建变量对象、作用域链、this等 80 | 5. checkscope 函数执行完毕,checkscope 执行上下文从执行上下文栈中弹出 81 | 6. 执行 f 函数,创建 f 函数执行上下文,f 执行上下文被压入执行上下文栈 82 | 7. f 执行上下文初始化,创建变量对象、作用域链、this等 83 | 8. f 函数执行完毕,f 函数上下文从执行上下文栈中弹出 84 | 85 | 了解到这个过程,我们应该思考一个问题,那就是: 86 | 87 | 当 f 函数执行的时候,checkscope 函数上下文已经被销毁了啊(即从执行上下文栈中被弹出),怎么还会读取到 checkscope 作用域下的 scope 值呢? 88 | 89 | 以上的代码,要是转换成 PHP,就会报错,因为在 PHP 中,f 函数只能读取到自己作用域和全局作用域里的值,所以读不到 checkscope 下的 scope 值。(这段我问的PHP同事……) 90 | 91 | 然而 JavaScript 却是可以的! 92 | 93 | 当我们了解了具体的执行过程后,我们知道 f 执行上下文维护了一个作用域链: 94 | 95 | ```js 96 | fContext = { 97 | Scope: [AO, checkscopeContext.AO, globalContext.VO], 98 | } 99 | ``` 100 | 101 | 对的,就是因为这个作用域链,f 函数依然可以读取到 checkscopeContext.AO 的值,说明当 f 函数引用了 checkscopeContext.AO 中的值的时候,即使 checkscopeContext 被销毁了,但是 JavaScript 依然会让 checkscopeContext.AO 活在内存中,f 函数依然可以通过 f 函数的作用域链找到它,正是因为 JavaScript 做到了这一点,从而实现了闭包这个概念。 102 | 103 | 所以,让我们再看一遍实践角度上闭包的定义: 104 | 105 | 1. 即使创建它的上下文已经销毁,它仍然存在(比如,内部函数从父函数中返回) 106 | 2. 在代码中引用了自由变量 107 | 108 | 在这里再补充一个《JavaScript权威指南》英文原版对闭包的定义: 109 | 110 | > This combination of a function object and a scope (a set of variable bindings) in which the function’s variables are resolved is called a closure in the computer science literature. 111 | 112 | 闭包在计算机科学中也只是一个普通的概念,大家不要去想得太复杂。 113 | 114 | ## 必刷题 115 | 116 | 接下来,看这道刷题必刷,面试必考的闭包题: 117 | 118 | ```js 119 | var data = []; 120 | 121 | for (var i = 0; i < 3; i++) { 122 | data[i] = function () { 123 | console.log(i); 124 | }; 125 | } 126 | 127 | data[0](); 128 | data[1](); 129 | data[2](); 130 | ``` 131 | 132 | 答案是都是 3,让我们分析一下原因: 133 | 134 | 当执行到 data[0] 函数之前,此时全局上下文的 VO 为: 135 | 136 | ```js 137 | globalContext = { 138 | VO: { 139 | data: [...], 140 | i: 3 141 | } 142 | } 143 | ``` 144 | 145 | 当执行 data[0] 函数的时候,data[0] 函数的作用域链为: 146 | 147 | ```js 148 | data[0]Context = { 149 | Scope: [AO, globalContext.VO] 150 | } 151 | ``` 152 | 153 | data[0]Context 的 AO 并没有 i 值,所以会从 globalContext.VO 中查找,i 为 3,所以打印的结果就是 3。 154 | 155 | data[1] 和 data[2] 是一样的道理。 156 | 157 | 所以让我们改成闭包看看: 158 | 159 | ```js 160 | var data = []; 161 | 162 | for (var i = 0; i < 3; i++) { 163 | data[i] = (function (i) { 164 | return function(){ 165 | console.log(i); 166 | } 167 | })(i); 168 | } 169 | 170 | data[0](); 171 | data[1](); 172 | data[2](); 173 | ``` 174 | 175 | 当执行到 data[0] 函数之前,此时全局上下文的 VO 为: 176 | 177 | ```js 178 | globalContext = { 179 | VO: { 180 | data: [...], 181 | i: 3 182 | } 183 | } 184 | ``` 185 | 186 | 跟没改之前一模一样。 187 | 188 | 当执行 data[0] 函数的时候,data[0] 函数的作用域链发生了改变: 189 | 190 | ```js 191 | data[0]Context = { 192 | Scope: [AO, 匿名函数Context.AO globalContext.VO] 193 | } 194 | ``` 195 | 196 | 匿名函数执行上下文的 AO 为: 197 | 198 | ```js 199 | 匿名函数Context = { 200 | AO: { 201 | arguments: { 202 | 0: 0, 203 | length: 1 204 | }, 205 | i: 0 206 | } 207 | } 208 | ``` 209 | 210 | data[0]Context 的 AO 并没有 i 值,所以会沿着作用域链从匿名函数 Context.AO 中查找,这时候就会找 i 为 0,找到了就不会往 globalContext.VO 中查找了,即使 globalContext.VO 也有 i 的值(值为3),所以打印的结果就是 0。 211 | 212 | data[1] 和 data[2] 是一样的道理。 213 | 214 | ## 下一篇文章 215 | 216 | [JavaScript深入之参数按值传递](https://github.com/mqyqingfeng/Blog/issues/10) 217 | 218 | ## 相关链接 219 | 220 | 如果想了解执行上下文的具体变化,不妨循序渐进,阅读这六篇: 221 | 222 | [《JavaScript深入之词法作用域和动态作用域》](https://github.com/mqyqingfeng/Blog/issues/3) 223 | 224 | [《JavaScript深入之执行上下文栈》](https://github.com/mqyqingfeng/Blog/issues/4) 225 | 226 | [《JavaScript深入之变量对象》](https://github.com/mqyqingfeng/Blog/issues/5) 227 | 228 | [《JavaScript深入之作用域链》](https://github.com/mqyqingfeng/Blog/issues/6) 229 | 230 | [《JavaScript深入之从ECMAScript规范解读this》](https://github.com/mqyqingfeng/Blog/issues/7) 231 | 232 | [《JavaScript深入之执行上下文》](https://github.com/mqyqingfeng/Blog/issues/8) 233 | 234 | ## 深入系列 235 | 236 | JavaScript深入系列目录地址:[https://github.com/mqyqingfeng/Blog](https://github.com/mqyqingfeng/Blog)。 237 | 238 | JavaScript深入系列预计写十五篇左右,旨在帮大家捋顺JavaScript底层知识,重点讲解如原型、作用域、执行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、继承等难点概念。 239 | 240 | 如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎star,对作者也是一种鼓励。 -------------------------------------------------------------------------------- /javascript进阶/demos/debounce/debounce1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 事件会被频繁的触发 3 | */ 4 | 5 | var count = 1; 6 | var container = document.getElementById('container'); 7 | 8 | function getUserAction() { 9 | container.innerHTML = count++; 10 | }; 11 | 12 | container.onmousemove = getUserAction; 13 | 14 | 15 | -------------------------------------------------------------------------------- /javascript进阶/demos/debounce/debounce2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 随你怎么移动,反正你移动完1000ms内不再触发,我再执行事件 3 | */ 4 | 5 | var count = 1; 6 | var container = document.getElementById('container'); 7 | 8 | function getUserAction() { 9 | container.innerHTML = count++; 10 | }; 11 | 12 | container.onmousemove = debounce(getUserAction, 1000); 13 | 14 | // 第一版 15 | function debounce(func, wait) { 16 | var timeout; 17 | return function () { 18 | clearTimeout(timeout) 19 | timeout = setTimeout(func, wait); 20 | } 21 | } -------------------------------------------------------------------------------- /javascript进阶/demos/debounce/debounce3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 使用正确的this指向 3 | */ 4 | var count = 1; 5 | var container = document.getElementById('container'); 6 | 7 | function getUserAction() { 8 | console.log(this) 9 | container.innerHTML = count++; 10 | }; 11 | 12 | container.onmousemove = debounce(getUserAction, 1000); 13 | 14 | // 第二版 15 | function debounce(func, wait) { 16 | var timeout; 17 | 18 | return function () { 19 | var context = this; 20 | 21 | clearTimeout(timeout) 22 | timeout = setTimeout(function(){ 23 | func.apply(context) 24 | }, wait); 25 | } 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /javascript进阶/demos/debounce/debounce4.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 函数传参 3 | */ 4 | var count = 1; 5 | var container = document.getElementById('container'); 6 | 7 | function getUserAction(e) { 8 | container.innerHTML = count++; 9 | console.log(e) 10 | }; 11 | 12 | container.onmousemove = debounce(getUserAction, 1000); 13 | 14 | // 第三版 15 | function debounce(func, wait) { 16 | var timeout; 17 | 18 | return function () { 19 | var context = this; 20 | var args = arguments; 21 | 22 | clearTimeout(timeout) 23 | timeout = setTimeout(function(){ 24 | func.apply(context, args) 25 | }, wait); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /javascript进阶/demos/debounce/debounce5.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 添加immediate参数,让函数能够立刻执行,仅当事件停止触发n秒后,才能重新触发 3 | */ 4 | var count = 1; 5 | var container = document.getElementById('container'); 6 | 7 | function getUserAction(e) { 8 | container.innerHTML = count++; 9 | }; 10 | 11 | container.onmousemove = debounce(getUserAction, 1000, true); 12 | 13 | // 第四版 14 | function debounce(func, wait, immediate) { 15 | 16 | var timeout; 17 | 18 | return function () { 19 | var context = this; 20 | var args = arguments; 21 | 22 | if (timeout) clearTimeout(timeout); 23 | if (immediate) { 24 | // 如果已经执行过,不再执行 25 | var callNow = !timeout; 26 | timeout = setTimeout(function(){ 27 | timeout = null; 28 | }, wait) 29 | if (callNow) func.apply(context, args) 30 | } 31 | else { 32 | timeout = setTimeout(function(){ 33 | func.apply(context, args) 34 | }, wait); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /javascript进阶/demos/debounce/debounce6.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 添加函数返回值 3 | */ 4 | 5 | // 第五版 6 | function debounce(func, wait, immediate) { 7 | 8 | var timeout, result; 9 | 10 | return function () { 11 | var context = this; 12 | var args = arguments; 13 | 14 | if (timeout) clearTimeout(timeout); 15 | if (immediate) { 16 | // 如果已经执行过,不再执行 17 | var callNow = !timeout; 18 | timeout = setTimeout(function(){ 19 | timeout = null; 20 | }, wait) 21 | if (callNow) result = func.apply(context, args) 22 | } 23 | else { 24 | timeout = setTimeout(function(){ 25 | func.apply(context, args) 26 | }, wait); 27 | } 28 | return result; 29 | } 30 | } 31 | 32 | var count = 1; 33 | var container = document.getElementById('container'); 34 | 35 | function getUserAction() { 36 | container.innerHTML = count++; 37 | return '111' 38 | }; 39 | 40 | container.onmousemove = function(){ 41 | var result = debounce(getUserAction, 1000, true)(); 42 | console.log(result) 43 | } -------------------------------------------------------------------------------- /javascript进阶/demos/debounce/debounce7.js: -------------------------------------------------------------------------------- 1 | /** 2 | * debounce函数可以取消 3 | * @type {Number} 4 | */ 5 | var count = 1; 6 | var container = document.getElementById('container'); 7 | 8 | function getUserAction(e) { 9 | container.innerHTML = count++; 10 | }; 11 | 12 | var setUseAction = debounce(getUserAction, 10000, true); 13 | 14 | container.onmousemove = setUseAction; 15 | 16 | document.getElementById("button").addEventListener('click', function(){ 17 | setUseAction.cancel(); 18 | }) 19 | 20 | // 第六版 21 | function debounce(func, wait, immediate) { 22 | 23 | var timeout, result; 24 | 25 | var debounced = function () { 26 | var context = this; 27 | var args = arguments; 28 | 29 | if (timeout) clearTimeout(timeout); 30 | if (immediate) { 31 | // 如果已经执行过,不再执行 32 | var callNow = !timeout; 33 | timeout = setTimeout(function(){ 34 | timeout = null; 35 | }, wait) 36 | if (callNow) result = func.apply(context, args) 37 | } 38 | else { 39 | timeout = setTimeout(function(){ 40 | func.apply(context, args) 41 | }, wait); 42 | } 43 | 44 | 45 | return result; 46 | }; 47 | 48 | debounced.cancel = function() { 49 | clearTimeout(timeout); 50 | timeout = null; 51 | }; 52 | 53 | return debounced; 54 | } -------------------------------------------------------------------------------- /javascript进阶/demos/debounce/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | debounce 8 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /javascript进阶/demos/node-vm/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * http://www.alloyteam.com/2015/04/xiang-jie-nodejs-di-vm-mo-kuai/ 3 | */ 4 | var vm = require("vm"); 5 | var util = require("util"); 6 | 7 | var window = { 8 | p: 2, 9 | vm: vm, 10 | console: console, 11 | require: require 12 | }; 13 | 14 | var p = 5; 15 | 16 | global.p = 11; 17 | 18 | vm.createContext(window); 19 | 20 | // global是 undefined 21 | // vm.runInContext('p = 3;console.log(global);', window); 22 | 23 | // 报错 window is not defined 24 | // vm.runInContext('p = 3;console.log(window);', window); 25 | 26 | // this 是有值的 27 | vm.runInContext('p = 3;console.log(this);', window); 28 | 29 | 30 | // console.log(window.p);// 被改变为3 31 | // console.log(util.inspect(window)); 32 | -------------------------------------------------------------------------------- /javascript进阶/demos/scope/scope.bash: -------------------------------------------------------------------------------- 1 | value=1 2 | function foo () { 3 | echo $value; 4 | } 5 | function bar () { 6 | local value=2; 7 | foo; 8 | } 9 | bar -------------------------------------------------------------------------------- /javascript进阶/demos/template/template1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | template 6 | 7 | 8 | 9 |
10 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /javascript进阶/demos/template/template1/template.js: -------------------------------------------------------------------------------- 1 | // 模板引擎第一版 2 | (function() { 3 | this.tmpl = function (str, data) { 4 | 5 | var str = document.getElementById(str).innerHTML; 6 | 7 | var string = "var p = []; p.push('" + 8 | str 9 | .replace(/[\r\t\n]/g, "") 10 | .replace(/<%=(.*?)%>/g, "');p.push($1);p.push('") 11 | .replace(/<%/g, "');") 12 | .replace(/%>/g,"p.push('") 13 | + "');" 14 | 15 | eval(string) 16 | 17 | return p.join(''); 18 | }; 19 | })(); 20 | 21 | var results = document.getElementById("container"); 22 | 23 | var users = [ 24 | { "name": "Byron", "url": "http://localhost" }, 25 | { "name": "Casper", "url": "http://localhost" }, 26 | { "name": "Frank", "url": "http://localhost" } 27 | ] 28 | 29 | results.innerHTML = tmpl("user_tmpl", users); -------------------------------------------------------------------------------- /javascript进阶/demos/template/template2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | template 6 | 7 | 8 | 9 |
10 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /javascript进阶/demos/template/template2/template.js: -------------------------------------------------------------------------------- 1 | // 模板引擎第二版 2 | (function() { 3 | this.tmpl = function (str, data) { 4 | 5 | var str = document.getElementById(str).innerHTML; 6 | 7 | var fn = new Function("obj", 8 | 9 | "var p = []; p.push('" + 10 | 11 | str 12 | .replace(/[\r\t\n]/g, "") 13 | .replace(/<%=(.*?)%>/g, "');p.push($1);p.push('") 14 | .replace(/<%/g, "');") 15 | .replace(/%>/g,"p.push('") 16 | + "');return p.join('');"); 17 | 18 | return fn(data); 19 | }; 20 | })(); 21 | 22 | var results = document.getElementById("container"); 23 | 24 | var users = [ 25 | { "name": "Byron", "url": "http://localhost" }, 26 | { "name": "Casper", "url": "http://localhost" }, 27 | { "name": "Frank", "url": "http://localhost" } 28 | ] 29 | 30 | results.innerHTML = tmpl("user_tmpl", users); -------------------------------------------------------------------------------- /javascript进阶/demos/template/template3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | template 6 | 7 | 8 | 9 |
10 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /javascript进阶/demos/template/template3/template.js: -------------------------------------------------------------------------------- 1 | // 模板引擎第三版 2 | (function() { 3 | this.tmpl = function (str, data) { 4 | var str = document.getElementById(str).innerHTML; 5 | 6 | var fn = new Function("obj", 7 | 8 | "var p = []; with(obj){p.push('" + 9 | 10 | str 11 | .replace(/[\r\t\n]/g, "") 12 | .replace(/<%=(.*?)%>/g, "');p.push($1);p.push('") 13 | .replace(/<%/g, "');") 14 | .replace(/%>/g,"p.push('") 15 | + "');}return p.join('');"); 16 | 17 | return fn(data); 18 | }; 19 | })(); 20 | 21 | var results = document.getElementById("container"); 22 | 23 | var data2 = { 24 | users: [ 25 | { "name": "Byron", "url": "http://localhost" }, 26 | { "name": "Casper", "url": "http://localhost" }, 27 | { "name": "Frank", "url": "http://localhost" } 28 | ] 29 | } 30 | 31 | results.innerHTML = tmpl("user_tmpl", data2); -------------------------------------------------------------------------------- /javascript进阶/demos/template/template4.1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | template 6 | 7 | 8 | 9 |
10 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /javascript进阶/demos/template/template4.1/template.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 这是文章中的原版实现,文章中对代码进行了简化 3 | */ 4 | (function() { 5 | var cache = {}; 6 | 7 | this.tmpl = function tmpl(str, data) { 8 | // Figure out if we're getting a template, or if we need to 9 | // load the template - and be sure to cache the result. 10 | var fn = !/\W/.test(str) ? 11 | cache[str] = cache[str] || 12 | tmpl(document.getElementById(str).innerHTML) : 13 | 14 | // Generate a reusable function that will serve as a template 15 | // generator (and which will be cached). 16 | new Function("obj", 17 | "var p=[],print=function(){p.push.apply(p,arguments);};" + 18 | 19 | // Introduce the data as local variables using with(){} 20 | "with(obj){p.push('" + 21 | 22 | // Convert the template into pure JavaScript 23 | str 24 | .replace(/[\r\t\n]/g, " ") 25 | .split("<%").join("\t") 26 | .replace(/((^|%>)[^\t]*)'/g, "$1\r") 27 | .replace(/\t=(.*?)%>/g, "',$1,'") 28 | .split("\t").join("');") 29 | .split("%>").join("p.push('") 30 | .split("\r").join("\\'") + 31 | "');}return p.join('');"); 32 | 33 | // Provide some basic currying to the user 34 | return data ? fn(data) : fn; 35 | }; 36 | })(); 37 | 38 | var results = document.getElementById("container"); 39 | 40 | var data2 = { 41 | users: [ 42 | { "name": "Byron", "url": "http://localhost" }, 43 | { "name": "Casper", "url": "http://localhost" }, 44 | { "name": "Frank", "url": "http://localhost" } 45 | ] 46 | } 47 | 48 | var compiled = tmpl("user_tmpl", data2); 49 | results.innerHTML = compiled; -------------------------------------------------------------------------------- /javascript进阶/demos/template/template4/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | template 6 | 7 | 8 | 9 |
10 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /javascript进阶/demos/template/template4/template.js: -------------------------------------------------------------------------------- 1 | // 模板引擎第三版 2 | (function() { 3 | this.tmpl = function (str) { 4 | var str = document.getElementById(str).innerHTML; 5 | 6 | var fn = new Function("obj", 7 | 8 | "var p = []; with(obj){p.push('" + 9 | 10 | str 11 | .replace(/[\r\t\n]/g, "") 12 | .replace(/<%=(.*?)%>/g, "');p.push($1);p.push('") 13 | .replace(/<%/g, "');") 14 | .replace(/%>/g,"p.push('") 15 | + "');}return p.join('');"); 16 | 17 | var template = function(data) { 18 | return fn.call(this, data) 19 | } 20 | return template; 21 | }; 22 | })(); 23 | 24 | var results = document.getElementById("container"); 25 | 26 | var data2 = { 27 | users: [ 28 | { "name": "Byron", "url": "http://localhost" }, 29 | { "name": "Casper", "url": "http://localhost" }, 30 | { "name": "Frank", "url": "http://localhost" } 31 | ] 32 | } 33 | 34 | var compiled = tmpl("user_tmpl"); 35 | results.innerHTML = compiled(data2); -------------------------------------------------------------------------------- /javascript进阶/demos/template/template5/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | template 6 | 7 | 8 | 9 |
10 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /javascript进阶/demos/template/template5/template.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 模板引擎第五版 3 | */ 4 | 5 | var settings = { 6 | // 求值 7 | evaluate: /<%([\s\S]+?)%>/g, 8 | // 插入 9 | interpolate: /<%=([\s\S]+?)%>/g, 10 | }; 11 | 12 | var escapes = { 13 | "'": "'", 14 | '\\': '\\', 15 | '\r': 'r', 16 | '\n': 'n', 17 | '\u2028': 'u2028', 18 | '\u2029': 'u2029' 19 | }; 20 | 21 | var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; 22 | 23 | 24 | var template = function(text) { 25 | 26 | var source = "var __p='';\n"; 27 | source = source + "with(obj){\n" 28 | source = source + "__p+='"; 29 | 30 | var main = text 31 | .replace(escapeRegExp, function(match) { 32 | return '\\' + escapes[match]; 33 | }) 34 | .replace(settings.interpolate, function(match, interpolate){ 35 | return "'+\n" + interpolate + "+\n'" 36 | }) 37 | .replace(settings.evaluate, function(match, evaluate){ 38 | return "';\n " + evaluate + "\n__p+='" 39 | }) 40 | 41 | source = source + main + "';\n }; \n return __p;"; 42 | 43 | console.log(source) 44 | 45 | var render = new Function('obj', source); 46 | 47 | return render; 48 | }; 49 | 50 | var results = document.getElementById("container"); 51 | 52 | var data = { 53 | users: [ 54 | { "name": "Byron", "url": "http://localhost" }, 55 | { "name": "Casper", "url": "http://localhost" }, 56 | { "name": "Frank", "url": "http://localhost" } 57 | ] 58 | } 59 | 60 | var text = document.getElementById("user_tmpl").innerHTML 61 | var compiled = template(text); 62 | results.innerHTML = compiled(data); -------------------------------------------------------------------------------- /javascript进阶/demos/template/template6/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | template 6 | 7 | 8 | 9 |
10 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /javascript进阶/demos/template/template6/template.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 模板引擎第六版 3 | */ 4 | 5 | var settings = { 6 | // 求值 7 | evaluate: /<%([\s\S]+?)%>/g, 8 | // 插入 9 | interpolate: /<%=([\s\S]+?)%>/g, 10 | }; 11 | 12 | var escapes = { 13 | "'": "'", 14 | '\\': '\\', 15 | '\r': 'r', 16 | '\n': 'n', 17 | '\u2028': 'u2028', 18 | '\u2029': 'u2029' 19 | }; 20 | 21 | var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; 22 | 23 | 24 | var template = function(text) { 25 | 26 | var source = "var __t, __p='';\n"; 27 | source = source + "with(obj){\n" 28 | source = source + "__p+='"; 29 | 30 | var main = text 31 | .replace(escapeRegExp, function(match) { 32 | return '\\' + escapes[match]; 33 | }) 34 | .replace(settings.interpolate, function(match, interpolate){ 35 | return "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'" 36 | }) 37 | .replace(settings.evaluate, function(match, evaluate){ 38 | return "';\n " + evaluate + "\n__p+='" 39 | }) 40 | 41 | source = source + main + "';\n }; \n return __p;"; 42 | 43 | console.log(source) 44 | 45 | var render = new Function('obj', source); 46 | 47 | return render; 48 | }; 49 | 50 | var results = document.getElementById("container"); 51 | 52 | var data = { 53 | users: [ 54 | { "url": "http://localhost" }, 55 | { "name": "Casper", "url": "http://localhost" }, 56 | { "name": "Frank", "url": "http://localhost" } 57 | ] 58 | } 59 | 60 | var text = document.getElementById("user_tmpl").innerHTML 61 | var compiled = template(text); 62 | results.innerHTML = compiled(data); -------------------------------------------------------------------------------- /javascript进阶/demos/template/template7/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | template 6 | 7 | 8 | 9 |
10 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /javascript进阶/demos/template/template7/template.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 模板引擎第七版 3 | */ 4 | 5 | var settings = { 6 | // 求值 7 | evaluate: /<%([\s\S]+?)%>/g, 8 | // 插入 9 | interpolate: /<%=([\s\S]+?)%>/g, 10 | }; 11 | 12 | var escapes = { 13 | "'": "'", 14 | '\\': '\\', 15 | '\r': 'r', 16 | '\n': 'n', 17 | '\u2028': 'u2028', 18 | '\u2029': 'u2029' 19 | }; 20 | 21 | var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; 22 | 23 | 24 | var template = function(text) { 25 | 26 | var matcher = RegExp([ 27 | (settings.interpolate).source, 28 | (settings.evaluate).source 29 | ].join('|') + '|$', 'g'); 30 | 31 | var index = 0; 32 | var source = "__p+='"; 33 | 34 | text.replace(matcher, function(match, interpolate, evaluate, offset) { 35 | 36 | source += text.slice(index, offset).replace(escapeRegExp, function(match) { 37 | return '\\' + escapes[match]; 38 | }); 39 | 40 | index = offset + match.length; 41 | 42 | if (interpolate) { 43 | source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; 44 | } else if (evaluate) { 45 | source += "';\n" + evaluate + "\n__p+='"; 46 | } 47 | 48 | return match; 49 | }); 50 | 51 | source += "';\n"; 52 | 53 | source = 'with(obj||{}){\n' + source + '}\n' 54 | 55 | source = "var __t, __p='';" + 56 | source + 'return __p;\n'; 57 | 58 | console.log(source) 59 | 60 | var render = new Function('obj', source); 61 | 62 | return render; 63 | }; 64 | 65 | var results = document.getElementById("container"); 66 | 67 | var data = { 68 | users: [ 69 | { "url": "http://localhost" }, 70 | { "name": "Casper", "url": "http://localhost" }, 71 | { "name": "Frank", "url": "http://localhost" } 72 | ] 73 | } 74 | 75 | var text = document.getElementById("user_tmpl").innerHTML 76 | var compiled = template(text); 77 | results.innerHTML = compiled(data); -------------------------------------------------------------------------------- /javascript进阶/demos/template/template8/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | template 6 | 7 | 8 | 9 |
10 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /javascript进阶/demos/template/template8/template.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 模板引擎第八版 3 | */ 4 | var _ = {}; 5 | 6 | _.templateSettings = { 7 | // 求值 8 | evaluate: /<%([\s\S]+?)%>/g, 9 | // 插入 10 | interpolate: /<%=([\s\S]+?)%>/g, 11 | // 转义 12 | escape: /<%-([\s\S]+?)%>/g 13 | }; 14 | 15 | var noMatch = /(.)^/; 16 | 17 | var escapes = { 18 | "'": "'", 19 | '\\': '\\', 20 | '\r': 'r', 21 | '\n': 'n', 22 | '\u2028': 'u2028', 23 | '\u2029': 'u2029' 24 | }; 25 | 26 | var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; 27 | 28 | var escapeChar = function(match) { 29 | return '\\' + escapes[match]; 30 | }; 31 | 32 | _.template = function(text, settings) { 33 | 34 | settings = Object.assign({}, _.templateSettings, settings); 35 | 36 | var matcher = RegExp([ 37 | (settings.escape || noMatch).source, 38 | (settings.interpolate || noMatch).source, 39 | (settings.evaluate || noMatch).source 40 | ].join('|') + '|$', 'g'); 41 | 42 | var index = 0; 43 | var source = "__p+='"; 44 | text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { 45 | 46 | source += text.slice(index, offset).replace(escapeRegExp, escapeChar); 47 | 48 | index = offset + match.length; 49 | 50 | if (escape) { 51 | source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; 52 | } else if (interpolate) { 53 | source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; 54 | } else if (evaluate) { 55 | source += "';\n" + evaluate + "\n__p+='"; 56 | } 57 | 58 | return match; 59 | }); 60 | source += "';\n"; 61 | 62 | if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; 63 | 64 | source = "var __t,__p='',__j=Array.prototype.join," + 65 | "print=function(){__p+=__j.call(arguments,'');};\n" + 66 | source + 'return __p;\n'; 67 | 68 | var render; 69 | try { 70 | render = new Function(settings.variable || 'obj', '_', source); 71 | } catch (e) { 72 | e.source = source; 73 | throw e; 74 | } 75 | 76 | var template = function(data) { 77 | return render.call(this, data, _); 78 | }; 79 | 80 | var argument = settings.variable || 'obj'; 81 | template.source = 'function(' + argument + '){\n' + source + '}'; 82 | 83 | return template; 84 | }; 85 | 86 | var results = document.getElementById("container"); 87 | 88 | var data = { 89 | users: [ 90 | { "name": "Byron", "url": "http://localhost" }, 91 | { "name": "Casper", "url": "http://localhost" }, 92 | { "name": "Frank", "url": "http://localhost" } 93 | ] 94 | } 95 | 96 | var text = document.getElementById("user_tmpl").innerHTML 97 | var compiled = _.template(text); 98 | 99 | console.log(compiled.source) 100 | results.innerHTML = compiled(data); -------------------------------------------------------------------------------- /javascript进阶/demos/throttle/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | throttle 8 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /javascript进阶/demos/throttle/throttle1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 第一版 使用时间戳 3 | */ 4 | 5 | var count = 1; 6 | var container = document.getElementById('container'); 7 | 8 | function getUserAction() { 9 | container.innerHTML = count++; 10 | }; 11 | 12 | container.onmousemove = throttle(getUserAction, 1000); 13 | 14 | function throttle(func, wait) { 15 | var context, args; 16 | var previous = 0; 17 | 18 | return function() { 19 | var now = +new Date(); 20 | context = this; 21 | args = arguments; 22 | if (now - previous > wait) { 23 | func.apply(context, args); 24 | previous = now; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /javascript进阶/demos/throttle/throttle2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 第二版 使用定时器 3 | */ 4 | var count = 1; 5 | var container = document.getElementById('container'); 6 | 7 | function getUserAction() { 8 | container.innerHTML = count++; 9 | }; 10 | 11 | container.onmousemove = throttle(getUserAction, 3000); 12 | 13 | function throttle(func, wait) { 14 | var timeout; 15 | 16 | return function() { 17 | var context = this; 18 | var args = arguments; 19 | if (!timeout) { 20 | timeout = setTimeout(function(){ 21 | timeout = null; 22 | func.apply(context, args) 23 | }, wait) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /javascript进阶/demos/throttle/throttle3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 第三版 有头有尾 3 | */ 4 | var count = 1; 5 | var container = document.getElementById('container'); 6 | 7 | function getUserAction() { 8 | container.innerHTML = count++; 9 | }; 10 | 11 | container.onmousemove = throttle(getUserAction, 3000); 12 | 13 | function throttle(func, wait) { 14 | var timeout, context, args, result; 15 | var previous = 0; 16 | 17 | var later = function() { 18 | previous = +new Date(); 19 | timeout = null; 20 | func.apply(context, args) 21 | }; 22 | 23 | var throttled = function() { 24 | var now = +new Date(); 25 | //下次触发func剩余的时间 26 | var remaining = wait - (now - previous); 27 | context = this; 28 | args = arguments; 29 | // 如果没有剩余的时间了或者你改了系统时间 30 | if (remaining <= 0 || remaining > wait) { 31 | if (timeout) { 32 | clearTimeout(timeout); 33 | timeout = null; 34 | } 35 | previous = now; 36 | func.apply(context, args); 37 | } else if (!timeout) { 38 | timeout = setTimeout(later, remaining); 39 | } 40 | }; 41 | 42 | 43 | return throttled; 44 | } 45 | -------------------------------------------------------------------------------- /javascript进阶/demos/throttle/throttle4.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 第四版 有头无尾 或者 无头有尾 3 | * leading:false 表示禁用第一次执行 4 | * trailing: false 表示禁用停止触发的回调 5 | */ 6 | 7 | var count = 1; 8 | var container = document.getElementById('container'); 9 | 10 | function getUserAction() { 11 | container.innerHTML = count++; 12 | }; 13 | 14 | // container.onmousemove = throttle(getUserAction, 3000, { 15 | // leading: false 16 | // }); 17 | 18 | container.onmousemove = throttle(getUserAction, 3000, { 19 | trailing: false 20 | }); 21 | 22 | function throttle(func, wait, options) { 23 | var timeout, context, args, result; 24 | var previous = 0; 25 | if (!options) options = {}; 26 | 27 | var later = function() { 28 | previous = options.leading === false ? 0 : new Date().getTime(); 29 | timeout = null; 30 | func.apply(context, args); 31 | if (!timeout) context = args = null; 32 | }; 33 | 34 | var throttled = function() { 35 | var now = new Date().getTime(); 36 | if (!previous && options.leading === false) previous = now; 37 | var remaining = wait - (now - previous); 38 | context = this; 39 | args = arguments; 40 | if (remaining <= 0 || remaining > wait) { 41 | if (timeout) { 42 | clearTimeout(timeout); 43 | timeout = null; 44 | } 45 | previous = now; 46 | func.apply(context, args); 47 | if (!timeout) context = args = null; 48 | } else if (!timeout && options.trailing !== false) { 49 | timeout = setTimeout(later, remaining); 50 | } 51 | }; 52 | 53 | return throttled; 54 | } 55 | 56 | 57 | -------------------------------------------------------------------------------- /javascript进阶/demos/throttle/throttle5.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 第五版 添加取消方法 用法跟 debounce 相同 3 | */ 4 | 5 | var count = 1; 6 | var container = document.getElementById('container'); 7 | 8 | function getUserAction() { 9 | container.innerHTML = count++; 10 | }; 11 | 12 | var setUseAction = throttle(getUserAction, 10000); 13 | 14 | container.onmousemove = setUseAction 15 | 16 | document.getElementById("button").addEventListener('click', function(){ 17 | setUseAction.cancel(); 18 | }) 19 | 20 | function throttle(func, wait, options) { 21 | var timeout, context, args, result; 22 | var previous = 0; 23 | if (!options) options = {}; 24 | 25 | var later = function() { 26 | previous = options.leading === false ? 0 : new Date().getTime(); 27 | timeout = null; 28 | func.apply(context, args); 29 | if (!timeout) context = args = null; 30 | }; 31 | 32 | var throttled = function() { 33 | var now = new Date().getTime(); 34 | if (!previous && options.leading === false) previous = now; 35 | var remaining = wait - (now - previous); 36 | context = this; 37 | args = arguments; 38 | if (remaining <= 0 || remaining > wait) { 39 | if (timeout) { 40 | clearTimeout(timeout); 41 | timeout = null; 42 | } 43 | previous = now; 44 | func.apply(context, args); 45 | if (!timeout) context = args = null; 46 | } else if (!timeout && options.trailing !== false) { 47 | timeout = setTimeout(later, remaining); 48 | } 49 | }; 50 | 51 | throttled.cancel = function() { 52 | clearTimeout(timeout); 53 | previous = 0; 54 | timeout = null; 55 | }; 56 | 57 | return throttled; 58 | } 59 | -------------------------------------------------------------------------------- /javascript进阶/demos/web-worker/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Web Worker 3 | * 在火狐中可以直接打开测试,在 Chrome 中需要起服务器 4 | */ 5 | var i = 0; 6 | 7 | function timedCount() { 8 | i = i + 1; 9 | 10 | console.log('window 对象为:', typeof window) 11 | console.log('global 对象为:', typeof global) 12 | console.log('self 对象为:', self) 13 | var root = (typeof window == 'object' && window.window == window && window) || 14 | (typeof global == 'object' && global.global == global && global); 15 | console.log(root) 16 | postMessage(i); 17 | setTimeout("timedCount()", 500); 18 | } 19 | 20 | timedCount(); 21 | -------------------------------------------------------------------------------- /javascript进阶/demos/web-worker/webworker.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

Count numbers: 9 | 10 |

11 | 12 | 13 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /this.MD: -------------------------------------------------------------------------------- 1 | ### [换个角度看 JavaScript 中的 (this) => { 整理 (JavaScript 深入之从 ECMAScript 规范解读 this ) }](https://juejin.im/post/5c1c5bfcf265da614c4cc40e) 2 | ### [this全面解析](https://juejin.im/post/5c22dbd0518825438f6bb6fc#heading-13) 3 | ### [「前端面试题系列4」this的原理以及用法](https://juejin.im/post/5c428ce0f265da612b13dca7) 4 | ### [JavaScript中的this详解](https://juejin.im/post/5c45c3cb518825538d0f420b) 5 | ### [JS 的 this 指来指去到底指哪去了?(call, apply, bind 改变 this 指向)](https://juejin.im/post/5cbda5266fb9a03214376078) 6 | -------------------------------------------------------------------------------- /函数式编程.MD: -------------------------------------------------------------------------------- 1 | ### [JavaScript 函数式编程](https://juejin.im/post/5b4ac0d0f265da0fa959a785) 2 | ### [函数式编程简介](https://juejin.im/post/5b94e2efe51d450e4d2f9e5e) 3 | ### [深入学习javascript函数式编程](https://juejin.im/post/5c1a231de51d452ce364d945) 4 | ### [[译] 编写函数式的 JavaScript 实用指南](https://juejin.im/post/5c46c4416fb9a049eb3c42d5) 5 | ### [「前端面试题系列6」理解函数的柯里化](https://juejin.im/post/5c677041f265da2de25b7707) 6 | -------------------------------------------------------------------------------- /前端荣耀/移动端踩坑之旅-ios下fixed、软键盘相关问题总结.md: -------------------------------------------------------------------------------- 1 | ###移动端踩坑之旅-ios下fixed、软键盘相关问题总结 2 | 3 | ### [移动端踩坑之旅-ios下fixed、软键盘相关问题总结](https://juejin.im/post/59e725865188257e0c3246bf) 4 | 5 | ```javascript 6 | // 解决键盘弹出后挡表单的问题 7 | window.addEventListener('resize', function() { 8 | if( 9 | document.activeElement.tagName === 'INPUT' || 10 | document.activeElement.tagName === 'TEXTAREA' 11 | ) { 12 | window.setTimeout(function() { 13 | if('scrollIntoView' in document.activeElement) { 14 | document.activeElement.scrollIntoView(); 15 | } else { 16 | document.activeElement.scrollIntoViewIfNeeded(); 17 | } 18 | }, 0); 19 | } 20 | }); 21 | ``` 22 | -------------------------------------------------------------------------------- /前端趋势.MD: -------------------------------------------------------------------------------- 1 | ### [深度介绍:💾 你听说过原生 HTML 组件吗?](https://juejin.im/post/5bc7ead7f265da0afc2c2c6b) 2 | -------------------------------------------------------------------------------- /动画.MD: -------------------------------------------------------------------------------- 1 | ### [动画道路上的新宠 -- Lottie](https://juejin.im/post/5b7e74ce51882542a92ba0e9) 2 | -------------------------------------------------------------------------------- /后台.MD: -------------------------------------------------------------------------------- 1 | ### [网页版海报排版设计](https://github.com/libin1991/pageDesign) 2 | -------------------------------------------------------------------------------- /国际化.MD: -------------------------------------------------------------------------------- 1 | ### [如何快速解决繁杂的国际化替换](https://juejin.im/post/5b9f7976e51d450e9e43fd71) 2 | -------------------------------------------------------------------------------- /大屏展示.MD: -------------------------------------------------------------------------------- 1 | ### [用Vue构建一个github“可视化大数据平台”-GitDataV,设计开发分享](https://juejin.im/post/5b7f6cd46fb9a019f709b17b) 2 | ### [快速实现地图迁移数据可视化](https://juejin.im/post/5c1a2524f265da614b11f102) 3 | -------------------------------------------------------------------------------- /安全.MD: -------------------------------------------------------------------------------- 1 | ### [浅说 XSS 和 CSRF](https://juejin.im/post/5b6bf1136fb9a04fda4e4265) 2 | ### [关于csrf,什么是csrf,怎么防范它?](https://juejin.im/post/5b6b08956fb9a04fc67c2263) 3 | ### [快速找出网站中可能存在的XSS漏洞实践(一)](https://juejin.im/post/5b7bdfa1f265da437174ae0d) 4 | ### [XSS 攻击进阶(挖掘漏洞)](https://juejin.im/post/5ba05b9ef265da0abd350f47) 5 | ### [前端安全系列之二:如何防止CSRF攻击?](https://juejin.im/post/5bc009996fb9a05d0a055192) 6 | ### [常见 Web 安全攻防总结](https://zoumiaojiang.com/article/common-web-security/) 7 | ### [Web 安全漏洞之 XSS 攻击](https://juejin.im/post/5bf214e151882579cf011c2a) 8 | ### [每一个工程师都要学的安全测试,老板再也不用担心服务器被黑](https://juejin.im/post/5c186f785188257a937f9098#heading-4) 9 | ### [小心 !跨站点websocket劫持!](https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665515571&idx=1&sn=0d0b7dea7f77e8f1844b366f1af9667f&chksm=80d67270b7a1fb66d93bae6cb36eabb52671ca9c4fcfcbd4b99a0f97477ea3d7f7ef87f086f3&token=1745763505&lang=zh_CN#rd) 10 | -------------------------------------------------------------------------------- /小程序.MD: -------------------------------------------------------------------------------- 1 | ### [微信小程序开发BUG经验总结](https://juejin.im/post/5b0f4fb4f265da08eb04a245) 2 | ### [小程序:无限自动滚动的Gallery](https://juejin.im/post/5c3df35bf265da610e80503f) 3 | # [微信小程序 - 富文本图片宽度自适应](https://juejin.im/post/5c3d97aef265da611e4de22b) 4 | # [小程序无限层级路由方案(无框架依赖)](https://juejin.im/post/5c09d82e51882517165dd485) 5 | # [微信小程序自定义组件实现 tabBar、navBar](https://juejin.im/post/5c3b35d2e51d455244740c66) 6 | ## [你可能不知道的小程序](https://juejin.im/post/5bfbc03ef265da615c58f0a5) 7 | ### [手把手教你迁移微信小程序到 QQ 浏览器](https://juejin.im/post/5c18f12ee51d45702018c38a) 8 | ### [微信小程序左滑删除功能开发案例,调用高德地图api,路线规划/规划详情演示,城市列表首字母排序](https://juejin.im/post/5be81e1251882516f578628a) 9 | ## [批量生成100万张小程序码?了解一下。](https://juejin.im/post/5bee7ec1e51d455fb4725471) 10 | ### [微信小程序之animation底部弹窗动画(两种方法)](https://juejin.im/post/5bd7ce15e51d4531b36efd5c) 11 | ### [微信小程序——踩坑篇](https://juejin.im/post/5b161c4bf265da6e1a603029) 12 | ### [微信小程序之物流状态时间轴](https://juejin.im/post/5bd17b0be51d457ab36d00b3) 13 | ### [小程序开发实践总结,坑](https://juejin.im/post/5b74d85751882560fb24b6c5) 14 | ### [给你安利几个小程序的“坑”](https://juejin.im/post/5b248a0e6fb9a00e833d4437) 15 | ### [小程序生成图片库,轻松通过 json 方式绘制一张可以发到朋友圈的图片](https://github.com/Kujiale-Mobile/Painter) 16 | ### [小程序生成图片库,轻松通过 json 方式绘制一张可以发到朋友圈的图片](https://github.com/libin1991/Painter) 17 | ### [微信小程序 canvas 绘图问题总结](https://juejin.im/post/5b41cb605188251aa82905af) 18 | ### [快给我打一个小程序预览码](http://web.jobbole.com/94910/) 19 | ### [小程序开发技巧总结](https://juejin.im/post/5b4f0ee95188251ad06b5f2a) 20 | ### [简易商城小程序全栈开发(mpvue+koa+mongodb)](https://juejin.im/post/5b548ce8e51d45191d79f8a6) 21 | ### [第一个mpvue小程序开发完了,来总结下吧](https://juejin.im/post/5b67e9c6f265da0f955cf158) 22 | ### [小程序中使用字体图标](https://juejin.im/post/5b712160f265da27ea319f2b) 23 | ### [小程序居然可以用WXS模拟实现过滤器!](https://juejin.im/post/5b7148da51882560fd2340c7) 24 | ### [你还在发愁小程序自定义导航栏吗?](https://juejin.im/post/5b7d5f5551882542e32a99c6) 25 | ### [撸个微信小程序的省市区选择器](https://juejin.im/post/5b7520966fb9a0099744a96f) 26 | ### [小程序如何发红包](https://juejin.im/post/5b94d6ad6fb9a05d3634bb4b) 27 | ### [一起给小程序原生的swiper化个妆,让她变成更漂亮点的banner吧](https://juejin.im/post/5b839bd86fb9a01a182683a3) 28 | ### [小程序的全栈开发新时代--云开发](https://juejin.im/post/5ba0bc8d6fb9a05d396f0827) 29 | ### [通过canvas生成图片并保存到本地](https://juejin.im/post/5b9a3113f265da0aaa04fffc) 30 | ### [小程序导出朋友圈海报详细记录](https://juejin.im/post/5b9dab12f265da0acf0ad156) 31 | ### [【5星级】html2img小程序生成图片库,轻松通过 json 方式绘制一张可以发到朋友圈的图片](https://github.com/libin1991/Painter) 32 | ### [mpvue官方分包](https://juejin.im/post/5b9919165188255c847394b0) 33 | ### [做完小程序项目、老板给我加了6k薪资~](https://juejin.im/post/5ba57b7c5188255c971fda3a) 34 | ### [Westore 1.0 正式发布 - 世界上最小却强大的小程序框架](https://juejin.im/post/5ba9d6a1e51d450e92522fe7) 35 | ## [微信小程序 bug 集中营](https://juejin.im/post/5bb86a62f265da0adc18e089) 36 | ### [小程序选人控件 - 仿企业微信实现多层级无规则嵌套](https://juejin.im/post/5bd3ec0551882528382d8028) 37 | ## [论如何将 h5 页面快速转换成微信小程序](https://juejin.im/post/5bed442c51882531b81ae51f) 38 | ## [微信小程序推广二维码海报Node.js实现版](https://juejin.im/post/5c05edbd6fb9a049be5d40c9) 39 | ### [小程序云开发让你不再加班](https://juejin.im/post/5bf0c908f265da61715deeaa) 40 | ### [微信小程序引入Font Awesome-icon](https://juejin.im/post/5c0e31fee51d457c5335f824) 41 | ## [小程序白屏问题和内存研究](https://juejin.im/post/5c108509e51d4510bf53b0be) 42 | ## [小程序中富文本解决方案](https://juejin.im/post/5c2350cee51d451b1c6ddb08) 43 | ### [微信小程序踩坑指南](https://juejin.im/post/5c259a8ee51d454b982930f9) 44 | ## [微信小程序,实现 watch 属性,监听数据变化](https://juejin.im/post/5c2e16236fb9a049f23ce159) 45 | -------------------------------------------------------------------------------- /微信.MD: -------------------------------------------------------------------------------- 1 | ### [神经病啊!——微信同层播放器接(踩)入(坑)总](https://segmentfault.com/a/1190000008782550) 2 | ### [记录一次vue2.0(history模式)下微信自定义分享的坑](https://juejin.im/post/5b8e44b3f265da433109ac4f) 3 | ### [前端对接微信分享功能完全指南](https://juejin.im/post/5be4238df265da6142736496) 4 | ### [纯前端导出微信通讯录到 Excel](https://juejin.im/post/5bebd0e5f265da61417120a9) 5 | ### [vue项目接入微信JSSDK的坑](https://juejin.im/post/5c121be6e51d4504bc5e542e) 6 | ### [搭建前后端分离开发模式下的微信网页项目](http://shuaihua.cc/article/1544885079777/) 7 | -------------------------------------------------------------------------------- /性能与异常上报.MD: -------------------------------------------------------------------------------- 1 | ### [前端性能与异常上报](https://juejin.im/post/5b5dcfb46fb9a04f8f37afbb) 2 | ### [前端性能与异常上报](https://github.com/xingbofeng/xingbofeng.github.io/issues/36) 3 | ### [前端性能监控:window.performance](https://juejin.im/post/59eb01e45188250988738938) 4 | ### [狙杀页面卡顿 —— Performance 指北](https://juejin.im/post/5b65105f5188251b134e9778) 5 | ### [[译] 使用 Web Beacon API 记录活动](https://juejin.im/post/5b694b5de51d4519700fa56a) 6 | ### [前端异常监控、上报及js压缩代码定位](https://juejin.im/post/5b55c3495188251acb0cf907) 7 | ### [前端错误收集以及统一异常处理](https://juejin.im/post/5be2b0f6e51d4523161b92f0) 8 | ### [zanePerfor 一款完整,高性能,高可用的前端性能监控系统](https://juejin.im/post/5be3ec29518825170b101f66) 9 | ### [前端错误监控与上报](https://juejin.im/post/5beb7dcff265da614f6fdbce) 10 | ### [浅谈前端错误处理](https://juejin.im/post/5bebcde951882516f663488e) 11 | ## [如何优雅处理前端异常?](http://jartto.wang/2018/11/20/js-exception-handling/) 12 | ### [js错误处理权威指北](https://juejin.im/post/5bfa5a8cf265da6124151e62) 13 | ### [前端开发中的Error以及异常捕获](https://juejin.im/post/5c2d60616fb9a049dc025c39) 14 | -------------------------------------------------------------------------------- /性能优化.MD: -------------------------------------------------------------------------------- 1 | ### [网站性能优化实战——从12.67s到1.06s的故事](https://juejin.im/post/5b0b7d74518825158e173a0c) 2 | ## [React性能优化总结](https://segmentfault.com/a/1190000007811296) 3 | ## [JavaScript的工作原理:引擎,运行时和调用堆栈](https://juejin.im/post/5c3ef2a76fb9a049df2456ee) 4 | ### [前端性能优化--从 10 多秒到 1.05 秒](https://juejin.im/post/5b0bff30f265da08f76cc6f0) 5 | ### [前端性能优化之关键路径渲染优化 ](https://github.com/fi3ework/blog/issues/16) 6 | ### [预加载与缓存](https://juejin.im/post/5b17e7f5e51d4506af2e8e42) 7 | ### [令人愉悦的性能统计分析工具](https://github.com/libin1991/hiper) 8 | ### [一个视频video首屏的优化过程](https://juejin.im/post/5b68288df265da0fa21aa6bf) 9 | ### [网站性能优化实战——从12.67s到1.06s的故事](https://juejin.im/post/5b6fa8c86fb9a0099910ac91) 10 | ### [React 16 ,webpack4加载性能优化指南](https://juejin.im/post/5b7272def265da2834796b73) 11 | ### [页面渲染:性能分析](https://juejin.im/post/5b879e16f265da436d7e543c) 12 | ## [Vue 应用性能优化指南](https://juejin.im/post/5b960fcae51d450e9d645c5f) 13 | ## [React性能分析利器来了,妈妈再也不用担心我的React应用慢了](https://juejin.im/post/5ba1f995f265da0a972e1657) 14 | ### [有一种优化,叫Preload](https://mp.weixin.qq.com/s?__biz=MzUxMTcwOTM4Mg==&mid=2247484163&idx=1&sn=16b9c907971683dd61cee251adcde79b&chksm=f96edaaace1953bcaf65a1adcf30b6d3dd66cf7b648ae59c4bf807d3f8bf460d5cd638e54ca1&token=946370022&lang=zh_CN#rd) 15 | ### [Vue项目优化实践 —— CDN + Gzip + Prerender](https://juejin.im/post/5b97b84ee51d450e6c7492f6) 16 | ### [前端性能优化之防抖-debounce](https://juejin.im/post/5be693d16fb9a04a053f2f1c) 17 | ## [如何监控网页崩溃?](https://zhuanlan.zhihu.com/p/40273861) 18 | ## [深度讲解:web前端性能优化](https://juejin.im/post/5c011e0c5188252ea66afdfa) 19 | ## [我是如何将页面加载时间从6S降到2S的?](https://juejin.im/post/5c07c6b96fb9a04a0d56a3cc#comment) 20 | ## [Web前端性能优化——如何提高页面加载速度](https://www.cnblogs.com/MarcoHan/p/5295398.html) 21 | ### [详解 CRP:如何最大化提升首屏渲染速度](https://juejin.im/post/5c33794bf265da6158775100) 22 | ### [(译)2019年前端性能优化清单 — 上篇](https://juejin.im/post/5c46cbaee51d453f45612a2c) 23 | ### [(译)2019年前端性能优化清单 — 中篇](https://juejin.im/post/5c471eaff265da616d547c8c) 24 | ### [(译)2019年前端性能优化清单 — 下篇](https://juejin.im/post/5c473cdae51d45518d4701ff) 25 | -------------------------------------------------------------------------------- /技巧.MD: -------------------------------------------------------------------------------- 1 | ### [特定场景下取代if-else和switch的方案](https://juejin.im/post/5b4b73e7f265da0f96287f0a) 2 | ## [移动端调试痛点?——送你五款前端开发利器](https://juejin.im/post/5b72e1f66fb9a009d018fb94) 3 | ### [扔掉Nginx,扔掉SwitchHosts,做纯粹的前端开发](https://coderge.com/articles/201808/pure-frontend-developer.html) 4 | ### [真▪一行代码完成从前端代码build到部署线上](https://juejin.im/post/5b6ab179f265da0f900e3f2b) 5 | ### [Web 端反爬虫技术方案](https://juejin.im/post/5b6d579cf265da0f6e51a7e0) 6 | ### [nodejs实现一个word文档解析器](https://juejin.im/post/5b713f0de51d456679159c6f) 7 | ### [开源库架构实战——从0到1搭建属于你自己的开源库](https://juejin.im/post/5b729909e51d45662434aef0#heading-7) 8 | ## [Web全屏模式](https://juejin.im/post/5b73d5d651882560ff5c15a4) 9 | ### [IOS下box-shadow的诡异bug的修复](https://juejin.im/post/5b739d97f265da28065fb1bc) 10 | ### [配置Tree Shaking来减少JavaScript的打包体积](https://juejin.im/post/5b7381c0f265da27dd66c6fd) 11 | ### [Vue项目使用eslint + prettier规范代码风格](https://juejin.im/post/5b79a52651882543025ac6d7) 12 | ### [告别庞大 PSD,轻松测量尺寸](https://imcuttle.github.io/make-psd-measurable) 13 | ### [常见的Javascript获取时间戳](https://juejin.im/post/5bc80178f265da0af334a674) 14 | ### [纯JS生成并下载各种文本文件或图片](https://juejin.im/post/5bd1b0aa6fb9a05d2c43f004) 15 | ## [JavaScript 复杂判断的更优雅写法](https://juejin.im/post/5bdfef86e51d453bf8051bf8) 16 | ## [H5 移动调试全攻略](http://jartto.wang/2018/11/01/mobile-debug/) 17 | ## [OMG,这些鲜为人知的JavaScript 特性!](https://segmentfault.com/a/1190000017303869#articleHeader3) 18 | -------------------------------------------------------------------------------- /数据结构算法.MD: -------------------------------------------------------------------------------- 1 | ### [前端也要会的数据结构 (不定期更新篇)](https://juejin.im/post/5b65a7fdf265da0fa00a3999) 2 | ### [前端也需要了解的数据结构-链表](https://juejin.im/post/5bf99f5e5188256d9832bb6d) 3 | ### [前端进阶(第一期)-调用堆栈笔记](https://juejin.im/post/5bfb4af1e51d4574b133d1e3) 4 | ## [五分钟学会一个高难度算法:希尔排序](https://juejin.im/post/5bf9f2285188256b0f5832a0) 5 | ### [看动画轻松理解「 堆 」](https://juejin.im/post/5c1ae6545188256a272a9cee) 6 | ### [算法篇 - 二叉搜索树](https://juejin.im/post/5c4468dae51d457d1b7f40c7) 7 | -------------------------------------------------------------------------------- /游戏.MD: -------------------------------------------------------------------------------- 1 | ### [CreateJS 新司机开车指南](https://zhuanlan.zhihu.com/p/40799542) 2 | -------------------------------------------------------------------------------- /爬虫.MD: -------------------------------------------------------------------------------- 1 | ### [node爬虫 => koa2创建一个port => axios请求数据](https://github.com/libin1991/node-koa2-axios) 2 | ### [分分钟教你用node.js写个爬虫](https://juejin.im/post/5b4f007fe51d4519277b9707) 3 | ### [Node.js爬取科技新闻网站cnBeta(附前端及服务端源码)](https://juejin.im/post/5c163e97f265da614171787a) 4 | -------------------------------------------------------------------------------- /算法.MD: -------------------------------------------------------------------------------- 1 | ### [js 无序数组 任意个数 相加之和为定量m?](https://segmentfault.com/q/1010000004185340) 2 | ### [从数组中选择m个数,使得和为sum,递归写法](https://blog.csdn.net/chen895281773/article/details/8819143) 3 | ## [10个台阶,每次只能上1个或者2个,一共有多少种走法](https://blog.csdn.net/kikitious_du/article/details/79057803) 4 | ### [记一次递归在我项目中所发挥的作用](https://juejin.im/post/5c26c764e51d457457291fae) 5 | ### [JavaScript 算法之复杂度分析](https://juejin.im/post/5c2a1d9d6fb9a04a0f654581#heading-9) 6 | ### [一道有意思的面试算法题](https://juejin.im/post/5c2ec7a0f265da612d196659) 7 | -------------------------------------------------------------------------------- /设计模式.MD: -------------------------------------------------------------------------------- 1 | # [每天一个设计模式](https://godbmw.com/categories/%E6%AF%8F%E5%A4%A9%E4%B8%80%E4%B8%AA%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/) 2 | --- 3 | ### [JavaScript 中常见设计模式整理](https://juejin.im/post/5afe6430518825428630bc4d) 4 | ### [发布订阅模式,在工作中它的能量超乎你的想象](https://juejin.im/post/5b125ad3e51d450688133f22) 5 | ### [每天一个设计模式](https://godbmw.com/archives/) 6 | ### [【JavaScript】常用设计模式及编程技巧(ES6描述)](https://juejin.im/post/5bf6c7076fb9a049b2218532#heading-13) 7 | ### [聊聊Typescript中的设计模式——装饰器篇(decorators)](https://juejin.im/post/5c1705dd51882567b920c795) 8 | ### [Javascript策略模式理解以及应用](https://juejin.im/post/5c0e7f83f265da61407ebdca#comment) 9 | ### [js设计模式--策略模式](https://juejin.im/post/5c2cd45b6fb9a049ed30faad) 10 | -------------------------------------------------------------------------------- /跨域.MD: -------------------------------------------------------------------------------- 1 | ### [前端常见跨域解决方案](https://github.com/libin1991/libin_Blog/issues/33) 2 | ### [跨域,你需要知道的全在这里](https://github.com/libin1991/libin_Blog/issues/169) 3 | ### [前端常见跨域解决方案](https://github.com/libin1991/libin_Blog/issues/177) 4 | ### [一种方便的跨域开发解决方案](https://github.com/libin1991/libin_Blog/issues/425) 5 | ### [那些年前端跨过的域,跨域](https://github.com/libin1991/libin_Blog/issues/553) 6 | ### [jsonpGet,跨域如此简单](https://juejin.im/post/5b746accf265da280d57928f) 7 | ### [前端跨域方法论](https://juejin.im/post/5b91d3be5188255c95380b5e) 8 | ## [JavaScript之跨域解决方式](https://juejin.im/post/5c03e24d6fb9a04a07301de0) 9 | ## [跨域不完全探究](https://juejin.im/post/5c03c26d51882556782cc007) 10 | ### [跨域资源共享CORS](https://juejin.im/post/5c370772e51d4503834d40c1) 11 | ### [【小哥哥, 跨域要不要了解下】CORS 进阶篇](https://juejin.im/post/5c0b5a8851882548e9380afb) 12 | ### [【小哥哥, 跨域要不要了解下】CORS 基础篇](https://juejin.im/post/5c0a55e76fb9a049ef2665ba) 13 | ### [CORS 标准解析与实践检验](https://github.com/chesscai/cors) 14 | ## [CORS跨域时,为何会出现一次动作,两次请求?](https://juejin.im/post/5c46af87e51d4552232feaeb) 15 | ### [web开发的跨域问题详解](https://juejin.im/post/5c25f1595188257abf1d9031) 16 | ### [九种 “姿势” 让你彻底解决跨域问题](https://segmentfault.com/a/1190000016653873#articleHeader5) 17 | ### [前端跨域问题解决方案(基于node与nginx)](https://juejin.im/post/5c35f6286fb9a049be5dad82) 18 | ### [九种 “姿势” 让你彻底解决跨域问题](https://segmentfault.com/a/1190000016653873#articleHeader10) 19 | -------------------------------------------------------------------------------- /面试2.MD: -------------------------------------------------------------------------------- 1 | ### [跨域总结](https://juejin.im/post/5b5ff1dfe51d4519610e26ec) 2 | ## [前端面试系统准备](https://github.com/libin1991/libin_Blog/issues/607) 3 | ## [浅说 XSS 和 CSRF](https://juejin.im/timeline/frontend) 4 | ### [[译] JavaScript中的“this”是什么?](https://juejin.im/post/5b6676e6f265da0fa00a3a12) 5 | ### [可能是最好的正则表达式的教程笔记了吧...](https://juejin.im/post/5b5db5b8e51d4519155720d2#comment) 6 | ## [函数防抖和节流](https://juejin.im/post/5b651dc15188251aa30c8669) 7 | ![1533045856 1](https://user-images.githubusercontent.com/16753554/43464913-ca6b33c2-950e-11e8-9cb9-febe0d7d20bb.jpg) 8 | ### [不要再问我跨域的问题了](http://web.jobbole.com/94928/) 9 | ### [深入浅出的“深拷贝与浅拷贝”](https://juejin.im/post/5b56f2325188251b1f2261bc) 10 | ## [前端异常监控](https://juejin.im/post/5b53218cf265da0f9313a3de) 11 | ## [Vuex基本使用的总结](https://juejin.im/post/5b573babf265da0fa50a1cad) 12 | ## [CSS中重要的BFC](https://juejin.im/post/5b51ee276fb9a04f86062cea) 13 | ## [Vue的钩子函数[路由导航守卫、keep-alive、生命周期钩子]](https://juejin.im/post/5b41bdef6fb9a04fe63765f1) 14 | ## [Vue的使用总结和技巧](https://juejin.im/post/5b56981b6fb9a04fd4509b76) 15 | ## [你可能从未听说过这15个HTML元素方法!](https://mp.weixin.qq.com/s?__biz=MzUxMzcxMzE5Ng==&mid=2247489226&idx=1&sn=5a6bd84ae30777ca5c57c1b0b1903a01&chksm=f951a389ce262a9f2f1298f0d02d4bcbc79142df26ffc62079b48c4b56a012e822eb88ed0cd8) 16 | ## [vue权限路由实现方式总结](https://juejin.im/post/5b5bfd5b6fb9a04fdd7d687a) 17 | ## [移动端常见bug](http://forum.bestvist.com/topic/100/%E7%A7%BB%E5%8A%A8%E7%AB%AF%E5%B8%B8%E8%A7%81bug) 18 | ### [JavaScript 学习之继承](https://juejin.im/post/5b4d9ed0e51d45198c018c87) 19 | ### [JavaScript实现继承的方式](https://juejin.im/post/5aab690cf265da237b21d737) 20 | ### [JS 检测网络带宽](https://juejin.im/post/5b4de6b7e51d45190d55340b#comment) 21 | ## [React 16 加载性能优化指南](https://juejin.im/post/5b506ae0e51d45191a0d4ec9) 22 | ## [前端工程师需要知道的反爬虫知识](https://juejin.im/post/5b4fed556fb9a04f8856cf46#comment) 23 | ## [水波图实现原理canvas](https://juejin.im/post/5b4ffa045188251b134e7211) 24 | ### [手把手教你搭建微信小程序服务器(HTTPS)](https://juejin.im/post/5b4f085b51882519790c82dd) 25 | ## [JS 中可以提升幸福度的小技巧](https://juejin.im/post/5b51e5d3f265da0f4861143c) 26 | ## [前端水印生成方案](https://musicfe.cn/page/15) 27 | ### [看看你,都用终端干了些什么事⁉️文末彩蛋](https://juejin.im/post/5b5409def265da0f6a0356f1) 28 | ## [解读js模块化方案modJS](https://juejin.im/post/5b52e1faf265da0f82022eff) 29 | ## [批量异步更新与nextTick原理](https://juejin.im/post/5b50760f5188251ad06b61be) 30 | ## [30分钟从零开始教会你什么是PWA](https://juejin.im/post/5b519d77f265da0f9d19ff3e) 31 | ## [Vuex 原理浅析笔记](https://juejin.im/post/5b52bb6d5188251b3e645b1e) 32 | ## [前端通过spark-md5.js计算本地文件md5](https://juejin.im/post/5b52a7535188251b381270a4) 33 | ## [node-"fs-extra"模块代替fs使用](https://juejin.im/post/5b52fd21e51d4519234468f1) 34 | ### [使用Chrome开发者工具调试Android端内网页(微信,QQ,UC,App内嵌页等)](https://juejin.im/post/5b558be7e51d4519984139e6) 35 | ## [Vue + Canvas项目总结](https://juejin.im/post/5b529ddaf265da0f504a552c) 36 | ## [柯里化与反柯里化](https://juejin.im/post/5b561426518825195f499772) 37 | ### [聊聊web缓存那些事!](https://juejin.im/post/5b1a7cd16fb9a01e7342d960) 38 | ### [create-react-app源码解读](https://juejin.im/post/5b56e84351882569fd2873ab) 39 | ### [通过几句node.js为前端初学者写个常用工具(node 拼接字符串,判断换行)](https://juejin.im/post/5b56e585e51d4535a65ad0b0) 40 | ### [一起来学习如何用 Node 来制作 CLI](https://juejin.im/post/5b581795e51d453509561b34) 41 | ### [前端面试&笔试&错题指南(二)](https://juejin.im/post/5b5749cbe51d453467550494) 42 | ### [Vuex基本使用的总结](https://juejin.im/post/5b573babf265da0fa50a1cad) 43 | # [从promise到async function](https://juejin.im/post/5b56d9555188251b134e7c51) 44 | ### [前端图片canvas,file,blob,DataURL等格式转换](https://juejin.im/post/5b5187da51882519ec07fa41) 45 | ### [循序渐进教你实现一个完整的node的EventEmitter模块](https://github.com/forthealllight/blog/issues/21) 46 | ### [手把手教你用原生JavaScript造轮子(1)——分页器](https://juejin.im/post/5b592635e51d4533d2043e15) 47 | ### [这样你都不懂Promise,算我输!](https://juejin.im/post/5b5491856fb9a04fa8672cad) 48 | ### [Vue-cli原理分析](https://juejin.im/post/5b592db551882536e5178ce6) 49 | ## [如何在 JS 代码中消灭 for 循环](https://juejin.im/post/5b5a9451f265da0f6a036346) 50 | ### [Form表单你真的了解么?](http://www.scopeman.cn/doc/record?id=5b560cb049bd3f0b908444a9) 51 | ### [canvas核心技术-如何绘制图片和文本](https://juejin.im/post/5b5a6d77e51d45162679d13c) 52 | ### [你真的了解前端路由吗?](https://juejin.im/post/5b5ec5dd6fb9a04fc564b72d) 53 | ### [慎用JS中的slice()、concat()和assign()方法来复制数组](https://juejin.im/post/5b5d6eaa6fb9a04faa79b40d) 54 | ## [ES6 Promise的使用和理解](https://juejin.im/post/5b605b035188251a90189c61) 55 | ## [浅拷贝与深拷贝](https://juejin.im/post/5b5dcf8351882519790c9a2e) 56 | ## [下拉菜单「点击外面关闭」的终极解决方案](https://juejin.im/post/5b615ca5f265da0f563df07d) 57 | ### [js在微信、微博、QQ、Safari唤起App的解决方案](https://juejin.im/post/5b6193c66fb9a04fb615017f) 58 | ### [在 CSS 动画中使用硬件加速(翻译)](https://juejin.im/post/5b6143996fb9a04fd343ae28) 59 | ### [DataURL 与 File,Blob,canvas 对象之间的互相转换](https://juejin.im/post/5b626b68e51d451956055651) 60 | ### [web移动端布局的那些事儿](https://juejin.im/post/5b6575b0518825196b01fd85) 61 | ## [JS数组专题1️⃣ ➖ 数组扁平化](https://juejin.im/post/5b67a5cee51d4519873f94d5) 62 | ## [vue中Axios的封装和API接口的管理](https://juejin.im/post/5b55c118f265da0f6f1aa354) 63 | ## [动手理解导航守卫(Vue)](https://juejin.im/post/5b681397f265da0f6436eaf3) 64 | ## [JavaScript数组的十八般武艺](https://juejin.im/post/5b684ef9e51d451964629ba1#heading-19) 65 | ## [你真的懂模块化吗?教你CommonJS实现](https://juejin.im/post/5b67c342e51d45172832123d) 66 | ## [前端er怎样操作剪切复制以及禁止复制+破解等](https://juejin.im/post/5b66993ee51d451924734c35) 67 | ### [Web全屏模式](https://juejin.im/post/5b73d5d651882560ff5c15a4) 68 | -------------------------------------------------------------------------------- /面试3.MD: -------------------------------------------------------------------------------- 1 | ### [2018前端面试总结,看完弄懂,工资少说加3K | 掘金技术征文](https://juejin.im/post/5b94d8965188255c5a0cdc02) 2 | ## [2万5千字大厂面经 | 掘金技术征文](https://juejin.im/post/5ba34e54e51d450e5162789b#comment) 3 | ## [前端常用插件、工具类库汇总,不要重复造轮子啦!!!](https://juejin.im/post/5ba7d5dd5188255c6140cc9d) 4 | ### [记一次前端大厂面试](https://juejin.im/post/5b9770056fb9a05d2f3692ce) 5 | ## [基于webpack4[.3+]构建可预测的持久化缓存方案](https://juejin.im/post/5b977a19f265da0ac4469057) 6 | ### [webpack性能优化不完全指北](https://juejin.im/post/5b8ac03ff265da431c627f8e) 7 | ### [前端性能优化webpack—js代码打包](https://juejin.im/post/5b9550806fb9a05cff31f7b3) 8 | ### [JS的节流、函数防抖 原理及使用场景](https://juejin.im/post/5b961773f265da0a9e52f0e3#comment) 9 | ### [vue2.0做移动端开发用到的相关插件和经验总结](https://juejin.im/post/5b80f4e36fb9a019ce148fe9) 10 | ### [babel 用法及其 .babelrc 的配置详解,想做前端架构,拒绝一知半解...](http://www.cnblogs.com/jiebba/p/9613248.html) 11 | ### [Vue: scoped 样式与 CSS Module 对比](https://juejin.im/post/5b9556446fb9a05d1b2e3613) 12 | ### [大白话讲解Promise(一)](https://www.cnblogs.com/lvdabao/p/es6-promise-1.html) 13 | ``` 14 | 31 | ``` 32 | |语言 | 实现 |特性 |赋值 |缩进 | 33 | | ------ | ------ | ------ | ------ |------ | 34 | |Sass |Ruby |变量$开头 | $var: value | 不需要 | 35 | |Less |JavaSript |变量@开头 | @var: value |不需要 | 36 | |Stylus |NodeJs |不能使用@开头 | var:10 |都可以 | 37 | ### [携程前端模拟排序动画](https://juejin.im/post/5b8fcaaee51d450e44378a5f) 38 | ### [JavaScript中高阶函数的魅力](https://juejin.im/post/5b8c8a6951882542ee717c86) 39 | ### [带你彻底弄懂Event Loop](https://juejin.im/post/5b8f76675188255c7c653811) 40 | ### [React专题:操作DOM](https://juejin.im/post/5b907ad65188255c38533bbf) 41 | ### [从babel实现es6类的继承来深入理解js的原型及继承](https://juejin.im/post/5b8d239b51882542d23a2a05) 42 | ``` 43 | 44 | 45 | 46 | 47 | 48 | 53 | 54 | 55 | 56 | 73 |
哈哈
74 | 82 | 83 | 84 | 85 | ``` 86 | ## 百度面试题 87 | ``` 88 | // 解决键盘弹出后挡表单的问题 89 | window.addEventListener('resize', function() { 90 | if( 91 | document.activeElement.tagName === 'INPUT' || 92 | document.activeElement.tagName === 'TEXTAREA' 93 | ) { 94 | window.setTimeout(function() { 95 | if('scrollIntoView' in document.activeElement) { 96 | document.activeElement.scrollIntoView(); 97 | } else { 98 | document.activeElement.scrollIntoViewIfNeeded(); 99 | } 100 | }, 0); 101 | } 102 | }); 103 | ``` 104 | ### [HTTP三种缓存方式](https://juejin.im/post/5b8d10c66fb9a019f82fc16e) 105 | ### [一起探讨 JavaScript 的对象](https://juejin.im/post/5b8b3f5ee51d4538a7520e05) 106 | ### [JavaScript设计模式之面向对象编程](https://juejin.im/post/5b87b393e51d4557631bf5f0) 107 | ### [css加载会造成阻塞吗?](https://juejin.im/post/5b88ddca6fb9a019c7717096) 108 | ### [前端数据校验从建模开始](https://juejin.im/post/5b87c8a5e51d4538e41067a8) 109 | ### [页面渲染:过程分析](https://juejin.im/post/5b879d0fe51d4538843631c1) 110 | ### [制作60fps的高性能动画](https://juejin.im/post/5b8d032f6fb9a019e04eb969) 111 | ### [你在用 JWT 代替 Session?](https://juejin.im/post/5b8a99f3e51d4538bf55dbf9) 112 | ### [推送事件 && 第八篇:显示一个通知](https://juejin.im/post/5b8d10cd6fb9a019fd147510) 113 | ### [7分钟理解JS的节流、防抖及使用场景](https://juejin.im/post/5b8de829f265da43623c4261) 114 | ### [一行代码生成登录表单](https://docs.authing.cn/#/quick_start/login-form) 115 | ### [编写更优雅的 JavaScript 代码](https://juejin.im/post/5b8fd36fe51d450e6475a92d) 116 | ## [使用 webpack 进行 web 性能优化(一):减小前端资源大小](https://juejin.im/post/5b976f4b5188255c865e0240) 117 | ### [“木偶”浏览器](https://juejin.im/post/5b9648e7e51d450e6321e3c5) 118 | ### [深入 Promise](https://juejin.im/post/5b95d196e51d450e41151e61) 119 | ### [十五分钟--分页逻辑--包学包会](https://juejin.im/post/5ba49868e51d450e664b4407) 120 | -------------------------------------------------------------------------------- /面试4.MD: -------------------------------------------------------------------------------- 1 | # [冴羽写博客的地方](https://github.com/mqyqingfeng/Blog) 2 | ### [一道关于this和原型链的JS题目](https://github.com/RicardoCao-Biker/RICO-BLOG/issues/16) 3 | ## [腾讯前端面试篇(一)](https://juejin.im/post/5c19c1b6e51d451d1e06c163) 4 | ### [JS 总结之对象](https://juejin.im/post/5c19b3f7f265da61620d5631) 5 | ### [2018年前端面试总结](https://juejin.im/post/5bee888fe51d4557fe34e356) 6 | ### [从URL输入到页面展现到底发生什么?](https://juejin.im/post/5bf3ad55f265da61682afc9b) 7 | ## [五分钟学会一个高难度算法:希尔排序](https://juejin.im/post/5bf9f2285188256b0f5832a0) 8 | ### [全方位彻底读懂<你不知道的JavaScript(上)>--一篇六万多字的读书笔记](https://juejin.im/post/5bfaa2e26fb9a04a0440b0e4) 9 | # Fundebug[JavaScript的值传递和引用传递](https://juejin.im/post/5beb934df265da61797460fd) 10 | ### [干货!撸一个webpack插件(内含tapable详解+webpack流程)](https://juejin.im/post/5beb8875e51d455e5c4dd83f) 11 | ### [Vue.js 父子组件通信的十种方式](https://juejin.im/post/5bd18c72e51d455e3f6e4334) 12 | ## [用100行代码提升10倍的性能](https://juejin.im/post/5bec223f5188250c102116b5) 13 | ### [关于 ES6 中 Promise 的面试题](https://juejin.im/post/5bd697cfe51d454c791cd1d5) 14 | ## [原生JavaScript之完美运动框架](https://juejin.im/post/5bd45cc3e51d4535115c7e41) 15 | # [https://www.pandashen.com/archives/](https://www.pandashen.com/archives/) 16 | # [手写promise](https://juejin.im/post/5bc7d9bef265da0af879a293) 17 | ## [深入理解BFC](https://juejin.im/post/5bc33d0d6fb9a05d1658afc7) 18 | ### [143行js顶部进度条最小插件-nanobar.js源码解析](https://juejin.im/post/5bcdb745e51d4536c65d1f27) 19 | ### [前端开发面试题汇总 | 掘金技术征文](https://juejin.im/post/5ba6e77e6fb9a05d0b14359b) 20 | ## [【译】 (a ==1 && a== 2 && a==3) 有可能是 true 吗?](http://elevenbeans.github.io/2018/01/23/nothing-is-impossible-for-javascript/) 21 | ### [让强大的console家族助你一臂之力](https://juejin.im/post/5b586ec06fb9a04fc436c9b3) 22 | ## [封装一个简易的上传附件方法](https://juejin.im/post/5bbc5619e51d450e8377b230) 23 | ## [百度阿里网易大疆等大小厂前端校招面筋 | 掘金技术征文](https://juejin.im/post/5bb470295188255c5e66f88f) 24 | ### [有一种优化,叫Preload](https://mp.weixin.qq.com/s?__biz=MzUxMTcwOTM4Mg==&mid=2247484163&idx=1&sn=16b9c907971683dd61cee251adcde79b&chksm=f96edaaace1953bcaf65a1adcf30b6d3dd66cf7b648ae59c4bf807d3f8bf460d5cd638e54ca1&token=946370022&lang=zh_CN#rd) 25 | ## [JS 原型链](https://github.com/libin1991/libin_Blog/issues/657) 26 | #### [用js将 386485473.88 转换为 386,485,473.88(千位分割符) ](https://www.seoxiehui.cn/article-71899-1.html) 27 | ### [基于IntersectionObserver的图片懒加载实现](https://juejin.im/post/5bbc60e8f265da0af609cd04) 28 | ### [浏览器输入 URL 后发生了什么?](https://zhuanlan.zhihu.com/p/43369093) 29 | ### [node.js中exports与module.exports的区别分析](https://juejin.im/post/5bc82e485188255c42585c02) 30 | ### [~,&,|,^等位运算符在JavaScript中的一些应用](https://juejin.im/post/5bc42c5c6fb9a05d3a4b5f59) 31 | ### [图像主题色的提取](https://juejin.im/post/5bc84159e51d450ea1329d6c) 32 | ## [看看这些被同事喷的JS代码风格你写过多少](https://juejin.im/post/5becf928f265da61380ec986) 33 | ### [[译] 你不知道的 console 命令](https://juejin.im/post/5bf64218e51d45194266acb7) 34 | ``` 35 | var separator=(num)=>{ 36 | if(!num){ 37 | return '0.00'; 38 | }; 39 | let str = parseFloat(num).toFixed(2); 40 | return str && str 41 | .toString() 42 | .replace(/(\d)(?=(\d{3})+\.)/g, function($0, $1) { 43 | return $1 + ","; 44 | }); 45 | } 46 | 47 | separator(386485473.88) //"386,485,473.88" 48 | ``` 49 | ### [Vue页面跳转动画效果实现](https://juejin.im/post/5ba358a56fb9a05d2068401d) 50 | ### [[前端开发]--分享个人习惯的命名方式](https://juejin.im/post/5b6ad6b0e51d4519171766e2) 51 | ### [求职季,前端面试送给你|掘金技术征文](https://juejin.im/post/5ba4584df265da0ab719a93d) 52 | ### [通过一个案例理解 JWT](https://juejin.im/post/5ba37c50e51d450e664b3fc3) 53 | ### [像滤镜一样改变字体颜色](https://juejin.im/post/5ba27b25e51d450e4b1bf4ba) 54 | ### [深拷贝的终极探索(90%的人都不知道)](https://juejin.im/post/5bc1ae9be51d450e8b140b0c) 55 | ### [Source Map的原理探究](https://blog.fundebug.com/2018/10/12/understanding_frontend_source_map/) 56 | ### [Web 动效四大才子简述](https://juejin.im/post/5bc58bd9e51d450e721108a4) 57 | ### [H5 和小程序拍照图片旋转、压缩和上传](https://juejin.im/post/5baf4a04e51d450ea52fd9a4) 58 | # [年终回顾,为你汇总一份「前端技术清单」](https://juejin.im/post/5bdfb387e51d452c8e0aa902) 59 | ## [你应该知道的 JavaScript Array.map() 的 5 种用途](https://www.css88.com/archives/10024) 60 | # [问题分享:Js引用类型赋值](https://juejin.im/post/5becd0e9e51d4543cd17310c) 61 | ### [自己动手实现一个前端路由](https://juejin.im/post/5bf16b506fb9a049b22178b4) 62 | # [某大厂面试题与解析(欢迎纠错,优化)](https://juejin.im/post/5be2fcd7f265da616d53aad0) 63 | # [面试官问:能否模拟实现bind](https://juejin.im/post/5bec4183f265da616b1044d7) 64 | # [前端实现文件下载和拖拽上传](https://juejin.im/post/5bf543d851882518eb1f5cc4) 65 | ## [刷《一年半经验,百度、有赞、阿里面试总结》·手记](https://juejin.im/post/5bfff5086fb9a049c84f2d24#heading-6) 66 | ## [支付宝6轮面试经验](https://juejin.im/post/5c0a90b1518825666808d1c5) 67 | ### [[]==''返回?为什么?运算符==进行了什么操作?](https://juejin.im/post/5c0b54a6518825061a2bd33b) 68 | -------------------------------------------------------------------------------- /面试5.MD: -------------------------------------------------------------------------------- 1 | ### [【进阶4-3期】面试题之如何实现一个深拷贝](https://juejin.im/post/5c45112e6fb9a04a027aa8fe) 2 | ### [每个 JavaScript 开发者都该了解的 ES2018 新特性](https://juejin.im/post/5c45dffef265da61163a13e2#heading-10) 3 | ``` 4 | 5 | // 使用let 声明变量 6 | function func() { 7 | var arr = []; 8 | for(let i = 0;i<3;i++){ 9 | arr.push(()=> { 10 | console.log(i); 11 | }) 12 | } 13 | return arr 14 | } 15 | var result = func(); 16 | result.forEach((item)=> { 17 | item(); 18 | }) 19 | 20 | 21 | // 使用闭包 22 | function func() { 23 | var arr = []; 24 | for(var i = 0;i<3;i++){ 25 | (function(i){ 26 | arr.push(()=> { 27 | console.log(i); 28 | }) 29 | })(i) 30 | } 31 | return arr 32 | } 33 | var result = func(); 34 | result.forEach((item)=> { 35 | item(); 36 | }) 37 | 38 | 39 | function func() { 40 | var arr = []; 41 | for(var i = 0;i<3;i++){ 42 | arr.push(function(i) { 43 | console.log(i); 44 | }.bind(this,i)) 45 | } 46 | return arr 47 | } 48 | var result = func(); 49 | result.forEach((item)=> { 50 | item(); 51 | }) 52 | 53 | 54 | function func() { 55 | var arr = []; 56 | for(var i = 0;i<3;i++){ 57 | arr.push(console.log.bind(null, i)) 58 | } 59 | return arr 60 | } 61 | var result = func(); 62 | result.forEach((item)=> { 63 | item(); 64 | }) 65 | 66 | ``` 67 | ### [作为技术面试官,为什么把你pass了](https://juejin.im/post/5c1e7a086fb9a049b82a7310) 68 | ### [如何在 ES5 环境下实现一个const ?](https://juejin.im/post/5c20dd39e51d457b8c1f3f30) 69 | ### [详细解析赋值、浅拷贝和深拷贝的区别](https://juejin.im/post/5c20509bf265da611b585bec#heading-6) 70 | ### [JS 总结之原型继承的几种方式](https://juejin.im/post/5c1f9fc0f265da6125781973) 71 | ### [浅谈JavaScript的类型转换](https://juejin.im/post/5c203d536fb9a049ef26960f) 72 | ### [腾讯前端面试篇(二)](https://juejin.im/post/5c1869ab6fb9a049f154207a) 73 | ### [让老板虎躯一震的前端技术,KPI杀手](https://juejin.im/post/5c3ff18b6fb9a04a0a5f76aa) 74 | ### [道阻且长啊TAT(前端面试总结) 附答案 - 上](https://juejin.im/post/59ddee81f265da4321530615#comment) 75 | --------------------------------------------------------------------------------