Repository: coconilu/Blog Branch: master Commit: 6d52ff9c10f4 Files: 17 Total size: 31.6 KB Directory structure: gitextract_558re6tm/ ├── .gitignore ├── README.md ├── README.old.md ├── code/ │ ├── classLike.js │ ├── event-loop.js │ ├── main.js │ ├── next-tick.js │ └── state.js ├── coolFunction/ │ ├── compose.js │ └── currying.js └── picture/ ├── JS运行原理.vsdx ├── extend验证.vsdx ├── new过程.vsdx ├── 总结.vsdx ├── 浏览器渲染进程.vsdx ├── 浏览器进程.vsdx └── 网页渲染时机.vsdx ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ node_modules .vscode dist .idea test ================================================ FILE: README.md ================================================ # 前端思维宫殿3.0 > 关于前端工程项目管理的经验分享 - [x] [代码格式的选择,ESM可以使用了么?](https://www.yuque.com/bayes-otxkg/ua5839/ha7r1r) - [ ] [如何管理项目中的CSS?](https://github.com/coconilu/Blog/issues/174) - [ ] [如何管理项目中的TypeScript?](https://github.com/coconilu/Blog/issues/175) ## 归档 [前端思维宫殿1.0](https://github.com/coconilu/Blog/issues/171) [前端思维宫殿2.0](https://github.com/coconilu/Blog/issues/173) # 勘误与改进 如果博客对您有所帮助或启发,期待您的star,同时对作者也是一种鼓励。 # License 所有文章采用[知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议](http://creativecommons.org/licenses/by-nc-sa/3.0/cn/)进行许可。 ================================================ FILE: README.old.md ================================================ # Bayes 的博客 每个人都应该有自己的思维宫殿,它有利于我们面对复杂系统的时候,可以游刃有余地去理解它们。 这些年来我收集了很多文章、博客,但我也是最近才想要仔细去把它们整理并串联起来,希望能组成一个有层次感的知识宫殿。 ## :books: 思维宫殿 ### [从“浏览器输入URL后”说起](https://github.com/coconilu/Blog/issues/120) ### 关于网络和安全 1. - [x] [网络模型](https://github.com/coconilu/Blog/issues/97) 2. - [ ] [数据链路层](https://github.com/coconilu/Blog/issues/140) 3. - [ ] [IP 协议](https://github.com/coconilu/Blog/issues/139) 4. - [ ] [TCP 协议](https://github.com/coconilu/Blog/issues/138) 5. - [x] [HTTP 协议](https://github.com/coconilu/Blog/issues/135) 6. - [x] [HTTPS 协议](https://github.com/coconilu/Blog/issues/137) 7. - [x] [HTTP2 协议](https://github.com/coconilu/Blog/issues/134) 6. - [ ] [网络模型中的其它协议(持续更新)](https://github.com/coconilu/Blog/issues/141) 8. - [x] [认证用户身份](https://github.com/coconilu/Blog/issues/136) 9. - [x] [Web 安全专题](https://github.com/coconilu/Blog/issues/38) 10. - [x] [OAUTH 2.0](https://github.com/coconilu/Blog/issues/58) 11. - [x] [JSON Web Token](https://github.com/coconilu/Blog/issues/110) ### 关于专业基本功 #### 计算机组成 #### 操作系统 #### 数据库 #### 数据结构与算法 ##### 1. JavaScript实现的排序算法 1. - [x] [校验排序算法的算法](https://gist.github.com/coconilu/f4d7c22f8056eecf7b4376f688389073) 2. - [x] [冒泡排序](https://gist.github.com/coconilu/e2bb8340729dfc3fa89a2e00fd76ffb9) 3. - [x] [插入排序](https://gist.github.com/coconilu/328a84764b15ec359d143fbd1a614a51) 4. - [x] [选择排序](https://gist.github.com/coconilu/cdd13940a6bd8f28c4bd6ab0d226b8dd) 5. - [x] [希尔排序](https://gist.github.com/coconilu/8cc56b37479070c6b6edacfd2eea995a) 6. - [x] [递归排序](https://gist.github.com/coconilu/0bc68ea5099292bbc1aca7d48e0d5e40) 7. - [x] [快速排序](https://gist.github.com/coconilu/8e814ac4238ac2fe3a6bf5113a685237) ##### 2. 其他有意思的算法 1. - [ ] 数组洗牌效果 ### 关于“浏览器运行原理”的系列博客 1. [浏览器运行原理概述](https://github.com/coconilu/Blog/issues/47) 2. [资源加载和页面渲染](https://github.com/coconilu/Blog/issues/48) 3. [浏览器缓存机制](https://github.com/coconilu/Blog/issues/113) 4. [同源策略与跨域请求](https://github.com/coconilu/Blog/issues/59) 5. [JavaScript 引擎](https://github.com/coconilu/Blog/issues/45) - [V8 引擎](https://github.com/coconilu/Blog/issues/49) 6. [异步编程与事件循环](https://github.com/coconilu/Blog/issues/7) ### 关于 “进阶的JavaScript”系列博客 - - [x] [类相关](https://github.com/coconilu/Blog/issues/9) - - [x] [JS 常用对象和全局对象的常用方法](https://github.com/coconilu/Blog/issues/70) - - [x] [JS 常用操作符](https://github.com/coconilu/Blog/issues/72) - - [x] [JS 常用数据结构](https://github.com/coconilu/Blog/issues/71) - - [x] [JS 可迭代对象、迭代器、生成器](https://github.com/coconilu/Blog/issues/73) - - [x] [防抖和节流](https://github.com/coconilu/Blog/issues/64) - - [x] [ES6 要点](https://github.com/coconilu/Blog/issues/60) - - [x] [JS 函数式编程](https://github.com/coconilu/Blog/issues/62) - - [x] [JS 元编程](https://github.com/coconilu/Blog/issues/68) - - [x] [JS 设计模式](https://github.com/coconilu/Blog/issues/69) - - [x] [用代码讲述Promise原理——每个人都应该有自己的Promise](https://github.com/coconilu/myPromise) - - [X] [深究Function.prototype.bind](https://github.com/coconilu/Blog/issues/12) - - [x] [JS 编程技巧(持续更新)](https://github.com/coconilu/Blog/issues/46) ### 关于 “前沿的JavaScript”系列博客 - - [x] [虚拟DOM与diff算法](https://github.com/coconilu/Blog/issues/65) - - [x] [Snabbdom 官方文档翻译](https://github.com/coconilu/Blog/issues/152) - - [ ] [抽象语法树](https://github.com/coconilu/Blog/issues/145) - - [ ] [JS 切面编程](https://github.com/coconilu/Blog/issues/148) ### 关于 “Web编程模型” 的系列博客 - [x] [Web编程模型概述](https://github.com/coconilu/Blog/issues/23) #### 1. HTML模块 1. - [x] [HTML概述](https://github.com/coconilu/Blog/issues/34) 2. - [x] [HTML标签及属性](https://github.com/coconilu/Blog/issues/20) #### 2. CSS 模块 1. - [x] [CSS 概述](https://github.com/coconilu/Blog/issues/28) 2. - [x] [CSS 基础](https://github.com/coconilu/Blog/issues/26) 3. - [x] [CSS 收集解析模型](https://github.com/coconilu/Blog/issues/18) 4. - [x] [CSS 盒模型](https://github.com/coconilu/Blog/issues/25) 5. - [x] [CSS 布局相关](https://github.com/coconilu/Blog/issues/17) 6. - [x] [CSS 行内元素排版原理](https://github.com/coconilu/Blog/issues/61) 6. - [x] [CSS 样式检索](https://github.com/coconilu/Blog/issues/27) 7. - [x] [CSS 进阶内容(持续更新)](https://github.com/coconilu/Blog/issues/29) 7. - [x] [CSS 工程化](https://github.com/coconilu/Blog/issues/144) #### 3. WebAPI 模块 1. - [X] [WebAPI 概述](https://github.com/coconilu/Blog/issues/35) 2. - [X] [DOM 模型](https://github.com/coconilu/Blog/issues/21) 3. - [x] [DOM的事件模型](https://github.com/coconilu/Blog/issues/22) 4. - [x] [Web API参考](https://github.com/coconilu/Blog/issues/24) 5. - [x] [WebAPI 字节处理能力](https://github.com/coconilu/Blog/issues/154) #### 4. 综合模块 1. - [X] [Web交互的关键:提交表单](https://github.com/coconilu/Blog/issues/30) 2. - [x] [上传文件](https://github.com/coconilu/Blog/issues/109) 2. - [x] [position: sticky的polyfill](https://github.com/coconilu/Blog/issues/31) 3. - [x] [实现缓慢回到顶部](https://github.com/coconilu/Blog/issues/44) 4. - [x] [网页关键数据与坐标](https://github.com/coconilu/Blog/issues/63) 5. - [x] [响应式布局](https://github.com/coconilu/Blog/issues/74) 6. - [x] [FLIP 动画](https://github.com/coconilu/Blog/issues/105) 7. - [x] [动画队列](https://github.com/coconilu/Blog/issues/106) 8. - [x] [页面生命周期](https://github.com/coconilu/Blog/issues/121) 9. - [x] [前端开发需要注意的一些细节(持续更新)](https://github.com/coconilu/Blog/issues/98) #### 5. 优化指南 1. 网络方面 2. 浏览器方面 3. 服务器方面 ### 前端业务场景 1. - [x] [懒加载图片](https://github.com/coconilu/my-lazyload-picture) 2. - [x] [预加载图片](https://github.com/coconilu/Blog/issues/85) 3. - [x] [弹幕效果](https://github.com/coconilu/Blog/issues/86) 4. - [x] [翻牌效果](https://github.com/coconilu/Blog/issues/107) 5. - [x] [拖拽专题](https://github.com/coconilu/Blog/issues/108) 6. - [x] [雪碧图](https://github.com/coconilu/Blog/issues/114) 7. - [x] [Canvas 经典案例(持续更新)](https://github.com/coconilu/Blog/issues/37) 8. 借助history api优化浏览器前进后退 9. - [ ] [JS生成图片方案](https://github.com/coconilu/Blog/issues/146) ### 关于VueJS 1. - [x] [VueJS 运行过程](https://github.com/coconilu/Blog/issues/19) 2. - [x] [VueJS 响应式原理及简单实现](https://github.com/coconilu/Blog/issues/75) 3. - [x] [VueJS 的编译阶段到挂载节点](https://github.com/coconilu/Blog/issues/92) 4. - [x] [VueJS 的模板引擎](https://github.com/coconilu/Blog/issues/91) 5. - [x] [VueJS 的VNode](https://github.com/coconilu/Blog/issues/94) 6. - [x] [VueJs 的组件化](https://github.com/coconilu/Blog/issues/93) 6. - [x] [VueJS 的调试](https://github.com/coconilu/Blog/issues/96) 7. - [x] [VueJS API](https://github.com/coconilu/Blog/issues/67) 8. - [x] [VueJS 全家桶](https://github.com/coconilu/Blog/issues/111) ### 关于React 1. - [x] [React 运行过程](https://github.com/coconilu/Blog/issues/99) 2. - [x] [React 进阶](https://github.com/coconilu/Blog/issues/100) 3. - [ ] [React 原理部分](https://github.com/coconilu/Blog/issues/112) ### 关于NodeJS 1. - [x] [NodeJS 运行原理](https://github.com/coconilu/Blog/issues/43) 2. - [x] [NodeJS 编程模型](https://github.com/coconilu/Blog/issues/41) 3. - [x] [基础模块](https://github.com/coconilu/Blog/issues/42) 4. - [x] [网络模块](https://github.com/coconilu/Blog/issues/50) 5. - [x] [系统模块](https://github.com/coconilu/Blog/issues/51) 6. - [x] [工具模块](https://github.com/coconilu/Blog/issues/53) 7. - [x] [Express源码解析](https://github.com/coconilu/Blog/issues/82) 8. - [x] [Koa源码解析](https://github.com/coconilu/Blog/issues/81) 9. - [x] [Express和Koa的对比](https://github.com/coconilu/Blog/issues/83) 10. - [ ] [NodeJS 集群](https://github.com/coconilu/Blog/issues/117) 11. - [ ] [Node 与视频流媒体](https://github.com/coconilu/Blog/issues/149) 12. - [ ] [pm2 使用手册](https://github.com/coconilu/Blog/issues/151) ### 关于包管理器 1. - [x] [NPM 指令大全](https://github.com/coconilu/Blog/issues/78) 1. - [x] [配置 NPM](https://github.com/coconilu/Blog/issues/143) 2. - [x] [NPM 上传自己的项目](https://github.com/coconilu/Blog/issues/79) 3. - [x] [NPM与工作流](https://github.com/coconilu/Blog/issues/77) 4. - [x] [NPM技巧收集(持续更新)](https://github.com/coconilu/Blog/issues/88) 5. - [x] [Yarn 使用手册](https://github.com/coconilu/Blog/issues/142) ### 关于GraphQL - [x] [GraphQL 速记手册](https://github.com/coconilu/Blog/issues/104) ### 关于JS第三方工具库 - [x] [axios 核心源码解读](https://github.com/coconilu/Blog/issues/116) - [ ] lodash ## :video_game: 工具 ### 1. 设计工具 #### Ant Design #### Fusion Design #### NG-ZORRO ### 2. 版本管理工具 #### Git - [x] [git模型](https://github.com/coconilu/Blog/issues/54) - [x] [git常用API](https://github.com/coconilu/Blog/issues/55) - [ ] [git 场景](https://github.com/coconilu/Blog/issues/157) - [x] [GitHub Flow](https://github.com/coconilu/Blog/issues/56) ### 3. 构建工具 #### Webpack - [x] [WebPack模型](https://github.com/coconilu/Blog/issues/87) - [x] [Webpack 进阶功能](https://github.com/coconilu/Blog/issues/123) - [x] [webpack-dev-server 原理探讨](https://github.com/coconilu/Blog/issues/115) - [x] [Webpack相关课题(持续更新)](https://github.com/coconilu/Blog/issues/122) - [x] [常用Loaders和Plugins(持续更新)](https://github.com/coconilu/Blog/issues/89) - [x] [Webpack 与内存](https://github.com/coconilu/Blog/issues/147) - [ ] webpack 与定制化编译过程 #### Babel - [x] [Babel 运行过程](https://github.com/coconilu/Blog/issues/102) - [x] [Babel API](https://github.com/coconilu/Blog/issues/156) #### Travis CI - [ ] [Travis CI 使用手册](https://github.com/coconilu/Blog/issues/118) #### 其它 - [x] [source-map实践](https://github.com/coconilu/Blog/issues/160) ### 4. 开发测试工具 #### VScode - [x] [vscode 设置默认终端为bash](https://github.com/coconilu/Blog/issues/80) - [x] [vscode 开发插件](https://github.com/coconilu/Blog/issues/90) #### Jest - [x] [Jest 速记手册](https://github.com/coconilu/Blog/issues/103) #### TypeScript - [x] [TypeScript 速记手册](https://github.com/coconilu/Blog/issues/101) #### Google开发者工具 - [x] [Google 开发者工具使用指南](https://github.com/coconilu/Blog/issues/119) - [x] [Devtools 设备模式](https://github.com/coconilu/Blog/issues/124) - [x] [Devtools 元素模板](https://github.com/coconilu/Blog/issues/125) - [x] [Devtools 控制台面板](https://github.com/coconilu/Blog/issues/126) - [x] [Devtools 源代码面板](https://github.com/coconilu/Blog/issues/127) - [x] [Devtools 网络面板](https://github.com/coconilu/Blog/issues/128) - [x] [Devtools 性能面板](https://github.com/coconilu/Blog/issues/129) - [ ] [Devtools 内存面板](https://github.com/coconilu/Blog/issues/130) - [ ] [Devtools 应用面板](https://github.com/coconilu/Blog/issues/131) - [ ] [Devtools 安全面板](https://github.com/coconilu/Blog/issues/132) #### 抓包工具 - [ ] [wireshark 使用手册](https://github.com/coconilu/Blog/issues/133) - [ ] [Fiddler 使用手册](https://github.com/coconilu/Blog/issues/150) #### 代理工具 - [ ] SwitchyOmega 使用手册 ### 5. 服务器相关 #### Nginx - [x] [前端与Nginx](https://github.com/coconilu/Blog/issues/76) - [x] [Protocol Buffers原理解析](https://github.com/coconilu/Blog/issues/159) - [ ] [Nginx 配置小结](https://github.com/coconilu/Blog/issues/153) ## :trophy: 开源贡献 ### 社区活动 #### 翻译活动 1. [参与MDN翻译](https://developer.mozilla.org/en-US/profiles/sunline.bucket) 2. [掘金翻译计划](https://github.com/coconilu/Blog/issues/36) #### [NPM 开源共享库](https://www.npmjs.com/~coconilu) 1. [@coconilu/mypromise](https://www.npmjs.com/package/@coconilu/mypromise) 2. [my-lazyload-picture](https://www.npmjs.com/package/my-lazyload-picture) 3. [my-flip-animation](https://www.npmjs.com/package/my-flip-animation) 4. [sticky-polyfill](https://www.npmjs.com/package/sticky-polyfill) ### 开源项目 1. [管理GitHub的stars](https://github.com/coconilu/iGitStar) # 勘误与改进 如果博客对您有所帮助或启发,期待您的star,同时对作者也是一种鼓励。 # License 所有文章采用[知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议](http://creativecommons.org/licenses/by-nc-sa/3.0/cn/)进行许可。 ================================================ FILE: code/classLike.js ================================================ let person = { name: 'Bar' } let handler = { get: function (target, name) { if (name === 'getName') { return () => target['name'] } } } let p = new Proxy(person, handler) console.log(p.getName()) // 验证extend的原理 class Father { constructor() { this.fatherSelf = function () { } } fatherPrototype() { } } class Child extends Father { constructor() { super() this.childSelf = function () { } } childPrototype() { } } var c = new Child() ================================================ FILE: code/event-loop.js ================================================ // 验证事件循环机制 // setTimeout(() => { // console.log('timeout 1') // Promise.resolve().then(() => { // console.log('Promise 3') // }) // setTimeout(() => { // console.log('timeout 3') // }) // setImmediate(() => { // console.log('immediate 3') // }) // }) // setImmediate(() => { // console.log('immediate 1') // }) // Promise.resolve().then(() => { // console.log('Promise 1') // Promise.resolve().then(() => { // console.log('Promise 2') // }) // setTimeout(() => { // console.log('timeout 2') // }) // setTimeout(() => { // console.log('timeout 4') // }) // setTimeout(() => { // console.log('timeout 5') // }) // setImmediate(() => { // console.log('immediate 2') // setTimeout(() => { // console.log('timeout 6') // }) // }) // }) // 更新UI机制 // var testTitle = document.getElementById('testTitle') // setTimeout(()=>{ // testTitle.textContent = 'wangyaohui' // var t = +new Date(); // while(+new Date() - t < 3000) ; // }) // 验证任务队列的执行逻辑 // process.nextTick(()=>{ // console.log('process 1') // }) // setTimeout(()=>{ // console.log('setTimeout 1') // process.nextTick(()=>{ // console.log('process 2') // setTimeout(()=>{ // console.log('setTimeout 4') // }) // }) // }) // setTimeout(()=>{ // console.log('setTimeout 2') // process.nextTick(()=>{ // console.log('process 4') // setTimeout(()=>{ // console.log('setTimeout 5') // }) // }) // }) // setTimeout(()=>{ // console.log('setTimeout 3') // }) // process.nextTick(()=>{ // console.log('process 3') // }) // 验证任务阻塞setTimeout执行的情况 // 结果相差 // var d1, d2, d3, d4 // console.log(d1 = new Date()) // setTimeout(() => { // console.log(d2 = new Date()) // var d; // setTimeout(() => { // console.log(d3 = new Date()) // }, 1000) // d = +new Date(); // while (+new Date() - d < 3000);// 延迟3秒 // console.log(d4 = new Date()) // }, 1000) // 验证setInterval的覆盖情况,nodejs // console.log(new Date()) // setTimeout(() => { // var d, num = 0; // setInterval(() => { // var dd; // console.log(new Date()) // console.log(num) // ++num // dd = +new Date(); // while (+new Date() - dd < 2000);// 延迟3秒 // }, 1000) // d = +new Date(); // while (+new Date() - d < 3000);// 延迟3秒 // }) // 验证setInterval的覆盖情况,浏览器环境 (function inter(num) { setInterval(() => { var t = +new Date(); ++num; console.log(num, new Date()); while (+new Date() - t < 1000); // 阻塞两秒 }, 2000) })(0) // 异步编程,优先级测试 // setImmediate(function(){ // console.log(1); // },0); // setTimeout(function(){ // console.log(2); // },0); // new Promise(function(resolve){ // console.log(3); // resolve(); // console.log(4); // }).then(function(){ // console.log(5); // }); // console.log(6); // process.nextTick(function(){ // console.log(7); // }); // console.log(8); // 疑惑中 // console.log('script start'); // setTimeout(function() { // console.log('setTimeout'); // }, 0); // Promise.resolve().then(function(resolve) { // console.log('promise1'); // setTimeout(function() { // console.log('setTimeout in microtask'); // }, 0); // }).then(function() { // console.log('promise2'); // }); // console.log('script end'); // 疑惑中 // setTimeout(() => { // console.log('timeout'); // }); // setImmediate(() => { // console.log('immediate'); // }); // const fs = require('fs'); // fs.readFile(__filename, () => { // setTimeout(() => { // console.log('timeout'); // }); // setImmediate(() => { // console.log('immediate'); // }); // }); ================================================ FILE: code/main.js ================================================ // hosting,提升 // console.log(a) // var a = 1 // function a () {} // console.log(a) // 类数组 // var ao = {1:'a', 2:'b', length:3} // var ar = Array.prototype.slice.apply(ao) // var arr = Array.from(ao) // console.log(ar) // console.log(arr) // 验证提升 // (function (a, b) { // console.log(a, b) // var a; // function b() {}; // a = 1; // console.log(a, b) // })(3, 4) // (() => { // // 验证任务队列有没有插队的行为 // // 先让主线程生成两个setTimeout和两个process.nextTick // setTimeout(() => { // console.log('timeout 1') // process.nextTick(() => { // console.log('process 3') // }) // setTimeout(() => { // console.log('timeout 3') // }) // }); // setTimeout(() => { // console.log('timeout 2') // }); // process.nextTick(() => { // console.log('process 1') // process.nextTick(() => { // console.log('process 4') // }) // setTimeout(() => { // console.log('timeout 4') // }) // }); // process.nextTick(() => { // console.log('process 2') // }); // })() // 验证箭头函数的this指向,在浏览器环境下测试通过 // var x = 'windows'; // function fun1() { // var fun2 = () => { // console.log(this.x) // } // fun2() // } // fun1(); // var obj = { // x: 'obj', // showX: fun1 // } // obj.showX() // function constructorDemo(x){ // this.x = x // this.showX = () => { // console.log(this.x) // } // } // new constructorDemo('new').showX() // 验证bind // function list() { // console.log(this) // return Array.prototype.slice.call(arguments); // } // var f1 = list.bind(undefined,37); // var f2 = f1.bind(undefined, 1, 2, 3); // console.log(f1(4)) // console.log(f2(4,5)) // 验证暂时性死区 // var x = 0; // function f(x = 2) { // console.log(x) // console.log(y) // let y = 1; // } // f() ================================================ FILE: code/next-tick.js ================================================ /* @flow */ /* globals MessageChannel */ import { noop } from 'shared/util' import { handleError } from './error' import { isIOS, isNative } from './env' const callbacks = [] let pending = false function flushCallbacks () { pending = false const copies = callbacks.slice(0) callbacks.length = 0 for (let i = 0; i < copies.length; i++) { copies[i]() } } // Here we have async deferring wrappers using both microtasks and (macro) tasks. // In < 2.4 we used microtasks everywhere, but there are some scenarios where // microtasks have too high a priority and fire in between supposedly // sequential events (e.g. #4521, #6690) or even between bubbling of the same // event (#6566). However, using (macro) tasks everywhere also has subtle problems // when state is changed right before repaint (e.g. #6813, out-in transitions). // Here we use microtask by default, but expose a way to force (macro) task when // needed (e.g. in event handlers attached by v-on). let microTimerFunc let macroTimerFunc let useMacroTask = false // Determine (macro) task defer implementation. // Technically setImmediate should be the ideal choice, but it's only available // in IE. The only polyfill that consistently queues the callback after all DOM // events triggered in the same loop is by using MessageChannel. /* istanbul ignore if */ if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) { macroTimerFunc = () => { setImmediate(flushCallbacks) } } else if (typeof MessageChannel !== 'undefined' && ( isNative(MessageChannel) || // PhantomJS MessageChannel.toString() === '[object MessageChannelConstructor]' )) { const channel = new MessageChannel() const port = channel.port2 channel.port1.onmessage = flushCallbacks macroTimerFunc = () => { port.postMessage(1) } } else { /* istanbul ignore next */ macroTimerFunc = () => { setTimeout(flushCallbacks, 0) } } // Determine microtask defer implementation. /* istanbul ignore next, $flow-disable-line */ if (typeof Promise !== 'undefined' && isNative(Promise)) { const p = Promise.resolve() microTimerFunc = () => { p.then(flushCallbacks) // in problematic UIWebViews, Promise.then doesn't completely break, but // it can get stuck in a weird state where callbacks are pushed into the // microtask queue but the queue isn't being flushed, until the browser // needs to do some other work, e.g. handle a timer. Therefore we can // "force" the microtask queue to be flushed by adding an empty timer. if (isIOS) setTimeout(noop) } } else { // fallback to macro microTimerFunc = macroTimerFunc } /** * Wrap a function so that if any code inside triggers state change, * the changes are queued using a (macro) task instead of a microtask. */ export function withMacroTask (fn: Function): Function { return fn._withTask || (fn._withTask = function () { useMacroTask = true const res = fn.apply(null, arguments) useMacroTask = false return res }) } export function nextTick (cb?: Function, ctx?: Object) { let _resolve callbacks.push(() => { if (cb) { try { cb.call(ctx) } catch (e) { handleError(e, ctx, 'nextTick') } } else if (_resolve) { _resolve(ctx) } }) if (!pending) { pending = true if (useMacroTask) { macroTimerFunc() } else { microTimerFunc() } } // $flow-disable-line if (!cb && typeof Promise !== 'undefined') { return new Promise(resolve => { _resolve = resolve }) } } ================================================ FILE: code/state.js ================================================ /* @flow */ import config from '../config' import Watcher from '../observer/watcher' import { pushTarget, popTarget } from '../observer/dep' import { isUpdatingChildComponent } from './lifecycle' import { set, del, observe, defineReactive, toggleObserving } from '../observer/index' import { warn, bind, noop, hasOwn, hyphenate, isReserved, handleError, nativeWatch, validateProp, isPlainObject, isServerRendering, isReservedAttribute } from '../util/index' const sharedPropertyDefinition = { enumerable: true, configurable: true, get: noop, set: noop } export function proxy (target: Object, sourceKey: string, key: string) { sharedPropertyDefinition.get = function proxyGetter () { return this[sourceKey][key] } sharedPropertyDefinition.set = function proxySetter (val) { this[sourceKey][key] = val } Object.defineProperty(target, key, sharedPropertyDefinition) } export function initState (vm: Component) { vm._watchers = [] const opts = vm.$options if (opts.props) initProps(vm, opts.props) if (opts.methods) initMethods(vm, opts.methods) if (opts.data) { initData(vm) } else { observe(vm._data = {}, true /* asRootData */) } if (opts.computed) initComputed(vm, opts.computed) if (opts.watch && opts.watch !== nativeWatch) { initWatch(vm, opts.watch) } } function initProps (vm: Component, propsOptions: Object) { const propsData = vm.$options.propsData || {} const props = vm._props = {} // cache prop keys so that future props updates can iterate using Array // instead of dynamic object key enumeration. const keys = vm.$options._propKeys = [] const isRoot = !vm.$parent // root instance props should be converted if (!isRoot) { toggleObserving(false) } for (const key in propsOptions) { keys.push(key) const value = validateProp(key, propsOptions, propsData, vm) /* istanbul ignore else */ if (process.env.NODE_ENV !== 'production') { const hyphenatedKey = hyphenate(key) if (isReservedAttribute(hyphenatedKey) || config.isReservedAttr(hyphenatedKey)) { warn( `"${hyphenatedKey}" is a reserved attribute and cannot be used as component prop.`, vm ) } defineReactive(props, key, value, () => { if (vm.$parent && !isUpdatingChildComponent) { warn( `Avoid mutating a prop directly since the value will be ` + `overwritten whenever the parent component re-renders. ` + `Instead, use a data or computed property based on the prop's ` + `value. Prop being mutated: "${key}"`, vm ) } }) } else { defineReactive(props, key, value) } // static props are already proxied on the component's prototype // during Vue.extend(). We only need to proxy props defined at // instantiation here. if (!(key in vm)) { proxy(vm, `_props`, key) } } toggleObserving(true) } function initData (vm: Component) { let data = vm.$options.data data = vm._data = typeof data === 'function' ? getData(data, vm) : data || {} if (!isPlainObject(data)) { data = {} process.env.NODE_ENV !== 'production' && warn( 'data functions should return an object:\n' + 'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function', vm ) } // proxy data on instance const keys = Object.keys(data) const props = vm.$options.props const methods = vm.$options.methods let i = keys.length while (i--) { const key = keys[i] if (process.env.NODE_ENV !== 'production') { if (methods && hasOwn(methods, key)) { warn( `Method "${key}" has already been defined as a data property.`, vm ) } } if (props && hasOwn(props, key)) { process.env.NODE_ENV !== 'production' && warn( `The data property "${key}" is already declared as a prop. ` + `Use prop default value instead.`, vm ) } else if (!isReserved(key)) { proxy(vm, `_data`, key) } } // observe data observe(data, true /* asRootData */) } export function getData (data: Function, vm: Component): any { // #7573 disable dep collection when invoking data getters pushTarget() try { return data.call(vm, vm) } catch (e) { handleError(e, vm, `data()`) return {} } finally { popTarget() } } const computedWatcherOptions = { computed: true } function initComputed (vm: Component, computed: Object) { // $flow-disable-line const watchers = vm._computedWatchers = Object.create(null) // computed properties are just getters during SSR const isSSR = isServerRendering() for (const key in computed) { const userDef = computed[key] const getter = typeof userDef === 'function' ? userDef : userDef.get if (process.env.NODE_ENV !== 'production' && getter == null) { warn( `Getter is missing for computed property "${key}".`, vm ) } if (!isSSR) { // create internal watcher for the computed property. watchers[key] = new Watcher( vm, getter || noop, noop, computedWatcherOptions ) } // component-defined computed properties are already defined on the // component prototype. We only need to define computed properties defined // at instantiation here. if (!(key in vm)) { defineComputed(vm, key, userDef) } else if (process.env.NODE_ENV !== 'production') { if (key in vm.$data) { warn(`The computed property "${key}" is already defined in data.`, vm) } else if (vm.$options.props && key in vm.$options.props) { warn(`The computed property "${key}" is already defined as a prop.`, vm) } } } } export function defineComputed ( target: any, key: string, userDef: Object | Function ) { const shouldCache = !isServerRendering() if (typeof userDef === 'function') { sharedPropertyDefinition.get = shouldCache ? createComputedGetter(key) : userDef sharedPropertyDefinition.set = noop } else { sharedPropertyDefinition.get = userDef.get ? shouldCache && userDef.cache !== false ? createComputedGetter(key) : userDef.get : noop sharedPropertyDefinition.set = userDef.set ? userDef.set : noop } if (process.env.NODE_ENV !== 'production' && sharedPropertyDefinition.set === noop) { sharedPropertyDefinition.set = function () { warn( `Computed property "${key}" was assigned to but it has no setter.`, this ) } } Object.defineProperty(target, key, sharedPropertyDefinition) } function createComputedGetter (key) { return function computedGetter () { const watcher = this._computedWatchers && this._computedWatchers[key] if (watcher) { watcher.depend() return watcher.evaluate() } } } function initMethods (vm: Component, methods: Object) { const props = vm.$options.props for (const key in methods) { if (process.env.NODE_ENV !== 'production') { if (methods[key] == null) { warn( `Method "${key}" has an undefined value in the component definition. ` + `Did you reference the function correctly?`, vm ) } if (props && hasOwn(props, key)) { warn( `Method "${key}" has already been defined as a prop.`, vm ) } if ((key in vm) && isReserved(key)) { warn( `Method "${key}" conflicts with an existing Vue instance method. ` + `Avoid defining component methods that start with _ or $.` ) } } vm[key] = methods[key] == null ? noop : bind(methods[key], vm) } } function initWatch (vm: Component, watch: Object) { for (const key in watch) { const handler = watch[key] if (Array.isArray(handler)) { for (let i = 0; i < handler.length; i++) { createWatcher(vm, key, handler[i]) } } else { createWatcher(vm, key, handler) } } } function createWatcher ( vm: Component, expOrFn: string | Function, handler: any, options?: Object ) { if (isPlainObject(handler)) { options = handler handler = handler.handler } if (typeof handler === 'string') { handler = vm[handler] } return vm.$watch(expOrFn, handler, options) } export function stateMixin (Vue: Class) { // flow somehow has problems with directly declared definition object // when using Object.defineProperty, so we have to procedurally build up // the object here. const dataDef = {} dataDef.get = function () { return this._data } const propsDef = {} propsDef.get = function () { return this._props } if (process.env.NODE_ENV !== 'production') { dataDef.set = function (newData: Object) { warn( 'Avoid replacing instance root $data. ' + 'Use nested data properties instead.', this ) } propsDef.set = function () { warn(`$props is readonly.`, this) } } Object.defineProperty(Vue.prototype, '$data', dataDef) Object.defineProperty(Vue.prototype, '$props', propsDef) Vue.prototype.$set = set Vue.prototype.$delete = del Vue.prototype.$watch = function ( expOrFn: string | Function, cb: any, options?: Object ): Function { const vm: Component = this if (isPlainObject(cb)) { return createWatcher(vm, expOrFn, cb, options) } options = options || {} options.user = true const watcher = new Watcher(vm, expOrFn, cb, options) if (options.immediate) { cb.call(vm, watcher.value) } return function unwatchFn () { watcher.teardown() } } } ================================================ FILE: coolFunction/compose.js ================================================ function compose() { let args = arguments let len = args.length if (len === 0) { return function () { } } return function () { let result = args[0].apply(undefined, arguments) for (let i = 1; i < len; ++i) { result = args[i].call(undefined, result) } return result } } // 测试 function what(n) { return n } function addTree(n) { return n + 3 } function multipleFour(n) { return n * 4 } function minusTwo(n) { return n / 2 } let com1 = compose(what, addTree, multipleFour) let com2 = compose(what, multipleFour, minusTwo) console.log(com1(2)) // 20 console.log(com2(2))// 4 ================================================ FILE: coolFunction/currying.js ================================================