├── article ├── 面试题目 │ ├── 算法 │ │ ├── 深度.md │ │ └── 二分查找.md │ ├── vue和react │ │ ├── vue常考面试题.md │ │ ├── 区别.md │ │ └── react常考面试题.md │ ├── JS │ │ ├── 2. js常见面试题-2.md │ │ ├── ES6 面试.md │ │ └── 1. JS面试 上.md │ ├── 浏览器和网络 │ │ ├── 浏览器常考面试题.md │ │ └── 网络常考面试题.md │ └── CSS │ │ ├── 盒模型相关面试题.md │ │ ├── 1. css常见面试题-1.md │ │ ├── 选择器相关面试题.md │ │ └── flex相关面试题.md ├── JavaScript │ ├── 事件循环.md │ ├── 专题 │ │ └── 1. JavaScript专题之深浅拷贝.md │ ├── 4. JavaScript深入之作用域链.md │ ├── 2. JavaScript深入之执行上下文栈.md │ ├── 6. JavaScript深入之执行上下文.md │ ├── 5. JavaScript深入之 this.md │ ├── 7.JavaScript深入之闭包.md │ ├── CommandJS.md │ ├── 3. JavaScript深入之变量对象.md │ ├── JavaScript之this指向.md │ ├── 10. JavaScript深入之new操作.md │ ├── 9. JavaScript深入之bind函数.md │ ├── 1. JavaScript深入之原型与原型炼.md │ └── 8. JavaScript深入之call和apply函数.md ├── Git │ ├── 0. 编写 git 文章目的.md │ ├── 1. git 命令.md │ ├── 3. 格式化commit命令.md │ └── 2. git 实践.md ├── ES6 │ ├── 0. 编写文章的目的.md │ ├── 1. 了解ES6.md │ ├── 5. 函数的扩展.md │ ├── 12. Module 语法.md │ ├── 11. 三种异步之async函数.md │ ├── 3. 变量的解构赋值.md │ ├── 2. let 和 const 命令.md │ ├── 4. 字符串的扩展.md │ ├── 10. 三种异步之Generator函数.md │ └── 8. Set 和 Map.md ├── CSS │ ├── 0. 编写 css 目的.md │ ├── 1. 盒模型.md │ ├── 3. BFC.md │ ├── 10. float.md │ ├── 8. div居中.md │ ├── 9. css3 新特性.md │ └── 6. css优先级.md └── github-pages │ ├── 4. gitalk和disgus评论.md │ ├── 1. hexo-githubPages.md │ └── 2. hexo配置项.md ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── asseats └── images │ ├── hexo │ ├── hexo.png │ ├── scroll.png │ ├── image-20220117153956920.png │ ├── image-20220117154056202.png │ ├── image-20220117154209325.png │ ├── image-20220117154336407.png │ ├── image-20220117154539668.png │ ├── image-20220117154713730.png │ ├── image-20220118144154623.png │ ├── image-20220118144310872.png │ ├── image-20220118144332639.png │ ├── image-20220118144408105.png │ ├── image-20220118151322761.png │ ├── image-20220118151413475.png │ ├── image-20220118151655445.png │ ├── image-20220119141616333.png │ ├── image-20220119141706654.png │ ├── image-20220119142042285.png │ ├── image-20220119142214404.png │ ├── image-20220119142457348.png │ ├── image-20220119142532859.png │ ├── image-20220119142808820.png │ ├── image-20220119143210533.png │ ├── image-20220119143343104.png │ ├── image-20220119144044662.png │ ├── image-20220119171611982.png │ ├── image-20220119172332985.png │ ├── image-20220119172501736.png │ ├── image-20220120083817190.png │ ├── image-20220120084754458.png │ ├── image-20220121110419337.png │ ├── image-20220121111002144.png │ ├── image-20220123104356814.png │ ├── image-20220123111354713.png │ ├── image-20220123115412196.png │ ├── image-20220123115524563.png │ ├── image-20220123115647543.png │ ├── image-20220123135642800.png │ ├── image-20220123172140939.png │ ├── image-20220123172359003.png │ ├── image-20220123173915817.png │ ├── image-20220123185803404.png │ ├── image-20220124084030346.png │ ├── image-20220124113551797.png │ ├── image-20220124115032597.png │ ├── image-20220124155840387.png │ ├── image-20220124161311114.png │ ├── image-20220124173335773.png │ ├── image-20220125104906272.png │ ├── image-20220125110924416.png │ └── image-20220125135325746.png │ ├── css │ ├── BFC │ │ ├── BFC1.png │ │ ├── BFC2.png │ │ ├── BFC3.png │ │ └── BFC4.png │ ├── flex │ │ ├── flex1.png │ │ ├── flex10.png │ │ ├── flex11.png │ │ ├── flex12.png │ │ ├── flex2.png │ │ ├── flex3.png │ │ ├── flex4.png │ │ ├── flex5.png │ │ ├── flex6.png │ │ ├── flex7.png │ │ ├── flex8.png │ │ └── flex9.png │ ├── boxModelbox-model1.png │ ├── boxModelbox-model2.png │ ├── boxModelbox-model3.png │ ├── boxModelbox-model6.png │ ├── boxModelbox-model7.png │ ├── position │ │ ├── position1.png │ │ ├── position2.png │ │ ├── position3.png │ │ ├── position4.png │ │ ├── position5.png │ │ ├── position6.png │ │ ├── position7.png │ │ ├── position8.png │ │ └── position9.gif │ ├── priority │ │ ├── priority1.png │ │ ├── priority2.png │ │ ├── priority3.png │ │ ├── priority4.png │ │ ├── priority5.png │ │ ├── priority8.png │ │ └── priority9.png │ ├── selector │ │ ├── selector1.png │ │ ├── selector2.png │ │ ├── selector3.png │ │ ├── selector4.png │ │ ├── selector5.png │ │ ├── selector6.png │ │ ├── selector7.png │ │ ├── selector8.png │ │ └── selector9.png │ ├── box-model │ │ ├── box-model1.png │ │ ├── box-model2.png │ │ ├── box-model3.png │ │ ├── box-model4.png │ │ ├── box-model5.png │ │ ├── box-model6.png │ │ └── box-model7.png │ └── div-center │ │ ├── div-center1.png │ │ ├── div-center2.png │ │ ├── div-center3.png │ │ └── div-center4.png │ ├── jsprototype8.png │ ├── html │ ├── 原型以及原型链.jpeg │ ├── 屏幕录制2022-01-15 下午2.gif │ ├── 屏幕录制2022-01-15 下午3.gif │ ├── 屏幕录制2022-01-15 下午3 (1).gif │ ├── image-20220114141352206.png │ ├── image-20220114141712822.png │ ├── image-20220114152116579.png │ ├── image-20220114152321369.png │ ├── image-20220114153129007.png │ ├── image-20220114155411899.png │ ├── image-20220114160450447.png │ ├── image-20220114161111959.png │ ├── image-20220114161329647.png │ ├── image-20220114161641065.png │ ├── image-20220114161713049.png │ ├── image-20220115082250490.png │ ├── image-20220115082334837.png │ ├── image-20220115082636821.png │ ├── image-20220115082716487.png │ ├── image-20220115082838323.png │ ├── image-20220115083005924.png │ ├── image-20220115083450019.png │ ├── image-20220115143358046.png │ ├── image-20220115144035655.png │ ├── image-20220115151143676.png │ └── htmlimage-20220106170248133.png │ ├── js │ ├── prototype1.png │ ├── prototype2.png │ ├── prototype3.png │ ├── prototype4.png │ ├── prototype5.png │ ├── prototype6.png │ └── prototype7.png │ ├── htmlimage-20220106170143742.png │ ├── htmlimage-20220106170248133.png │ └── htmlhtmlimage-20220106170143742.png ├── commitlint.config.js ├── package.json └── README.md /article/面试题目/算法/深度.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | -------------------------------------------------------------------------------- /article/面试题目/vue和react/vue常考面试题.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /article/面试题目/算法/二分查找.md: -------------------------------------------------------------------------------- 1 | # 二分查找 2 | 3 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn commitlint --edit "$1" 5 | -------------------------------------------------------------------------------- /asseats/images/hexo/hexo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/hexo.png -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn lint-staged --allow-empty "$1" 5 | -------------------------------------------------------------------------------- /asseats/images/css/BFC/BFC1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/BFC/BFC1.png -------------------------------------------------------------------------------- /asseats/images/css/BFC/BFC2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/BFC/BFC2.png -------------------------------------------------------------------------------- /asseats/images/css/BFC/BFC3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/BFC/BFC3.png -------------------------------------------------------------------------------- /asseats/images/css/BFC/BFC4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/BFC/BFC4.png -------------------------------------------------------------------------------- /asseats/images/hexo/scroll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/scroll.png -------------------------------------------------------------------------------- /asseats/images/jsprototype8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/jsprototype8.png -------------------------------------------------------------------------------- /asseats/images/css/flex/flex1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/flex/flex1.png -------------------------------------------------------------------------------- /asseats/images/css/flex/flex10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/flex/flex10.png -------------------------------------------------------------------------------- /asseats/images/css/flex/flex11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/flex/flex11.png -------------------------------------------------------------------------------- /asseats/images/css/flex/flex12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/flex/flex12.png -------------------------------------------------------------------------------- /asseats/images/css/flex/flex2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/flex/flex2.png -------------------------------------------------------------------------------- /asseats/images/css/flex/flex3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/flex/flex3.png -------------------------------------------------------------------------------- /asseats/images/css/flex/flex4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/flex/flex4.png -------------------------------------------------------------------------------- /asseats/images/css/flex/flex5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/flex/flex5.png -------------------------------------------------------------------------------- /asseats/images/css/flex/flex6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/flex/flex6.png -------------------------------------------------------------------------------- /asseats/images/css/flex/flex7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/flex/flex7.png -------------------------------------------------------------------------------- /asseats/images/css/flex/flex8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/flex/flex8.png -------------------------------------------------------------------------------- /asseats/images/css/flex/flex9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/flex/flex9.png -------------------------------------------------------------------------------- /asseats/images/html/原型以及原型链.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/原型以及原型链.jpeg -------------------------------------------------------------------------------- /asseats/images/js/prototype1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/js/prototype1.png -------------------------------------------------------------------------------- /asseats/images/js/prototype2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/js/prototype2.png -------------------------------------------------------------------------------- /asseats/images/js/prototype3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/js/prototype3.png -------------------------------------------------------------------------------- /asseats/images/js/prototype4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/js/prototype4.png -------------------------------------------------------------------------------- /asseats/images/js/prototype5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/js/prototype5.png -------------------------------------------------------------------------------- /asseats/images/js/prototype6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/js/prototype6.png -------------------------------------------------------------------------------- /asseats/images/js/prototype7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/js/prototype7.png -------------------------------------------------------------------------------- /asseats/images/css/boxModelbox-model1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/boxModelbox-model1.png -------------------------------------------------------------------------------- /asseats/images/css/boxModelbox-model2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/boxModelbox-model2.png -------------------------------------------------------------------------------- /asseats/images/css/boxModelbox-model3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/boxModelbox-model3.png -------------------------------------------------------------------------------- /asseats/images/css/boxModelbox-model6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/boxModelbox-model6.png -------------------------------------------------------------------------------- /asseats/images/css/boxModelbox-model7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/boxModelbox-model7.png -------------------------------------------------------------------------------- /asseats/images/css/position/position1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/position/position1.png -------------------------------------------------------------------------------- /asseats/images/css/position/position2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/position/position2.png -------------------------------------------------------------------------------- /asseats/images/css/position/position3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/position/position3.png -------------------------------------------------------------------------------- /asseats/images/css/position/position4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/position/position4.png -------------------------------------------------------------------------------- /asseats/images/css/position/position5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/position/position5.png -------------------------------------------------------------------------------- /asseats/images/css/position/position6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/position/position6.png -------------------------------------------------------------------------------- /asseats/images/css/position/position7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/position/position7.png -------------------------------------------------------------------------------- /asseats/images/css/position/position8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/position/position8.png -------------------------------------------------------------------------------- /asseats/images/css/position/position9.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/position/position9.gif -------------------------------------------------------------------------------- /asseats/images/css/priority/priority1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/priority/priority1.png -------------------------------------------------------------------------------- /asseats/images/css/priority/priority2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/priority/priority2.png -------------------------------------------------------------------------------- /asseats/images/css/priority/priority3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/priority/priority3.png -------------------------------------------------------------------------------- /asseats/images/css/priority/priority4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/priority/priority4.png -------------------------------------------------------------------------------- /asseats/images/css/priority/priority5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/priority/priority5.png -------------------------------------------------------------------------------- /asseats/images/css/priority/priority8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/priority/priority8.png -------------------------------------------------------------------------------- /asseats/images/css/priority/priority9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/priority/priority9.png -------------------------------------------------------------------------------- /asseats/images/css/selector/selector1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/selector/selector1.png -------------------------------------------------------------------------------- /asseats/images/css/selector/selector2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/selector/selector2.png -------------------------------------------------------------------------------- /asseats/images/css/selector/selector3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/selector/selector3.png -------------------------------------------------------------------------------- /asseats/images/css/selector/selector4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/selector/selector4.png -------------------------------------------------------------------------------- /asseats/images/css/selector/selector5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/selector/selector5.png -------------------------------------------------------------------------------- /asseats/images/css/selector/selector6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/selector/selector6.png -------------------------------------------------------------------------------- /asseats/images/css/selector/selector7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/selector/selector7.png -------------------------------------------------------------------------------- /asseats/images/css/selector/selector8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/selector/selector8.png -------------------------------------------------------------------------------- /asseats/images/css/selector/selector9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/selector/selector9.png -------------------------------------------------------------------------------- /asseats/images/css/box-model/box-model1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/box-model/box-model1.png -------------------------------------------------------------------------------- /asseats/images/css/box-model/box-model2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/box-model/box-model2.png -------------------------------------------------------------------------------- /asseats/images/css/box-model/box-model3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/box-model/box-model3.png -------------------------------------------------------------------------------- /asseats/images/css/box-model/box-model4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/box-model/box-model4.png -------------------------------------------------------------------------------- /asseats/images/css/box-model/box-model5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/box-model/box-model5.png -------------------------------------------------------------------------------- /asseats/images/css/box-model/box-model6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/box-model/box-model6.png -------------------------------------------------------------------------------- /asseats/images/css/box-model/box-model7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/box-model/box-model7.png -------------------------------------------------------------------------------- /asseats/images/html/屏幕录制2022-01-15 下午2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/屏幕录制2022-01-15 下午2.gif -------------------------------------------------------------------------------- /asseats/images/html/屏幕录制2022-01-15 下午3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/屏幕录制2022-01-15 下午3.gif -------------------------------------------------------------------------------- /asseats/images/css/div-center/div-center1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/div-center/div-center1.png -------------------------------------------------------------------------------- /asseats/images/css/div-center/div-center2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/div-center/div-center2.png -------------------------------------------------------------------------------- /asseats/images/css/div-center/div-center3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/div-center/div-center3.png -------------------------------------------------------------------------------- /asseats/images/css/div-center/div-center4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/css/div-center/div-center4.png -------------------------------------------------------------------------------- /asseats/images/html/屏幕录制2022-01-15 下午3 (1).gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/屏幕录制2022-01-15 下午3 (1).gif -------------------------------------------------------------------------------- /asseats/images/htmlimage-20220106170143742.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/htmlimage-20220106170143742.png -------------------------------------------------------------------------------- /asseats/images/htmlimage-20220106170248133.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/htmlimage-20220106170248133.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220117153956920.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220117153956920.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220117154056202.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220117154056202.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220117154209325.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220117154209325.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220117154336407.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220117154336407.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220117154539668.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220117154539668.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220117154713730.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220117154713730.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220118144154623.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220118144154623.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220118144310872.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220118144310872.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220118144332639.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220118144332639.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220118144408105.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220118144408105.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220118151322761.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220118151322761.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220118151413475.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220118151413475.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220118151655445.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220118151655445.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220119141616333.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220119141616333.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220119141706654.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220119141706654.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220119142042285.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220119142042285.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220119142214404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220119142214404.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220119142457348.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220119142457348.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220119142532859.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220119142532859.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220119142808820.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220119142808820.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220119143210533.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220119143210533.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220119143343104.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220119143343104.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220119144044662.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220119144044662.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220119171611982.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220119171611982.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220119172332985.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220119172332985.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220119172501736.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220119172501736.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220120083817190.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220120083817190.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220120084754458.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220120084754458.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220121110419337.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220121110419337.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220121111002144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220121111002144.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220123104356814.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220123104356814.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220123111354713.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220123111354713.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220123115412196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220123115412196.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220123115524563.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220123115524563.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220123115647543.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220123115647543.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220123135642800.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220123135642800.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220123172140939.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220123172140939.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220123172359003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220123172359003.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220123173915817.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220123173915817.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220123185803404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220123185803404.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220124084030346.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220124084030346.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220124113551797.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220124113551797.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220124115032597.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220124115032597.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220124155840387.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220124155840387.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220124161311114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220124161311114.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220124173335773.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220124173335773.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220125104906272.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220125104906272.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220125110924416.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220125110924416.png -------------------------------------------------------------------------------- /asseats/images/hexo/image-20220125135325746.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/hexo/image-20220125135325746.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220114141352206.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220114141352206.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220114141712822.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220114141712822.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220114152116579.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220114152116579.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220114152321369.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220114152321369.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220114153129007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220114153129007.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220114155411899.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220114155411899.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220114160450447.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220114160450447.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220114161111959.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220114161111959.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220114161329647.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220114161329647.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220114161641065.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220114161641065.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220114161713049.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220114161713049.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220115082250490.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220115082250490.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220115082334837.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220115082334837.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220115082636821.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220115082636821.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220115082716487.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220115082716487.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220115082838323.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220115082838323.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220115083005924.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220115083005924.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220115083450019.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220115083450019.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220115143358046.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220115143358046.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220115144035655.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220115144035655.png -------------------------------------------------------------------------------- /asseats/images/html/image-20220115151143676.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/image-20220115151143676.png -------------------------------------------------------------------------------- /asseats/images/html/htmlimage-20220106170248133.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/html/htmlimage-20220106170248133.png -------------------------------------------------------------------------------- /asseats/images/htmlhtmlimage-20220106170143742.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hzzzzzzzq/Blog/HEAD/asseats/images/htmlhtmlimage-20220106170143742.png -------------------------------------------------------------------------------- /article/JavaScript/事件循环.md: -------------------------------------------------------------------------------- 1 | # Event Loop 事件循环机制 (作为一篇技术博客去写 2 | 3 | ## 前言 4 | 5 | JS 中,我们都知道它是一门单线程语言,单线程,就是在代码在执行的时候,都只有一个主线程来处理所有的任务。 6 | 7 | **单线程的原因** 8 | 9 | **使用异步的作用** 10 | 11 | 而作为单线程的 JS 是如何做到异步非阻塞这个特点呢?那就是现在,我要讲的,Event Loop 事件循环机制。 12 | 13 | ## JS 中的事件循环机制 14 | 15 | ## 执行栈与事件队列 16 | 17 | - 执行栈 18 | 执行 script 中的同步代码 19 | - 事件队列 20 | 存放一些异步代码,非阻塞代码 21 | -------------------------------------------------------------------------------- /article/Git/0. 编写 git 文章目的.md: -------------------------------------------------------------------------------- 1 | ## 目的 2 | 在我们工作的开发中,避免不了 `Git` 的使用,而很多人,在使用 `Git` 时,产生的错误,都不知道怎么处理,反而给公司带来了一些不可逆的操作,所以学习 `Git` 则成了开发的一个重要工作。 3 | 4 | 我会尽力用这文章来教会我们使用 `git` 的基本操作,让你在开发时不会给公司招成太多烦恼。 5 | 6 | ## 文章目录 7 | 8 | - git 命令 9 | 简单介绍了 `git` 的一些常用命令。 10 | - git 实战 11 | 实战具体教了,如何去使用 `git` 的一些常用命令,在开发中解决大部分烦恼。 12 | - 格式化 commit 命令 13 | 格式化命令,主要是用来规范 `commit log` 信息,来提交 `commit` 的可读性。 14 | 15 | 一共三篇文章,如果在以后有新内容会对文章做修改或添加新文章。 -------------------------------------------------------------------------------- /article/ES6/0. 编写文章的目的.md: -------------------------------------------------------------------------------- 1 | ## 编写目的 2 | 3 | - 帮助更多学习前端 ES6 的人更好的理解知识点 4 | - 可以加深并巩固自身的知识点 5 | 6 | ## 编写目录 7 | 8 | ### 第一版 9 | 10 | - let 和 const 命令 11 | - 变量的解构赋值 12 | - 字符串的扩展 13 | - 函数的扩展 14 | - 参数默认值 - 作用域 15 | - 数组的扩展 16 | - 对象的扩展 17 | - 属性名表达式 18 | - 方法 name 属性 19 | - Object.assign() 写了基础的 20 | - Map 和 Set 21 | - weakMap 没写 22 | - setMap 没写 23 | - Promise 对象 24 | - Generator 函数 25 | - async 函数 26 | - 需要补充 27 | - Module 语法 28 | -------------------------------------------------------------------------------- /article/面试题目/JS/2. js常见面试题-2.md: -------------------------------------------------------------------------------- 1 | ## 1. js 延迟加载的方式有哪些 2 | 3 | - defer 属性 4 | - async 属性 5 | - 动态创建 DOM 方式 6 | - 使用 setTimeout 延迟方法 7 | - 让 JS 最后加载 8 | 9 | ## 2. defer 和 async 的区别 10 | 11 | defer 属性表示延迟执行引入的 JavaScript,即这段 JS 代码加载时 HTML 并未停止解析,这两个过程时并行的。当整个 document 解析完成后,在执行脚本。在 DOMContentLoaded 事件触发之前完成 12 | 13 | 多个脚本按顺序执行。 14 | 15 | async 属性表示异步执行引入的 JavaScript。 16 | 区别在于,如果已经加载好,就会开始执行,也就是说它的执行仍然会阻塞文档解析,只是它的加载过程不会阻塞。 17 | 18 | 多个脚本的执行顺序无法保证。 19 | 20 | ## 3. -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'], // 以下时我们自定义的规则 3 | rules: { 4 | 'type-enum': [ 5 | 2, 6 | 'always', 7 | [ 8 | 'bug', // 此项特别针对bug号,用于向测试反馈bug列表的bug修改情况 9 | 'feat', // 新功能(feature) 10 | 'fix', // 修补bug 11 | 'docs', // 文档(documentation) 12 | 'style', // 格式(不影响代码运行的变动) 13 | 'refactor', // 重构(即不是新增功能,也不是修改bug的代码变动) 14 | 'test', // 增加测试 15 | 'chore', // 构建过程或辅助工具的变动 16 | 'revert', // feat(pencil): add ‘graphiteWidth’ option (撤销之前的commit) 17 | 'merge', // 合并分支, 例如: merge(前端页面): feature-xxxx修改线程地址 18 | 'build', // 修改 package.json 等构件内容 19 | 'update', // 更新 20 | ], 21 | ], 22 | }, 23 | }; 24 | -------------------------------------------------------------------------------- /article/面试题目/vue和react/区别.md: -------------------------------------------------------------------------------- 1 | # vue 和 react 区别 2 | 3 | # 需要重新汇总 4 | 5 | - Vue 的表单可以使⽤ v-model ⽀持双向绑定,相⽐于 React 来说开发上更加⽅便, 当然了 v-model 其实就是个语法糖,本质上和 React 写表单的⽅式没什么区别 改变数据⽅式不同, Vue 修改状态相⽐来说要简单许多, React 需要使⽤ setState 6 | - 来改变状态,并且使⽤这个 API 也有⼀些坑点。并且 Vue 的底层使⽤了依赖追踪,⻚ ⾯更新渲染已经是最优的了,但是 React 还是需要⽤户⼿动去优化这⽅⾯的问题。 7 | - React 16 以后,有些钩⼦函数会执⾏多次,这是因为引⼊ Fiber 的原因 8 | - React 需要使⽤ JSX ,有⼀定的上⼿成本,并且需要⼀整套的⼯具链⽀持,但是完全可 以通过 JS 来控制⻚⾯,更加的灵活。 Vue 使⽤了模板语法,相⽐于 JSX 来说没有那 么灵活,但是完全可以脱离⼯具链,通过直接编写 render 函数就能在浏览器中运⾏。 在⽣态上来说,两者其实没多⼤的差距,当然 React 的⽤户是远远⾼于 Vue 的 9 | 10 | > => 相同点: 1.数据驱动页面,提供响应式的试图组件 2.都有 virtual DOM,组件化的开发,通过 props 参数进行父子之间组件传递数据,都实现了 webComponents 规范 3.数据流动单向,都支持服务器的渲染 SSR 4.都有支持 native 的方法,react 有 React native, vue 有 wexx 11 | > => 不同点: 1.数据绑定:Vue 实现了双向的数据绑定,react 数据流动是单向的 2.数据渲染:大规模的数据渲染,react 更快 3.使用场景:React 配合 Redux 架构适合大规模多人协作复杂项目,Vue 适合小快的项目 4.开发风格:react 推荐做法 jsx + inline style 把 html 和 css 都写在 js 了 12 | > vue 是采用 webpack + vue-loader 单文件组件格式,html, js, css 同一个文件 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "myblog", 3 | "version": "1.0.0", 4 | "description": "这是我记录博客的地方,希望能多写一些技术博客,JS、ES、React、Vue等", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "prepare": "husky install" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/hzzzzzzzq/Blog.git" 13 | }, 14 | "author": "", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/hzzzzzzzq/Blog/issues" 18 | }, 19 | "homepage": "https://github.com/hzzzzzzzq/Blog#readme", 20 | "lint-staged": { 21 | "src/**/*.{js,jsx,ts,tsx,json}": [ 22 | "prettier --write", 23 | "eslint", 24 | "git add" 25 | ] 26 | }, 27 | "devDependencies": { 28 | "@commitlint/cli": "^15.0.0", 29 | "@commitlint/config-conventional": "^15.0.0", 30 | "eslint": "^8.4.1", 31 | "husky": "^7.0.4", 32 | "lint-staged": "^12.1.2", 33 | "prettier": "^2.5.1" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /article/CSS/0. 编写 css 目的.md: -------------------------------------------------------------------------------- 1 | # 编写 CSS 目的 2 | 3 | ## 适合人群 4 | 5 | - 适合了解过 CSS 基础的人 6 | - 想要更深入的进行学习 CSS 的人 7 | - CSS 面试复习的人 8 | 9 | ## 目的 10 | 11 | > 主要是为了让更多的人,掌握 css 相关的布局,选择器等内容,方便在开发中使用。 12 | 13 | 在开发过程中,样式与布局是我们最常用到的内容,而我在下面的这些文章中,以面试题目的方式,教一些最常用的一些 `css` 内容。 14 | 15 | 而这些内容的作用,主要是为了让你的页面布局更加实用、美观。 16 | 17 | 公司的开发项目中,一般会使用 `less、scss` 等一些框架方式,而这些框架的基础其实都是 `css` 的一些基础。 18 | 19 | 基础样式,我就不在这些文章中叙述了。 20 | 21 | ## 文章目录 22 | 23 | - **盒模型** 24 | 主要介绍了盒模型是什么。 25 | - **css 选择器** 26 | 了解一下 `css` 各类选择器,具体的使用方式。 27 | - **BFC** 28 | 带你们了解一下,什么是 `BFC`,以及它的应用有什么? 29 | - **position** 30 | 各种定位,方便在开发中使用。 31 | - **flex** 32 | 主要介绍了 `flex` 布局,可以学的详细,并使用。 33 | - **css 优先级** 34 | 主要介绍了 `css` 样式优先级,在这里可以了解到,各类选择器的优先级情况。 35 | - 双飞翼/圣杯布局 36 | 主要介绍了三列布局,如何来做。 37 | - **div 居中** 38 | 介绍了一些,让元素或者内容水平垂直居中的方式。 39 | - **css3 新特性** 40 | 这篇文章,主要是带你们了解一下 `css3` 中新增加的特性 41 | - **float** 42 | 了解浮动,使用,以及清除浮动 43 | 44 | ## 为什么写这些 CSS 文章? 45 | 46 | CSS 也是面试中的内容,而在以往,我们对 CSS 的学习,都是最基础的内容进行学习,而没有深入去了解过知识。 47 | 48 | 这些文章,都是在面试题中常用的文章,也是在开发中经常使用的文章,如果都可以熟练掌握,对开发中的布局将会有一个极大的提升。 49 | 50 | 这些文章可以用来对知识进行一个巩固,通过学习,我相信可以学到你想要的 CSS 知识。 51 | -------------------------------------------------------------------------------- /article/ES6/1. 了解ES6.md: -------------------------------------------------------------------------------- 1 | # 了解 ES 6 2 | 3 | 首先呢,我们来说一下 `ECMAScript`,`ECMAScript` 是 `JavaScript` 中的语法规范。那我们来看看[**维基百科**中的定义](https://zh.wikipedia.org/wiki/ECMAScript)。 4 | 5 | > ECMAScript 是一种由 Ecma 国际(前身为欧洲计算机制造商协会)在标准 ECMA-262 中定义的脚本语言规范。这种语言在万维网上应用广泛,它往往被称为 JavaScript 或 JScript,但实际上后两者是 ECMA-262 标准的实现和扩展。 6 | 7 | 那 `ECMAScript` 的主要作用是什么呢?定义了很多我们需要使用的重要的东西。 8 | 9 | - 语法: 解析规则,关键词,语句,声明,操作等 10 | - 类型: 布尔型,数字,字符串,对象等 11 | - 原型和继承 12 | - 内置对象和函数的标准库: JSON,Math,数组方法等等 13 | 14 | 说完了 `ECMAScript` ,那我们就可以来看看 `ES 6` 了。 15 | `ES 6` 全称 `ECMASCript 6`,我们可以看出,是 `ECMAScript` 的第六版,是 `JavaScript` 的一个标准, 2015 年 6 月发版,主要目的是解决 `ES 5` 的不足。截止 2020 年 6 月已经更新至 `11` 版。 16 | 17 | ## 为什么要学习 ES 6? 18 | 19 | 首先,`ES 6` 是 `ECMAScript 2015` 出版的一个标准,各个浏览器厂商都相当踊跃的遵循了这个标准,目前 **Chrome 已经支持了超过 80% 的 `ES 6` 特性**,业界流行框架类库都开始使用 `ES6` 编写。 20 | 从 2011 年更新了 5.1 版本之后,直到 2015 年才更新了 `ES 6`, 它已成为 `JavaScript` 有史以来最实质的一次升级,新的语言和库特性就像无主之宝,等待有识之士的发掘。新的语言特性涵盖范围甚广,小到受欢迎的语法糖,例如箭头函数和简单的字符串插值,大到复杂的新概念,例如代理、生成器和承诺(`Promise`)等。 21 | `ES 6` 彻底改变了我们的编写 `JavaScript` 代码方式,况且目前 `ES 5` 的使用已经很少,基本上都采用了 `ES 6` 的写法。 22 | 所以在这个复杂的前端时代,学习 `ES 6` 已经成为了必然。 23 | 24 | ## 如何怎么学习? 25 | 26 | 那我们来看看应该怎么学吧,我在接下来的文章中,将 `ES 6` 中重要的内容挖出来,并进行简单化教程,可以观看我之后的文章进行快速性学习,然后通过不断联系,去加快自己的掌握。 27 | -------------------------------------------------------------------------------- /article/面试题目/JS/ES6 面试.md: -------------------------------------------------------------------------------- 1 | ## **ES6面试题** 2 | 3 | 4 | **ES6新增方法面试题** 5 | 6 | - 1.let const var比较 7 | - 2.反引号(`)标识 8 | - 3.函数默认参数 9 | - 4.箭头函数 10 | - 5.属性简写 11 | - 6.方法简写 12 | - 7.Object.keys()方法,获取对象的所有属性名或方法名 13 | - 8.Object.assign ()原对象的属性和方法都合并到了目标对象 14 | - 9.for...of 循环 15 | - 10.import和export 16 | - 11.Promise对象 17 | - 12.解构赋值 18 | - 13.set数据结构(可用于快速去重) 19 | - 14.Spread Operator 展开运算符(...) 20 | - 15.字符串新增方法 21 | 22 | 23 | 24 | **ES6数组面试题** 25 | 26 | - 1.forEach() 27 | 28 | 回调函数,带三个参数 item,index, array 29 | 30 | item 当前值,index当前索引 array为原数组 31 | 32 | - 2.map() 33 | 34 | 创建一个新数组,其结果是该数组中的每个元素都调用一次提供的函数后的返回值 35 | 36 | - 3.filter() 37 | 38 | 过滤,创建一个新数组,包含通过提供函数实现的所有元素。 39 | 40 | ```javascript 41 | const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present']; 42 | 43 | const result = words.filter(word => word.length > 6); 44 | 45 | console.log(result); 46 | // expected output: Array ["exuberant", "destruction", "present"] 47 | ``` 48 | 49 | - 4.reduce() 50 | 51 | 对数组中的每个元素执行一个reducer函数,将结果汇总为单个返回值 52 | 53 | - 5.some() 54 | 55 | 测试数组中是不是至少有一个元素通过了被测试函数,返回一个布尔值 56 | 57 | - 6.every() 58 | 59 | 返回一个布尔值,判断某个数组中所有的元素是否都满足回调函数的条件,如果满足,返回 true 60 | 61 | ```javascript 62 | const isBelowThreshold = (currentValue) => currentValue < 40; 63 | 64 | const array1 = [1, 30, 39, 29, 10, 13]; 65 | 66 | console.log(array1.every(isBelowThreshold)); 67 | // expected output: true 68 | ``` 69 | 70 | - 7.all()方法 71 | 72 | **ES6编程题** 73 | 74 | - 1.使用解构,实现两个变量的值的交换 75 | 76 | [a, b] = [b, a] 77 | 78 | - 2.利用数组推导,计算出数组 [1,2,3,4] 每一个元素的平方并组成新的数组。 79 | - 3.使用ES6改下面的模板 80 | - 4.把以下代码使用两种方法,来依次输出0到9? -------------------------------------------------------------------------------- /article/面试题目/浏览器和网络/浏览器常考面试题.md: -------------------------------------------------------------------------------- 1 | ## 1. session、cookie、localStorage 的区别 2 | 3 | **相同点** 4 | 5 | - 都是保存在浏览器端,且同源的。 6 | 7 | | 特征 | cookie | session | localStorage | 8 | | ------------ | ------------------------------ | ------------------ | -------------------------- | 9 | | 数据⽣命周期 | 由服务器生成,可以设置过期时间 | 页面关闭清理 | 除⾮手动清理,否则⼀直存在 | 10 | | 数据存储大小 | 4K | 5M | 5M | 11 | | 与服务端通信 | 每次都会携带在 header 中 | 不参与,只存在本地 | 不参与,只存在本地 | 12 | 13 | ## 2. 浏览器渲染的主要流程 14 | 15 | - 将 `html` 代码按照深度优先遍历来生成 `DOM` 树 16 | - `css` 文件下载完后也会进行渲染,生成相应的 CSSOM 17 | - 当所有的 `css` 文件下载完且所有的 `CSSOM` 构建结束后,就会和 `DOM` 一起生成 `Render Tree` 18 | - 浏览器就会进入 `Layout` 环节,将所有的节点位置计算出来 19 | - 通过 Painting 环节将所有的节点内容呈现到屏幕上 20 | 21 | 简化一下 22 | html 遍历 > 生成 DOM 树 > 生成 CSSOM > 构建 Render Tree > Layout 计算节点位置 > 通过 Painting 呈现在屏幕 23 | 24 | ## 3. 从输入 url 地址到页面相应都发生了什么? 25 | 26 | 1、浏览器的地址栏输入 URL 并按下回车。 27 | 2、浏览器查找当前 URL 是否存在缓存,并比较缓存是否过期。3、DNS 解析 URL 对应的 IP。 28 | 4、根据 IP 建立 TCP 连接(三次握手)。 29 | 5、HTTP 发起请求。 30 | 6、服务器处理请求,浏览器接收 HTTP 响应。 31 | 7、渲染页面,构建 DOM 树。 32 | 8、关闭 TCP 连接(四次挥手) 33 | 34 | ## 4. 缓存策略 35 | 36 | ## 5. history 和 hash 两种路由 37 | 38 | ## 6. HTML5 新特性 39 | 40 | - 语义化标签: header、footer、section、nav、aside、article 41 | 42 | - 增强型表单: input 的多个 type: color, date, datetime, email, month, number, range, search, tel, time, url, week 43 | 44 | - 新增表单元素: 45 | 46 | - datalist 定义选项列表。请与 input 元素配合使用该元素,来定义 input 可能的值 47 | - keygen 规定用于表单的密钥对生成器字段 48 | - output 定义不同类型的输出,比如脚本的输出 49 | 50 | - 音频视频 51 | 52 | > audio 定义音频内容 53 | > video 定义视频 54 | > source 定义多媒体资源 video 和 audio 55 | > embed 定义潜入的内容,比如插件 56 | > track 为诸如 video 和 audio 元素之类的媒介规定外部文本轨道 57 | 58 | - 拖拽: drag 59 | 60 | - 本地存储: localStorage、sessionStorage 61 | 62 | - WebSocket 63 | 64 | ## 7. -------------------------------------------------------------------------------- /article/JavaScript/专题/1. JavaScript专题之深浅拷贝.md: -------------------------------------------------------------------------------- 1 | # 深拷贝和浅拷贝 2 | 3 | ## 浅拷贝 4 | 5 | 拷贝了基础数据,而引用数据拷贝后也会被引用,换句话就是,当拷贝的引用数据修改时,两个会同时修改。 6 | 7 | - `Object.assign()` 8 | - `Array.prototype.concat()` 9 | - 扩展运算符 10 | - `Array.prototype.slice()` 11 | 12 | ```javascript 13 | // 手动实现,浅拷贝 14 | function clone(obj) { 15 | if (!obj || typeof obj !== 'object') return; 16 | let newObj = Array.isArray(obj) ? [] : {}; 17 | for (let o in obj) { 18 | if (obj.hasOwnProperty(o)) { 19 | newObj[o] = obj[o]; 20 | } 21 | } 22 | return newObj; 23 | } 24 | let obj = { 25 | name: 'hzzzzzzzq', 26 | age: 22, 27 | info: { 28 | address: '地址', 29 | }, 30 | }; 31 | let cloneObj = clone(obj); 32 | cloneObj.info.address = '杭州'; 33 | cloneObj obj 34 | // 我们会发现 两者打印相同的,说明浅拷贝只是拷贝了 info 的引用地址,所以修改拷贝时,原数据也会变 35 | // { 36 | // "name": "hzzzzzzzq", 37 | // "age": 22, 38 | // "info": { 39 | // "address": "杭州" 40 | // } 41 | // } 42 | ``` 43 | 44 | ## 深拷贝 45 | 46 | 创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。 47 | 48 | 深拷贝的三种方式 49 | 50 | - `JSON.parse、JSON.stringify()` 51 | - 递归 52 | - `lodash _.cloneDeep` 53 | 54 | 介绍递归手写的方式。 55 | 56 | ```javascript 57 | // 手动实现深拷贝 58 | function deepClone(obj) { 59 | if (!obj || typeof obj !== 'object') return; 60 | let newObj = Array.isArray(obj) ? [] : {}; 61 | for (let o in obj) { 62 | if (obj.hasOwnProperty(o)) { 63 | newObj[o] = typeof obj[o] === 'object' ? deepClone(obj[o]) : obj[o]; 64 | } 65 | } 66 | return newObj; 67 | } 68 | let obj = { 69 | name: 'hzzzzzzzq', 70 | age: 22, 71 | info: { 72 | address: '地址', 73 | }, 74 | }; 75 | let cloneObj = deepClone(obj); 76 | cloneObj.info.address = '杭州'; 77 | cloneObj; 78 | // { 79 | // "name": "hzzzzzzzq", 80 | // "age": 22, 81 | // "info": { 82 | // "address": "杭州", 83 | // } 84 | // } 85 | obj; 86 | // { 87 | // "name": "hzzzzzzzq", 88 | // "age": 22, 89 | // "info": { 90 | // "address": "地址", 91 | // } 92 | // } 93 | ``` 94 | -------------------------------------------------------------------------------- /article/面试题目/CSS/盒模型相关面试题.md: -------------------------------------------------------------------------------- 1 | ## 1. 请画出 css 盒模型,基于盒模型的原理,说明相对定位、绝对定位、浮动实现样式是如何实现的? 2 | 3 | 由外到里顺序:margin-border-padding-content 4 | 5 | IE 盒模型宽度 width = content+padding+border (border-box) 6 | 7 | 标准盒模型宽度 width = content (content-box) 8 | 9 | #### 不同定位 10 | 11 | **1. 相对定位** 12 | 13 | relative 对象不可层叠、不脱离文档流,参考自考静态位置通过 top、bottom、left、right 定位,并且可以通过 z-index 进行层级分级。 14 | 15 | **2. 绝对定位** 16 | 17 | absolute 脱离文档流,通过 top、bottom、left、right 定位。选取其最近一个最有定位设置的父级对象进行绝对定位,如果对象的父级没有设置定位属性,absolute 元素将以 body 坐标原点进行定位,可以通过 z-index 进行层次分级。 18 | 19 | **3. 浮动** 20 | 21 | 脱离文档流,也就是将元素从普通的布局排版中拿走,其他盒子再定位的时候,会当做脱离文档流的元素不存在而进行定位。 22 | 23 | ### 10. 以下选项为 css 盒模型属性有哪些?(多选 24 | 25 | A.`font` B. `margin` C. `padding` D. `visible` E. `border` 26 | 27 | `B C E` 28 | 29 | #### 解释:如 11 题所说 30 | 31 | ### 11. 说下盒模型的区别?介绍一下标准的 css 盒模型?border-box 和 content-box 有什么区别 32 | 33 | #### 盒模型 34 | 35 | 盒模型是 css 中的一种基础设计模式,web 页面中的所有元素都可以当作一个盒模型,每一个盒模型都是由 display,position,float,width,height,margin,padding 和 border 等属性组合所构成的,不同类型的盒模型会有不一样的布局,css 中主要有 inline,inline-block,block,table,absolute,position,float 等类型。 36 | 37 | #### W3C 标准模型和 IE 的传统模型 38 | 39 | 相同之处都是对 web 中元素计算尺寸的模型,不同之处在于两者的计算方式不同。 40 | 41 | 标准模型: 包含 margin、border、padding、content,并且 content 中不包含其他部分。 42 | 43 | 计算方式: 44 | 45 | - height(空间高度) = height(content) + padding + border + margin (height 为内容高度 46 | - width(空间宽度) = width(content) + padding + border +margin (width 为内容高度 47 | 48 | IE 传统模型: 包含 margin、border、padding、content,不同的是,content 中包含了 padding 和 border。 49 | 50 | 计算方式: 51 | 52 | - height(空间高度) = content + margin 53 | - width(空间宽度) = content + margin 54 | 55 | #### border-box & content-box 56 | 57 | ##### Content-box 58 | 59 | 默认值,也就是说设置的 width 其实并不是显示的 width,设置的 width 只是 其中内容(content)部分是 width,而别的是另外加的。 60 | 61 | **举个例子** 62 | 63 | ```css 64 | .content-box { 65 | width: 100px; 66 | height: 100px; 67 | padding: 10px; 68 | margin: 10px; 69 | box-sizing: content-box; 70 | border: 10px solid #999; 71 | } 72 | ``` 73 | 74 | 这边设置的 width 是 100px 而实际元素展示的宽度 = 100 + 2\*padding + 2\*border = 140px 75 | 76 | 高度计算与宽度相同 77 | 78 | ##### border-box 79 | 80 | 重新定义 css2.1 中盒模型组成的模式,让元素维持 IE 传统的盒模型(IE6 一下版本和 IE6-7 怪异模式),也就是说元素的宽度或高度等于元素内容的宽度或高度。从上面盒模型介绍可知,这里的内容宽度或者高度包含了元素的 border、padding、内容的宽度或高度(此处的内容宽度 = 盒子的宽度 - 边框 - 内距 81 | 82 | 举个例子 83 | 84 | ```css 85 | .border-box { 86 | width: 100px; 87 | height: 100px; 88 | padding: 10px; 89 | margin: 10px; 90 | box-sizing: border-box; 91 | border: 10px solid #999; 92 | } 93 | ``` 94 | 95 | 这边设置的 width 是 100px,实际元素展示的宽度就是 100px 96 | 97 | content 内容的宽度 = 100 - 2\*border - 2\*padding = 60px 98 | -------------------------------------------------------------------------------- /article/面试题目/JS/1. JS面试 上.md: -------------------------------------------------------------------------------- 1 | **js面试题** 2 | 3 | - 1.简述同步和异步的区别 4 | - 2.怎么添加、移除、复制、创建、和查找节点 5 | - 3.实现一个函数clone 可以对Javascript中的五种主要数据类型(Number、string、Object、Array、Boolean)进行复制 6 | - 4.如何消除一个数组里面重复的元素 7 | - 5.写一个返回闭包的函数 8 | - 6.使用递归完成1到100的累加 9 | - 7.Javascript有哪几种数据类型 10 | - 8.如何判断数据类型 11 | - 9.console.log(1+'2')和console.log(1-'2')的打印结果 12 | 13 | ​ '12' -1 14 | 15 | - 10.Js的事件委托是什么,原理是什么 16 | - 11.如何改变函数内部的this指针的指向 17 | - 12.列举几种解决跨域问题的方式,且说明原理 18 | - 13.谈谈垃圾回收机制的方式及内存管理 19 | - 14.写一个function ,清除字符串前后的空格 20 | - 15.js实现继承的方法有哪些 21 | - 16.判断一个变量是否是数组,有哪些办法 22 | - 17.let ,const ,var 有什么区别 23 | - 18.箭头函数与普通函数有什么区别 24 | - 19.随机取1-10之间的整数 25 | - 20.new操作符具体干了什么 26 | - 21.Ajax原理 27 | - 22.模块化开发怎么做 28 | - 23.异步加载Js的方式有哪些 29 | - 24.xml和 json的区别 30 | - 25.webpack如何实现打包的 31 | - 26.常见web安全及防护原理 32 | - 27.用过哪些设计模式 33 | - 28.为什么要同源限制 34 | - 29.offsetWidth/offsetHeight,clientWidth/clientHeight与scrollWidth/scrollHeight的区别 35 | - 30.javascript有哪些方法定义对象 36 | - 31.说说你对promise的了解 37 | - 32.谈谈你对AMD、CMD的理解 38 | - 33.web开发中会话跟踪的方法有哪些 39 | - 34.介绍js有哪些内置对象? 40 | - 35.说几条写JavaScript的基本规范? 41 | - 36.javascript创建对象的几种方式? 42 | - 37.eval是做什么的? 43 | - 38.null,undefined 的区别? 44 | - 39.[“1”, “2”, “3”].map(parseInt) 答案是多少? 45 | - 40.javascript 代码中的”use strict”;是什么意思 ? 使用它区别是什么? 46 | - 41.js延迟加载的方式有哪些? 47 | - 42.defer和async 48 | - 43.说说严格模式的限制 49 | - 44.attribute和property的区别是什么? 50 | - 45.ECMAScript6 怎么写class么,为什么会出现class这种东西? 51 | - 46.常见兼容性问题 52 | - 47.函数防抖节流的原理 53 | - 48.原始类型有哪几种?null是对象吗? 54 | - 49.为什么console.log(0.2+0.1==0.3) //false 55 | - 50.说一下JS中类型转换的规则? 56 | - 51.深拷贝和浅拷贝的区别?如何实现 57 | - 52.如何判断this?箭头函数的this是什么 58 | - 53.== 和 ===的区别 59 | - 54.什么是闭包 60 | - 55.JavaScript原型,原型链 ? 有什么特点? 61 | - 56.typeof()和instanceof()的用法区别 62 | - 57.什么是变量提升 63 | - 58.all、apply以及bind函数内部实现是怎么样的 64 | - 59.为什么会出现setTimeout倒计时误差?如何减少 65 | - 60.谈谈你对JS执行上下文栈和作用域链的理解 66 | - 61.new的原理是什么?通过new的方式创建对象和通过字面量创建有什么区别? 67 | - 62.prototype 和 proto 区别是什么? 68 | - 63.使用ES5实现一个继承? 69 | - 64.取数组的最大值(ES5、ES6) 70 | - 65.ES6新的特性有哪些? 71 | - 66.promise 有几种状态, Promise 有什么优缺点 ? 72 | - 67.Promise构造函数是同步还是异步执行,then呢 ?promise如何实现then处理 ? 73 | - 68.Promise和setTimeout的区别 ? 74 | - 69.如何实现 Promise.all ? 75 | - 70.如何实现 Promise.finally ? 76 | - 71.如何判断img加载完成 77 | - 72.如何阻止冒泡? 78 | - 73.如何阻止默认事件? 79 | - 74.ajax请求时,如何解释json数据 80 | - 75.json和jsonp的区别? 81 | - 76.如何用原生js给一个按钮绑定两个onclick事件? 82 | - 77.拖拽会用到哪些事件 83 | - 78.document.write和innerHTML的区别 84 | - 79.jQuery的事件委托方法bind 、live、delegate、on之间有什么区别? 85 | - 80.浏览器是如何渲染页面的? 86 | - 81.$(document).ready()方法和window.onload有什么区别? 87 | - 82.jquery中.get()提交和post()提交有区别吗? 88 | - 83.对前端路由的理解?前后端路由的区别? 89 | - 84.手写一个类的继承 90 | - 85.XMLHttpRequest:XMLHttpRequest.readyState;状态码的意思 -------------------------------------------------------------------------------- /article/JavaScript/4. JavaScript深入之作用域链.md: -------------------------------------------------------------------------------- 1 | # JavaScript 深入之作用域链 2 | 3 | 在[《JavaScript 深入之执行上下文栈》]()中提到,当 JavaScript 代码执行代码时,就会创建一个执行上下文。 4 | 5 | 对于执行上下文,都有三个重要属性: 6 | 7 | - 变量对象 (Variable Object - VO) 8 | - 作用域链 9 | - this 10 | 11 | 我们来介绍一下作用域链。 12 | 13 | ## 作用域链 14 | 15 | 在查找变量的时候,会先从当前上下文的变量对象中查找,如果没找到,就会从上一级的执行上下文的变量对象中查找,直到找到全局对象为止。 16 | 17 | 而这样由多个执行上下文的变量对象构成的链表就时作用域链。 18 | 19 | ## 函数创建 20 | 21 | 每一个函数都有自己的作用域,内部有一个 `[[scope]]` 属性,当函数创建时,就会保存所有父级变量对象到其中,简单来说,`[[scope]]` 就是所有父级变量对象的层级链。 22 | 注意:`[[scope]]` 并不能代表完整的作用域链。 23 | 24 | 我们来看一个例子吧 25 | 26 | ```javascript 27 | function fn1() { 28 | function fn2() { 29 | function fn3() {} 30 | } 31 | } 32 | ``` 33 | 34 | 函数创建时,我们来看看每一个函数的 `[[scope]]` 为: 35 | 36 | ```javascript 37 | fn1.[[scope]] = [ 38 | globalContext.VO 39 | ]; 40 | fn2.[[scope]] = [ 41 | fn1Context.AO, 42 | globalContext.VO 43 | ]; 44 | fn3.[[scope]] = [ 45 | fn2Context.AO, 46 | fn1Context.AO, 47 | globalContext.VO 48 | ] 49 | ``` 50 | 51 | ## 函数激活 52 | 53 | 当函数激活时,进入函数上下文,创建 `VO/AO` 后,就会将活动对象添加到作用域链的前端。 54 | 55 | 在执行上下文中,我们将作用域链命名为 `Scope` 56 | 57 | ```javascript 58 | Scope = [AO].concat([[Scope]]); 59 | ``` 60 | 61 | 我们来举个例子吧,对《JavaScript 权威指南》 中的例子进行修改 62 | 63 | ```javascript 64 | var scope = 'global scope'; 65 | function checkscope() { 66 | var scope = 'local scope'; 67 | return scope; 68 | } 69 | checkscope(); 70 | ``` 71 | 72 | 来看看执行过程吧 73 | 74 | - 创建 checkscope 函数 75 | 76 | ```javascript 77 | checkscope.[[scope]] = [ 78 | globalContext.VO 79 | ] 80 | ``` 81 | 82 | - 创建 checkscope 函数执行上下文,并将 checkscope 函数执行上下文压入执行上下文栈 83 | 84 | ```javascript 85 | ECStack = [checkscopeContext, globalContext]; 86 | ``` 87 | 88 | - checkscope 函数分析阶段 - 复制函数[[scope]]属性创建作用域链,并进行 `AO` 的创建。如何创建看[《JavaScript 深入之变量对象》]()。 89 | 90 | ```javascript 91 | checkscopeContext = { 92 | AO: { 93 | arguments: { 94 | length: 0 95 | }, 96 | scope: undefined 97 | }, 98 | Scope: checkscope.[[scope]] 99 | } 100 | ``` 101 | 102 | - 将活动对象压入 checkscope 作用域链顶端 103 | 104 | ```javascript 105 | checkscopeContext = { 106 | AO: { 107 | arguments: { 108 | length: 0, 109 | }, 110 | scope: undefined, 111 | }, 112 | Scope: [AO, [[Scope]]], 113 | }; 114 | ``` 115 | 116 | - 开始执行函数 117 | 118 | ```javascript 119 | checkscopeContext = { 120 | AO: { 121 | arguments: { 122 | length: 0, 123 | }, 124 | scope: 'local scope', 125 | }, 126 | Scope: [AO, [[Scope]]], 127 | }; 128 | ``` 129 | 130 | - 返回 `scope`,在一开始就找到了,所有直接返回该值,函数执行完毕。函数上下文弹出执行上下文栈。 131 | 132 | ```javascript 133 | ECStack = [globalContext]; 134 | ``` 135 | -------------------------------------------------------------------------------- /article/面试题目/vue和react/react常考面试题.md: -------------------------------------------------------------------------------- 1 | ## 1. 生命周期 2 | 3 | **不展示不常用的生命周期** 4 | 5 | ![image-20210630171416757](/Users/hzq/Library/Application Support/typora-user-images/image-20210630171416757.png) 6 | 7 | **展示不常用生命周期** 8 | 9 | ![image-20210630171407188](/Users/hzq/Library/Application Support/typora-user-images/image-20210630171407188.png) 10 | 11 | #### 常用的三个 12 | 13 | **componentDidMount()** 14 | 15 | - 方法在组件挂载后(插入 DOM 树中) 立即调用。依赖于 DOM 节点的初始化应该放在这里。如需通过网络请求获取数据,此处是实例化的好地方。 16 | - 这个方法是比较适合添加订阅的地方。如果添加了订阅,请不要忘记在 `componentWillUnmount()` 里面取消订阅 17 | - 也可以在方法里**直接调用 setState()**. 它将触发额外渲染,但是此渲染会发生在浏览器更新屏幕之前。如此保证了即使在 `render()` 两次调用的情况下,用户也不会看到中间状态。需要谨慎使用该模式,因为它会导致性能问题。通常,你应该在 `constructor()` 中初始化 state。如果你的渲染依赖于 DOM 节点的大小或位置,比如实现 modals 和 tooltips 等情况下,你可以使用此方式处理 18 | 19 | **componentDidUpdate()** 20 | 21 | - 方法在更新后会被立即调用。首次渲染不会执行此方法。 22 | - 当组件更新后,可以在此处对 DOM 进行操作。如果你对更新前后的 props 进行了比较,也可以选择在此处进行网络请求。(例如,当 props 未发生变化时,则不会执行网络请求)。 23 | 24 | ```jsx 25 | componentDidUpdate(prevProps) { 26 | // 典型用法(不要忘记比较 props): 27 | if (this.props.userID !== prevProps.userID) { 28 | this.fetchData(this.props.userID); 29 | } 30 | } 31 | ``` 32 | 33 | - 你也可以在 componentDidUpdate() 中**直接调用 setState()**,但请注意它必须被包裹在一个条件语句里,正如上述的例子那样进行处理,否则会导致死循环。它还会导致额外的重新渲染,虽然用户不可见,但会影响组件性能,不要将 props“镜像”给 state,请考虑直接使用 props。 34 | 35 | 如果 shouldComponentUpdate() 返回 false 就不会调用 componentDidUpdate() 36 | 37 | **componentWillUnmount()** 38 | 39 | - 会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除 timer,取消网络请求或清除在 componentDidMount() 中创建的订阅等 40 | - **不应调用 setState()**,因为该组件将永远不会重新渲染。组件实例卸载后,将用户不会再挂载它。 41 | 42 | #### 不常用生命周期 43 | 44 | **shouldComponentUpdate(nextProps, nextState)** 45 | 46 | - 根据该方法的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。默认行为是 state 每次发生变化组件都会重新渲染。大部分情况下,你应该遵守默认行为 47 | - 当 props 或 state 发生变化时,shouldComponentUpdate() 会在渲染执行之前被调用。返回值默认 true。首次渲染或使用 forceUpdate() 时不会调用该方法 48 | - 此方法仅作为性能优化的方式而存在。不要企图依靠此方式来"阻止"渲染,因为这可能会产生 bug。你应该考虑使用内置的 PureComponent 组件,而不是手动编写该方法。PureComponent 会对 props 和 state 进行浅层比较。并减少了跳过必要更新的可能性。 49 | - 如果你一定要手动编写,可以将 this.props 与 nextProps 以及 this.state 与 nextState 进行比较,并返回 false 以告诉 React 可以跳过更新。请注意,返回 false 并不会阻止组件在 state 更改时重新渲染。 50 | - 不建议在改函数中进行深层次比较或者使用 JSON.stringify()。这样非常影响效率,且会损害性能。 51 | - 目前,如果该函数返回 false,则不会调用 UNSAFE_componentWillUpdate(),render() 和 componentDidUpdate()。后续版本,React 可能会讲 该函数 视为提示而不是严格的指令,并且,当返回 false 时,仍可能导致组件重新渲染 52 | 53 | **static getDerivedStateFromProps(props, state)** 54 | 55 | - getDerivedStateFromProps 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回 null 则不更新内容。 56 | - 此方法适用于罕见的用例,即 state 的值在任何时候都取决于 props。 57 | 58 | **getSnapshotBeforeUpdate(prevProps, prevState)** 59 | 60 | - 在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期的任何返回值将作为参数传递给 `componentDidUpdate()` 61 | 62 | 63 | ## 2. setState 64 | 65 | ## 3. 性能优化 66 | 67 | ## 4. husky -------------------------------------------------------------------------------- /article/JavaScript/2. JavaScript深入之执行上下文栈.md: -------------------------------------------------------------------------------- 1 | # JavaScript 深入之执行上下文栈 2 | 3 | ## JS 是否是顺序执行? 4 | 5 | JavaScript 代码的执行顺序,在写过该语言的人眼中,都会认为是顺序执行的。 6 | 7 | ```javascript 8 | var fn = function () { 9 | console.log('first function'); 10 | }; 11 | 12 | fn(); // first function 13 | 14 | var fn = function () { 15 | console.log('second function'); 16 | }; 17 | fn(); // second function 18 | ``` 19 | 20 | 完美的顺序执行,但是我们稍微修改一下呢? 21 | 22 | ```javascript 23 | function fn() { 24 | console.log('first function'); 25 | } 26 | 27 | fn(); // second function 28 | 29 | function fn() { 30 | console.log('second function'); 31 | } 32 | fn(); // second function 33 | ``` 34 | 35 | 打印结果真的是出人意料啊,两个都为 `second function`。这又是为什么呢? 36 | 37 | 因为我们的 `JavaScript` 引擎执行代码是通过一段一段的执行,而不是一行一行的执行。所以当执行一段代码时,就会进入一个准备工作,比如变量提升或函数提升。 38 | 39 | 现在我们了解到了,执行方式,那我们再来看看,`JS` 是怎么一段一段的执行的。 40 | 41 | ## 执行上下文 42 | 43 | 我们先了解一下执行上下文,执行上下文就是当前 JavaScript 代码被解析和执行时所在环境的抽象概念,JavaScript 中运行任何的代码都是在执行上下文中运行。 44 | 45 | JavaScript 中的运行环境包括三种情况: 46 | 47 | - 全局环境:JavaScript 代码运行首先会进入该环境 48 | - 函数环境:当函数被调用执行时,就会进入该环境 49 | - eval:运行在 eval 函数中的代码创建的自己的执行上下文(不建议使用,基本上算作是一个作废的东西) 50 | 51 | 举一个小例子,当执行一个函数时,就会进行准备工作,而这个准备工作,专业一点的说法就是执行上下文。 52 | 53 | ## 什么是执行上下文栈? 54 | 55 | 那么函数多了,如何来管理这么多执行上下文呢? 56 | 57 | **所以 JavaScript 引擎创建了执行上下文栈来管理执行上下文**。 58 | 59 | 我们使用一个 `ECStack` 数组,作为执行上下文栈的行为模拟工具。 60 | 61 | 首先,当 `JavaScript` 开始解析执行代码时,先遇到一个**全局代码**,所以在初始化我们的执行栈时,就会向执行上下文栈压入一个全局执行栈(`globalContext`)。 62 | 并且只有整个程序执行结束时,`ECStack` 才会被清空,所以在程序结束之前,`globalContext` 会一直存在于 `ECStack` 的最底部。 63 | 64 | ```javascript 65 | ECStack = []; // 创建 66 | ECStack = [globalContext]; // 压入全局执行栈 67 | ``` 68 | 69 | 我们写一段代码,来测试我们的执行栈。 70 | 71 | ```javascript 72 | function fn1() { 73 | console.log('fn1 code'); 74 | } 75 | function fn2() { 76 | fn1(); 77 | } 78 | function fn3() { 79 | fn2(); 80 | } 81 | fn3(); 82 | ``` 83 | 84 | 当执行函数时,就会创建一个执行上下文,并且压入栈,执行完毕,就会从栈中弹出。我们用数组来模拟栈,所以是先进后出。 85 | 86 | 所以我们来看看时怎么执行栈的吧: 87 | 88 | ```javascript 89 | // 一开始执行时,栈中有全局执行栈 90 | ECStack = [ 91 | globalContext, 92 | ] 93 | // 首先 94 | // fn3() 执行,压入栈 95 | ECStack.push( functionContext); 96 | ECStack = [ 97 | globalContext, 98 | functionContext 99 | ] 100 | 101 | // fn3 函数中 执行了 fn2 102 | ECStack.push( functionContext); 103 | ECStack = [ 104 | functionContext 105 | functionContext, 106 | globalContext 107 | ] 108 | // fn2 函数中执行了 fn1 109 | ECStack.push( functionContext); 110 | ECStack = [ 111 | functionContext, 112 | functionContext, 113 | functionContext, 114 | globalContext 115 | ] 116 | 117 | // fn1 执行完毕 118 | ECStack.pop(); 119 | 120 | // fn2 执行完毕 121 | ECStack.pop(); 122 | 123 | // fn3 执行完毕 124 | ECStack.pop(); 125 | 126 | // 最后就是继续执行 JavaScript 代码,知道全部执行完毕,才弹出 globalContext 127 | ``` 128 | 129 | 深入执行上下文栈,就介绍到这里了。 130 | -------------------------------------------------------------------------------- /article/面试题目/CSS/1. css常见面试题-1.md: -------------------------------------------------------------------------------- 1 | # css 面试题汇总 2 | 3 | ## 1. flex 布局 4 | 5 | - 创建 6 | 父元素属性设置 `display: flex`. 7 | 8 | **父属性** 9 | 10 | - flex-direction 更改主轴方向 11 | - flex-wrap 是否换行 12 | - flex-flow 是 flex-direction flex-wrap 的缩写 13 | - justify-content 在主轴上的布局 14 | - align-items 在交叉轴上的布局 15 | - align-content 多行在交叉轴上的布局 16 | 17 | **子元素属性** 18 | 19 | - order 定义项目的顺序,数值越小,排在越前 20 | - flex-grow 放大比例,默认 `0` 21 | - flex-shrink 压缩比例,默认 `1` 22 | - flex-basis 分配多余空间之前,项目占据的主轴空间 23 | - flex 是 flex-grow flex-shrink flex-basis 的缩写 24 | - align-self 可以设置单个子项目在交叉轴上的布局 25 | 26 | ## 2. img 中 title 和 alt 的区别 27 | 28 | - alt 是在图片不能正常显示时出现的文本提示 29 | - title 是鼠标移动在图片上面是,显示的文本 30 | 31 | ## 3. CSS 创建一个三角形 32 | 33 | 原理其实也很简单,就是不设置我们容器宽度,只设置边框,就会进行挤压,然后我们让三条边框的颜色呈现透明,就会出现三角形。 34 | 35 | ```css 36 | .box { 37 | width: 0; 38 | heigth: 0; 39 | border: 40px solid transparent; 40 | border-bottom: 40px solid red; 41 | } 42 | ``` 43 | 44 | ## 4. CSS 盒子模型 45 | 46 | 可以看看,我写的 `css` 文章 [1. 盒模型]() 47 | 48 | 设置通过 box-sizing 49 | 50 | - 标准模型(默认值 content-box):元素宽度 = 内容宽度(content) +border+padding 51 | - IE 模型(border-box):元素宽度 = 内容宽度(content+border+padding) 52 | 53 | ## 5. 如何让一个 div 水平居中 54 | 55 | - block 元素 ,添加 margin:0 auto 属性。 56 | - 已知宽度,绝对定位的居中 ,上下左右都为 0,margin:auto 57 | - 相对定位或绝对定位 left: 50%, tranform: translateX(-50%),偏移回内部元素宽度的 50% 58 | - flex 布局 jusitify-content: center 59 | 60 | ## 6. div 垂直居中 61 | 62 | - block line-height 同高度 63 | - 相对定位或绝对定位 top: 50% , tranfrom: translateY(-50%) ,偏移回内部元素高度的 50% 64 | - flex 布局 align-items: center 65 | 66 | ## 7. display:none 和 visibility: hidden 的区别 67 | 68 | - `display: none` 隐藏对应的元素,在文档布局中不再给它分配空间 69 | - `visibility: hidden` 隐藏对应的元素,但是在文档布局中仍保留原来的空间 70 | 71 | ## 8. link 和 @import 区别 72 | 73 | - link 属于 HTML 标签,而 @import 是 CSS 提供的 74 | - 页面被加载的时,link 会同时被加载,而 @import 引用的 CSS 会等到页面被加载完再加载 75 | - import 只在 IE5 以上才能识别,而 link 无兼容问题 76 | - link 方式的权重高于 @import 的权重. 77 | 78 | ## 9. position 的 absolute 与 fixed 共同点与不同点 79 | 80 | - 相同:改变行内元素的呈现方式,display 被置为 block 让元素脱离普通流,不占据空间 默认会覆盖到非定位元素上 81 | - 不同: absolute 的”根元素“是可以设置的 fixed 的”根元素“固定为浏览器窗口。当你滚动网页,fixed 元素与浏览器窗口之间的距离是不变的 82 | 83 | ## 10. css 优先级 84 | 85 | - !importtant(无穷大) > 行内样式(10000) > id 选择器(1000) > class/伪类/属性(100) > 标签选择器/伪元素(10) > 通配符(1) 86 | - 行内样式 > 内联样式 & 外联样式 87 | 88 | ## 11. 清浮动 89 | 90 | - clear: both 91 | - 给浮动元素的父级设置高度 92 | - 父级同时浮动 93 | - 父级设置成 inline-block,其 margin: 0 auto 居中方式失效 94 | - 给父级添加 overflow:hidden 清除浮动方法 95 | - 万能清除法 after 伪类 清浮动(现在主流方法,推荐使用) 96 | 97 | ```css 98 | float_div:after { 99 | content: '.'; 100 | clear: both; 101 | display: block; 102 | height: 0; 103 | overflow: hidden; 104 | visibility: hidden; 105 | } 106 | ``` 107 | 108 | ## 12. 让元素消失的方法 109 | 110 | - opacity:0 透明化元素,不改变布局,能触发响应事件 111 | - visibility:hidden 隐藏对应的元素,不改变布局,但是不会触发该元素已经绑定的事件 112 | - display: none 隐藏元素,并且会改变页面布局 113 | - z-index: -1 其实就是让该元素覆盖在其他元素的下层,做到隐藏 114 | 115 | -------------------------------------------------------------------------------- /article/CSS/1. 盒模型.md: -------------------------------------------------------------------------------- 1 | # 盒模型 2 | 3 | ## 标准模型+IE 模型 4 | 5 | 盒模型又称框模型,包含了内容(`content`)、内边距(`padding`)、边框(`border`)、外边距(`margin`)四个要素。 6 | 具体排布如下图所示。 7 | 8 | ![box-model1](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/box-model/box-model1.png) 9 | 10 | 盒模型分为两种 11 | 12 | - 标准模型 13 | - IE 模型 14 | 15 | ## 两种盒模型区别 16 | 17 | 两种模型的**内容宽高计算方式不同** 18 | 19 | - IE 模型元素宽度 `width = content + padding + border`,高度类似宽度计算。 20 | 21 | ![box-model2](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/box-model/box-model2.png) 22 | 23 | - 标准模型元素宽度 `width = content`,高度类似宽度计算。 24 | 25 | ![box-model3](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/box-model/box-model3.png) 26 | 27 | ## 两种模型的宽和高 28 | 29 | 通过 `css3` 新增的属性 `box-sizing` 可以设置盒模型类型。**在不设置 `box-sizing` 的情况下,默认为 `content-box`**。 30 | 31 | - 标准模型 - `content-box` 32 | 33 | ```css 34 | .content-box { 35 | box-sizing: content-box; 36 | width: 100px; 37 | height: 100px; 38 | border: 5px solid #1890ff; 39 | padding: 10px; 40 | margin: 15px; 41 | } 42 | ``` 43 | 44 | ![box-model4](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/box-model/box-model4.png) 45 | 46 | `content-box `设置为标准模型,从图上看,我们就可以知道,我们设置的 `width` 属性,指的是 `content` 的宽度。所以我们来计算元素宽度: `content-width + 2 * border + 2 * padding = 130px`。 47 | 48 | - IE 模型 - `border-box` 49 | 50 | ```css 51 | .border-box { 52 | box-sizing: border-box; 53 | width: 100px; 54 | height: 100px; 55 | border: 5px solid #1890ff; 56 | padding: 10px; 57 | margin: 15px; 58 | } 59 | ``` 60 | 61 | ![box-model5](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/box-model/box-model5.png) 62 | 63 | `.border-box` 设置为 `IE` 模型,从上图看,我们就可以知道,它的元素宽度为 `content-width + 2 * padding + 2 * border = 70px + 2 * 10px + 2 * 5px = 100px`。所以元素的宽度就是我们设置的 `width: 100px;`。而内容的宽度则是 `width - 2 * padding - 2 * border = 70px`。 64 | 65 | ### 外边距(margin)重叠 66 | 67 | 在使用中,在垂直方向上,有两个外边距重叠时,会合并成一个外边距,高度等于两者中的较大者。 68 | 69 | 需要注意的是,只有在普通文档流中,才会发生合并。行内框、浮动框或绝对定位之间的外边距并不会发生合并。 70 | 71 | ![box-model6](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/box-model/box-model6.png) 72 | 73 | 合并之前,是 `30px`,合并之后以大的值保留,剩下`20`。 74 | 75 | 我们来举个例子。 76 | 77 | ```css 78 | .box { 79 | width: 100px; 80 | height: 100px; 81 | } 82 | .first { 83 | margin-bottom: 100px; 84 | background-color: orange; 85 | } 86 | .second { 87 | margin-top: 50px; 88 | background-color: wheat; 89 | } 90 | ``` 91 | 92 | ```html 93 |
94 |
95 | ``` 96 | 97 | 为了效果明显,我们在这里添加了 `1.5` 个格子的高度,来看看效果,我们就发现了,其实只保留了一个格子的高度。所以验证了外边距合并。 98 | 99 | ![box-model7](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/box-model/box-model7.png) 100 | 101 | 而为什么会这样呢,其实在这里就是创建了一个 [《CSS 系列之 BFC 容器》](),可以在这边文章中去了解 `BFC`。 102 | 103 | 盒模型,在面试中容易遇到,是比较简单但是很重要的知识点。 104 | -------------------------------------------------------------------------------- /article/Git/1. git 命令.md: -------------------------------------------------------------------------------- 1 | # git 常用命令 2 | 3 | ## 新建代码库 4 | 5 | 可以在自己目录下创建一个新的 git 仓库,也可以从远端服务器克隆一个仓库到本地。 6 | 7 | - 在当前目录下创建一个 git 仓库 8 | 9 | ```bash 10 | git init 11 | ``` 12 | 13 | - 新建一个目录,并将其初始化为 git 仓库 14 | 15 | ```bash 16 | # name 表示 新建目录名 17 | git init [name] 18 | ``` 19 | 20 | - 从远程仓库 下载拷贝一个仓库和它的整个代码历史 21 | 22 | ```bash 23 | # url - 拷贝仓库的地址 24 | git clone url 25 | ``` 26 | 27 | ## 添加和删除文件 28 | 29 | 就是将你有改动的文件,添加或删除到本地的暂存区。 30 | 31 | - 添加文件 32 | 33 | ```bash 34 | # filename - 文件位置 35 | # 添加文件 36 | git add [filename] [filename] ... 37 | 38 | # 添加指定目录到暂存区 39 | git add [dir] 40 | 41 | # 添加所有文件到暂存区 42 | git add . 43 | ``` 44 | 45 | - 删除文件 46 | 47 | ```bash 48 | # 删除文件 49 | git rm [filename] [filename] ... 50 | ``` 51 | 52 | ## 代码提交 53 | 54 | 提交就是将代码提交到本地仓库区,并不会直接提交到远端服务器。提交代码也是推送的前提,有提交才会有推送。 55 | 56 | ```bash 57 | # 提交暂存区到仓库区 58 | git commit -m "代码提交信息" 59 | 60 | # 提交暂存区的指定文件 61 | git commit [filename] [filename] ... -m "代码提交信息" 62 | 63 | # 用新的 commit 替换上一次提交 64 | # 如果内容无任何变化,用来改写上一次 commit 的提交信息 65 | git commit --amend -m "新提交信息" 66 | ``` 67 | 68 | ## 推送改动 69 | 70 | 推送,就是用来,将你的本地代码推送到远端服务器,在远端保存。 71 | 72 | ```bash 73 | # branch - 想推送的分支 74 | git push [origin] [branch] 75 | ``` 76 | 77 | ## 分支 78 | 79 | 分支是用来将特性开发绝缘开来。在创建一个仓库的时候, `master` 是**默认的**分支,我们可以作为主分支,在其他分支上完成相对应的功能后,再将分支合并到主分支 `master` 上。可以有效的对项目进行管理,降低出错概率。 80 | 81 | ![image](https://user-images.githubusercontent.com/66205484/145320439-ce0b38e6-bf4e-4fa4-80d8-4bc84b176492.png) 82 | 83 | ```bash 84 | # 创建一个叫做 ‘feat-new’ 的分支,并切换过去 85 | git checkout -b feat-new 86 | 87 | # 切换回主分支 88 | git checkout master 89 | 90 | # 删除新建分支 91 | git branch -d feat-new 92 | 93 | # 推送本地创建的分支到远端仓库,让他人可见 94 | git push origin feat-new 95 | ``` 96 | 97 | ## 更新与合并 98 | 99 | 更新本地仓库,以及将本地数据合并到 `master` ,获取 (`fetch`) 并合并 (`merge`) 远端的改动。 100 | 101 | ```bash 102 | # 更新本地代码 103 | git pull 104 | 105 | # 合并其他分支到当前分支 106 | git merge [branch] 107 | ``` 108 | 109 | 当然,不是每一次的合并都是顺利的,可能会出现冲突,这时候,就需要手动去修改冲突文件并合并冲突。 110 | 111 | ```bash 112 | # 添加 冲突文件,标记为合并成功 113 | git add [filename] [filename] ... 114 | 115 | # 合并之前,可以使用该命令预览差异 116 | git diff [source_branch] [target_branch] 117 | ``` 118 | 119 | ## 标签 120 | 121 | 在开发过程中,是需要标签的,来标记软件发布情况。 122 | 123 | ```bash 124 | # 打标签 125 | # tagID 是标记的提交ID,需要具有唯一性。 126 | git tag 1.0.0 [tagID] 127 | 128 | # 获取提交 ID,查看本地仓库的历史记录 129 | git log 130 | 131 | # 可以添加参数来修改输出 132 | # 只看某个人的记录 133 | git log --author=hzzzzzzzq 134 | 135 | # 每条提交记录只占一行的输出(压缩之后 136 | git log --pretty=oneline 137 | 138 | # 查看哪些文件有变动 139 | git log --name-status 140 | 141 | # 如果这些不够使用,可以查看更多的 git log 信息 142 | git log --help 143 | ``` 144 | 145 | ## 回退 146 | 147 | 有时候,可能在 `commit` 时,发现有错误,或者在 `push` 时,发现 `commit log` 信息错误,不允许提交(当然这是在公司项目配置的情况下才会发生),我们就需要对提交进行回退,去修改错误或者修改 `commit log` 信息。 148 | 149 | 当然,还有命令时是用于版本回退的。 150 | 151 | ```bash 152 | # 回退信息 - 回退一次,数字表示回退次数 153 | git reset HEAD~1 154 | 155 | # 获取服务器上最新的版本历史,并让本地分支指向它 156 | git fetch origin 157 | git reset --hard origin/master 158 | ``` 159 | -------------------------------------------------------------------------------- /article/ES6/5. 函数的扩展.md: -------------------------------------------------------------------------------- 1 | # 函数的扩展 2 | 3 | ## 函数参数默认值 4 | 5 | ### 基本用法 6 | 7 | 我们来介绍一下函数的默认值,在 ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方式。 8 | 9 | 我们先来看看 ES6 之前怎么给函数参数添加默认值 10 | 11 | ```javascript 12 | function add(x, y) { 13 | y = y || 1; 14 | return x + y; 15 | } 16 | console.log(add(1)); // 2 17 | console.log(add(1, 2)); // 3 18 | ``` 19 | 20 | 我们做的是检查 `y` 的值有没有传入,如果没有则会默认被赋值为 `1`。这种方式是有缺点的,如果传入的值为**布尔值 `false`**,那么传入的值会变得无效。**空字符串**也是会有布尔值 `false` 一样的结果。 21 | 22 | 那么现在我们来看看 ES6 允许设置默认值的写法吧 23 | 24 | ```javascript 25 | function add(x = 1, y = 2) { 26 | return x + y; 27 | } 28 | console.log(add()); // 3 29 | console.log(add(3)); // 5 30 | console.log(add(2, 3)); // 5 31 | ``` 32 | 33 | 从上面的代码就可以看到,一眼就可以**判断出参数是否可省略,且写法比 `ES5` 简洁许多** 34 | 35 | > 注意: 36 | > 37 | > - 函数的参数变量是默认声明的,所以不能使用 let 或者 const 再次声明。 38 | > - 参数默认值的位置,必须是在函数的尾部,如果不是在尾部,否则是没法省略的。 39 | 40 | ### **解构赋值与默认值结合使用** 41 | 42 | ```javascript 43 | function add([x, y] = [1, 2]) { 44 | return x + y; 45 | } 46 | ``` 47 | 48 | 来我们还是先用 `add` 函数来举例,上面就是用的数组的解构赋值,可以个传入的数组进行解构赋值,默认解构赋值。 49 | 50 | ### 函数的 length 51 | 52 | 很奇怪吧,函数居然能有 `length`,来我们在这里简单提一下函数的 `length` 是什么。 53 | 54 | ```javascript 55 | console.log(function (x) {}.length); // 1 56 | console.log(function (x = 1) {}.length); // 0 57 | console.log(function (x, y, z = 2) {}.length); // 2 58 | ``` 59 | 60 | 没错,就是这样。它的 `length` 就是函数必须传入的参数,也就是函数的所有参数减去制定了默认值的参数个数。 如果设置了默认值的参数不是尾参数,那么 `length` 属性也不再计入后面的参数了。 61 | 62 | ### 作用域 63 | 64 | --- 65 | 66 | ## rest 参数 67 | 68 | ES6 中引入来 `rest` 参数(形式为 `...变量名` ),用于获取函数的多余参数,替代 `arguments` 对象。 69 | 70 | 我们还是那 `add` 函数来举例吧。 71 | 72 | ```javascript 73 | function add(...values) { 74 | let sum = 0; 75 | for (let num of values) { 76 | sum += num; 77 | } 78 | return sum; 79 | } 80 | console.log(add(1, 2, 3, 4, 5)); // 15 81 | ``` 82 | 83 | 这里就可以看出来,`rest` 参数是做什么用的,使用它之后,参数可以无限传入,不限制定量。 84 | 85 | 函数的 `length` 不包括 `rest` 参数。 86 | 87 | --- 88 | 89 | ## 箭头函数 90 | 91 | ### 基本使用 92 | 93 | 我们来看看 ES6 中增加的箭头函数( `=>` ),来我们还是用 `add` 函数来举例子, 94 | 95 | ```javascript 96 | function add(a, b) { 97 | return a + b; 98 | } 99 | 100 | // 等价于 101 | const add = (a, b) => { 102 | return a + b; 103 | }; 104 | ``` 105 | 106 | 来看看更简单的写法 107 | 108 | ```javascript 109 | function multiply(n) { 110 | return n * n; 111 | } 112 | // 等价于 113 | const multiply = (n) => n * n; 114 | ``` 115 | 116 | 有时候 `return` 可以省略。 117 | 118 | 当然,箭头函数可以**嵌套**使用,会大大增加代码量 119 | 120 | ```javascript 121 | function add(x) { 122 | return function (y) { 123 | return function (z) { 124 | return x + y + z; 125 | }; 126 | }; 127 | } 128 | ``` 129 | 130 | 上面是普通的写法,然后我们来看一下箭头函数的写法 131 | 132 | ```javascript 133 | const add = (x) => (y) => (z) => x + y + z; 134 | ``` 135 | 136 | 对比一下,应该就知道啦,两种的写法简便程度差别真的很大。 137 | 138 | ### 注意点 139 | 140 | 在这里,稍微提一下箭头函数的相关注意点: 141 | 142 | - 箭头函数没有自己的 `this` 对象 143 | - 不可以当作构造函数,即不可使用 `new` 命令 144 | - 不可以使用 `arguments` 对象,不存在该对象,但是可以使用 `rest` 参数代替 145 | - 不可以使用 `yield` 命令,因此箭头函数不能使用 `Generator` 函数 146 | 147 | 在这里不特点讲述,如果想要具体了解,可以看一下我的另一篇文章[Javasctip - this 指向](),文章后续补齐。 148 | -------------------------------------------------------------------------------- /article/CSS/3. BFC.md: -------------------------------------------------------------------------------- 1 | # BFC 2 | 3 | ## 什么是 BFC? 4 | 5 | `BFC` 即 `Block Formatting Contexts` (块级格式化上下文),它属于定位方案中的普通流。 6 | 7 | 我们可以把具有 `BFC` 特性的元素看作为**隔离了的独立容器**,容器内的元素不会在布局上影响到外面的元素,并且 BFX 具有普通容器所没有的一些特性。 8 | 9 | 简单来说,就是 `BFC` 有一个自己的空间,在空间内怎么做,都不会影响外面。 10 | 11 | ## BFC 原理 12 | 13 | - `BFC` 元素垂直方向的边距会发生重叠,属于不同 `BFC` 的外边距不会发生重叠。 14 | - `BFC` 区域不会与浮动元素的布局重叠。 15 | - `BFC` 元素是一个独立的容器,外面的元素不会影响到内部元素,同样,内部元素也不会影响外部元素。 16 | - 浮动元素也会参与 `BFC` 高度的计算。 17 | 18 | ## 触发 BFC 19 | 20 | 只要元素满足下面任一条件即可出发 BFC 特性 21 | 22 | - `body` 根元素 23 | - 浮动元素: `float` 除 `none` 以外的值 24 | - 绝对定位元素:`position` 的 `absolute` 和 `fixed` 25 | - `display` 为 `inline-block`、`table-cells`、`flex` 26 | - `overflow` 除了 `visible` 之外的值 (如:`hidden`、`auto`、`scroll`) 27 | 28 | ## BFC 特性及应用 29 | 30 | **1. 同一个 BFC 下外边距会发生折叠** 31 | 32 | ```css 33 | .box { 34 | width: 100px; 35 | height: 100px; 36 | } 37 | .first { 38 | margin-bottom: 100px; 39 | background-color: orange; 40 | } 41 | .second { 42 | margin-top: 50px; 43 | background-color: wheat; 44 | } 45 | ``` 46 | 47 | ```html 48 | 49 |
50 |
51 | 52 | ``` 53 | 54 | ![BFC1](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/BFC/BFC1.png) 55 | 56 | 从结果来看,两个 `div` 元素都处在同一个 `BFC` 容器下,也就是 `body` 根元素。所以 `first` 的下边距与 `second` 的上边距发生重叠,且保留大的值。所以两个元素之间的距离只有 `100px`,而不是 `150px`。 57 | 58 | 我们想要两个盒子不进行折叠,这时候只需要将两个盒子设置为 `BFC` 容器就可以了。 59 | 60 | ```css 61 | .container { 62 | overflow: hidden; 63 | } 64 | .box { 65 | width: 100px; 66 | height: 100px; 67 | } 68 | .first { 69 | margin-bottom: 100px; 70 | background-color: orange; 71 | } 72 | .second { 73 | margin-top: 50px; 74 | background-color: wheat; 75 | } 76 | ``` 77 | 78 | ```html 79 |
80 |
81 | ``` 82 | 83 | BFC2 84 | 85 | 这时候,两个盒子的垂直边距就变成了 `150px`。 86 | 87 | **2. BFC 可以包含浮动的元素(清除浮动)** 88 | 89 | 浮动的元素会脱离标准文档流,我们看一个不设置 `BFC` 是的例子。 90 | 91 | ```css 92 | .box { 93 | border: 2px solid #999; 94 | width: 200px; 95 | } 96 | .child { 97 | width: 100px; 98 | height: 100px; 99 | float: left; 100 | background-color: orange; 101 | } 102 | ``` 103 | 104 | ```html 105 |
106 |
107 |
108 | ``` 109 | 110 | 我们来看看显示效果,这时候 `box` 容器没有出发 `BFC`,显示时 `child` 是有浮动起来的,脱离文档流。 111 | 112 | ![BFC3](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/BFC/BFC3.png) 113 | 114 | 由于 `child` 元素浮动,脱离了文档流,所以容器只剩下 `4px` 的高度。 115 | 116 | 现在我们让 `box` 触发 `BFC`,这时候就会将浮动元素包裹起来。 117 | 118 | ```css 119 | .box { 120 | border: 2px solid #999; 121 | width: 200px; 122 | overflow: hidden; 123 | } 124 | ``` 125 | 126 | ![BFC4](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/BFC/BFC4.png) 127 | 128 | 我们看到,我们给 `box` 容器设置 `overflow: hidden` 触发 `BFC`,将浮动元素也包裹进 `box` 元素,清除了浮动效果。 129 | -------------------------------------------------------------------------------- /article/ES6/12. Module 语法.md: -------------------------------------------------------------------------------- 1 | # Module 语法 2 | 3 | ## 概述 4 | 5 | 在 ES 6 之前,社区制定了一些模块加载方案,最主要的就是 [`CommonJS`]() 和 AMD 两种。前者主要用于服务器,后者用于浏览器。ES 6 在语言层面上实现了模块功能,可以取代 [`CommonJS`]() 和 AMD 规范,成为了通用的模块解决方案。 6 | 7 | ## 基本使用 8 | 9 | `module` 主要由 `export` 和 `import` 两个命令。`export` 命令用于规定模块的对外接口,`import` 命令用于输入其他模块功能。 10 | 每一个模块都是一个独立文件,文件内的所有变量,外部无法获取,如果希望在外部获取,就必须使用 `export` 命令进行输出。 11 | 我们创建一个 `export.js` 文件,来写 `export` 相关内容,`import.js` 作为 `import` 导入相关内容。 12 | 13 | ### export 命令 14 | 15 | 先看看 `export` 命令的写法。 16 | 17 | ```javascript 18 | // export.js 19 | export const name = 'hzzzzzzzq'; 20 | export const age = 18; 21 | export const height = 1.78; 22 | ``` 23 | 24 | 上面是一种每一个都导出的写法,也可以看一下另外一种写法,使用一起导出的方式。 25 | 26 | ```javascript 27 | // export.js 28 | const name = 'hzzzzzzzq'; 29 | const age = 18; 30 | const height = 1.78; 31 | export { name, age, height }; 32 | ``` 33 | 34 | 两种写法是相同的。 35 | 当然 export 命令肯定不只是只能导出变量,还可以导出函数或者类。 36 | 来看看函数导出吧,还是用老朋友 `add` 来看吧。 37 | 当然, function 和 class 的输出,必须使用这样的格式。 38 | 39 | ```javascript 40 | // export.js 41 | export function add(x, y) { 42 | return x + y; 43 | } 44 | 45 | // 或者 46 | function add(x, y) { 47 | return x + y; 48 | } 49 | export { add }; 50 | ``` 51 | 52 | 在导出的时候,需要注意的是,**导出的变量必须与模块内部的变量建立一一对应关系**。 53 | 54 | ### import 命令 55 | 56 | 使用 `import` 命令导入 `export.js` 文件,然后打印。 57 | 58 | ```javascript 59 | // import.js 60 | import { name, age, height, add } from './export.js'; 61 | console.log(name, age, height); 62 | // hzzzzzzzq 18 1.78 63 | console.log(add(1, 2)); // 3 64 | ``` 65 | 66 | 如果想要自己重新命名,在 `import` 时,要使用 `as` 关键字,比如我将 `add` 改为 `sum`。 67 | 68 | ```javascript 69 | import { add as sum } from './export.js'; 70 | ``` 71 | 72 | 需要注意的是 73 | 74 | - `import` 命令具有提升效果,会提升到整个模块的顶部,首先执行。 75 | - `import` 是静态执行,不可以使用表达式或者变量 76 | - 多次重复执行同一句 `import` ,那么只会执行一次,不会多次执行。 77 | 78 | ```javascript 79 | console.log(add(1, 2)); // 3 80 | import { add } from './export.js'; 81 | import { name } from './export.js'; // 与上一句相同 82 | // 等同于 83 | import { add, name } from './export.js' 84 | 85 | import { 'a' + 'dd'} from './export.js'; // 报错 86 | ``` 87 | 88 | ### 模块的整体加载 89 | 90 | 导入时,除了一个一个的导入,还有一种整体导入方式,就是使用( `*` )来指定一个对象。 91 | 92 | 我们来看看刚刚的全部导入方式。 93 | 94 | ```javascript 95 | import * as all from './export.js'; 96 | 97 | console.log(all.name, all.age, all.height); // hzzzzzzzq 18 1.78 98 | console.log(all.add(1, 2)); // 3 99 | ``` 100 | 101 | 这种方式,模块整体加载所在的那个对象,也就是 `all` 对象。 102 | 103 | ### export default 命令 104 | 105 | 导出还有一种 `export default` 命令,这种导出方式就是指定默认输出。 106 | 107 | ```javascript 108 | // export.js 109 | // 例子 类 110 | export default class () { ... } 111 | 112 | // 或者 113 | // 例子 函数 114 | export function (x, y) { 115 | return x + y; 116 | } 117 | ``` 118 | 119 | 这种导出方式,不需要固定的名称,来对应,可以直接使用匿名类或匿名函数,也可以不用匿名,但是导出时,都是可以任意命名。 120 | 121 | 导入时不需要使用 `{}` 来包裹,可以直接命名,使用任何名称命名导入。 122 | 123 | ```javascript 124 | // 例子 类 125 | import Obj from './export.js'; 126 | let obj = new Obj(); 127 | 128 | // 或者 129 | // 例子 函数 130 | import add from './export.js'; 131 | console.log(add(1, 2)); 132 | ``` 133 | 134 | ## 总结 135 | 136 | 在正常开发当中,最常使用的一些 `export` 、`improt` 以及一些 `export default` 的方法。 137 | -------------------------------------------------------------------------------- /article/ES6/11. 三种异步之async函数.md: -------------------------------------------------------------------------------- 1 | # Async/await 2 | 3 | ## 介绍 4 | 5 | `async` 函数时什么,其实就是 `Generator` 的语法糖,只需要将 `*` 改写成 `async`,`yield` 改写成 `await`。 6 | 我们来看看 `Generator` 的写法,与 `async` 的写法。 7 | 8 | ```javascript 9 | const readFile = function (fileName, ms) { 10 | return new Promise((resolve, reject) => { 11 | setTimeout(() => { 12 | console.log(fileName); 13 | resolve(fileName); // 需要给 `Promise` 一个状态转化,就是异步执行是否成功 14 | }, ms); 15 | }); 16 | }; 17 | 18 | function* genator() { 19 | yield readFile('fileName1', 1000); 20 | yield readFile('fileName2', 2000); 21 | yield readFile('fileName3', 3000); 22 | console.log('打印完毕'); 23 | } 24 | const gen = genator(); 25 | gen.next(); // fileName1 26 | gen.next(); // fileName2 27 | gen.next(); // fileName3 28 | 29 | async function asyncTest() { 30 | await readFile('fileName1', 1000); 31 | await readFile('fileName2', 2000); 32 | await readFile('fileName3', 3000); 33 | console.log('执行完毕'); 34 | } 35 | asyncTest(); 36 | // fileName1 37 | // fileName2 38 | // fileName3 39 | // 执行完毕 40 | ``` 41 | 42 | 从上面我们可以看出,我们需要手动调用 `next` 方法,来执行下一步。 43 | 而 `async` 有自己内置执行器。 44 | 45 | 我们来看看 `async` 对 `Generator` 的改进。 46 | 47 | - 内置执行器 48 | Generator 函数执行需要 `next` 执行器,外面手动调用,所以有 `co` 模块,而 async 函数自带执行器,与普通函数一样,只需要一行调用。 49 | 下面代码中,调用了该函数之后,就会自动执行,输出最后结果。 50 | 51 | ```javascript 52 | asyncTest(); 53 | ``` 54 | 55 | - 语义更好 56 | `async/await`,比起 `Generator` 函数的 `*` 与 `yield`,语义更清晰。 `async` 就表示异步,而 `await` 表示后面的表达式需要等待结果。 57 | 58 | - 适用性更强 59 | `co` 模块约定,`yield` 后面只能是 `Thunk` 函数或者 `Promise` 对象,而 `await` 后面可以是 `Promise`,也可以是原始类型值。 60 | 61 | - 返回值是 `Promise` 62 | `async` 函数返回值是 `Promise` 对象,可以用 `then` 方法来进行下一步操作。 63 | `await` 命令就是内部 `then` 命令的语法糖。 64 | 65 | ## 用法 66 | 67 | ### 返回 Promise 对象 68 | 69 | - `async` 函数返回一个 `Promise` 对象,可以使用 `then` 方法加入回调函数。 70 | - 执行函数时,遇到 `await` 就会先返回,等异步操作结束,再继续执行函数体后面的语句。 71 | - 必须等到内部所有 `await` 命令后面的 `Promise` 对象执行完毕,状态才会改变,除非遇到 `return` 或者报错。 72 | - `async` 函数内部的异步操作执行完毕,就可以执行 `then` 方法。 73 | - `JS` 没有休眠的语法,但是借助 `await` 命令就可以让程序停顿一定的时间。 74 | 75 | ```javascript 76 | async function useAsync() { 77 | // readFile 使用的是本文顶部的方法 78 | const result = await readFile('fileName', 1000); 79 | return result; 80 | } 81 | useAsync().then((value) => { 82 | console.log(value); 83 | }); 84 | // fileName 85 | // fileName 86 | ``` 87 | 88 | - 如果返回 `reject` 状态,则会中断执行,并通过 `catch` 捕获 89 | 90 | ```javascript 91 | async function useAsync() { 92 | // readFile 使用的是本文顶部的方法 93 | const result = await Promise.reject('测试错误'); 94 | console.log('打印?'); 95 | return result; 96 | } 97 | useAsync() 98 | .then((value) => { 99 | console.log(value); 100 | }) 101 | .catch((error) => { 102 | console.log(error); 103 | }); 104 | // 测试错误 105 | ``` 106 | 107 | ### await 命令 108 | 109 | `await` 命令后面是一个 `Promise` 对象,返回结果。如果不是 `Promise`,就直接返回对应值。 110 | 111 | - `await` 命令只能出现在 `async` 命令函数内部,不然会报错。 112 | 113 | ```javascript 114 | const add = (a, b) => { 115 | return a + b; 116 | }; 117 | async function useAsync() { 118 | const result = await add(1, 2); 119 | return result; 120 | } 121 | useAsync().then((value) => { 122 | console.log(value); 123 | }); 124 | // 3 125 | ``` 126 | 127 | `await` 后面跟着 `add` 方法,算出一个数值 `3`,然后将值 `return` 出来。 128 | 129 | --- 130 | 131 | 简单的 `await` 使用方法,就是如此。 132 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Blog 2 | 3 | 这里是我记录博客的地方,现在已有内容, ES 6 的基础教程、git 基础相关教学,以及实战。 4 | 5 | 也可以去我的个人网站观看 [点击这里进入!!!](https://hzzzzzzzq.github.io/) 6 | 7 | ## 个人博客搭建 8 | 9 | 1. [Hexo + GithubPages + NexT 主题快速搭建个人网站](https://github.com/hzzzzzzzq/Blog/issues/38) 10 | 11 | 2. [Hexo 各类配置项](https://github.com/hzzzzzzzq/Blog/issues/39) 12 | 13 | 3. [NexT 主题功能(阅读时间、浏览量、看板娘、打赏等各类功能)](https://github.com/hzzzzzzzq/Blog/issues/40) 14 | 15 | 4. [Hexo - NexT 主题下配置 gitalk/Disqus 评论系统](https://github.com/hzzzzzzzq/Blog/issues/41) 16 | 17 | ## Git 系列 18 | 19 | 1. [Git 系列之Git 命令](https://github.com/hzzzzzzzq/Blog/issues/15) 20 | 21 | 2. [Git 系列之Git 实战](https://github.com/hzzzzzzzq/Blog/issues/16) 22 | 23 | 3. [Git 系列之Git格式化 commit log](https://github.com/hzzzzzzzq/Blog/issues/17) 24 | 25 | ## ES 6 系列 26 | 27 | 1. [ES 6 系列之了解ES 6](https://github.com/hzzzzzzzq/Blog/issues/2) 28 | 29 | 2. [ES 6 系列之let 和 const 命令](https://github.com/hzzzzzzzq/Blog/issues/3) 30 | 31 | 3. [ES 6 系列之变量的解构赋值](https://github.com/hzzzzzzzq/Blog/issues/4) 32 | 33 | 4. [ES 6 系列之字符串的扩展](https://github.com/hzzzzzzzq/Blog/issues/5) 34 | 35 | 5. [ES 6 系列之函数的扩展](https://github.com/hzzzzzzzq/Blog/issues/6) 36 | 37 | 6. [ES 6 系列之数组的扩展](https://github.com/hzzzzzzzq/Blog/issues/7) 38 | 39 | 7. [ES 6 系列之对象的扩展](https://github.com/hzzzzzzzq/Blog/issues/8) 40 | 41 | 8. [ES 6 系列之Set 和 Map](https://github.com/hzzzzzzzq/Blog/issues/9) 42 | 43 | 9. [ES 6 系列之三种异步之Promise 对象](https://github.com/hzzzzzzzq/Blog/issues/10) 44 | 45 | 10. [ES 6 系列之三种异步之Generator函数](https://github.com/hzzzzzzzq/Blog/issues/11) 46 | 47 | 11. [ES 6 系列之三种异步之async](https://github.com/hzzzzzzzq/Blog/issues/12) 48 | 49 | 12. [ES 6 系列之Module 语法](https://github.com/hzzzzzzzq/Blog/issues/13) 50 | 51 | ## CSS 系列 52 | 53 | 1. [CSS 系列之盒模型](https://github.com/hzzzzzzzq/Blog/issues/24) 54 | 55 | 2. [CSS 系列之CSS选择器](https://github.com/hzzzzzzzq/Blog/issues/25) 56 | 57 | 3. [CSS 系列之BFC](https://github.com/hzzzzzzzq/Blog/issues/26) 58 | 59 | 4. [CSS 系列之position](https://github.com/hzzzzzzzq/Blog/issues/27) 60 | 61 | 5. [CSS 系列之flex](https://github.com/hzzzzzzzq/Blog/issues/28) 62 | 63 | 6. [CSS 系列之css 优先级](https://github.com/hzzzzzzzq/Blog/issues/29) 64 | 65 | 7. [CSS 系列之双飞翼/圣杯布局](https://github.com/hzzzzzzzq/Blog/issues/34) 66 | 67 | 8. [CSS 系列之div 居中](https://github.com/hzzzzzzzq/Blog/issues/35) 68 | 69 | 9. [CSS 系列之css3 新特性](https://github.com/hzzzzzzzq/Blog/issues/36) 70 | 71 | 10. [CSS 系列之float](https://github.com/hzzzzzzzq/Blog/issues/37) 72 | 73 | ## JavaScript 深入系列 74 | 1. [深入理解 JavaScript 系列(1):原型与原型链](https://github.com/hzzzzzzzq/Blog/issues/42) 75 | 76 | 2. [深入理解 JavaScript 系列(2):执行上下文栈](https://github.com/hzzzzzzzq/Blog/issues/43) 77 | 78 | 3. [深入理解 JavaScript 系列(3):变量对象](https://github.com/hzzzzzzzq/Blog/issues/44) 79 | 80 | 4. [深入理解 JavaScript 系列(4):作用域链](https://github.com/hzzzzzzzq/Blog/issues/45) 81 | 82 | 5. [深入理解 JavaScript 系列(5):this](https://github.com/hzzzzzzzq/Blog/issues/46) 83 | 84 | 6. [深入理解 JavaScript 系列(6):执行上下文](https://github.com/hzzzzzzzq/Blog/issues/47) 85 | 86 | 7. [深入理解 JavaScript 系列(7):闭包](https://github.com/hzzzzzzzq/Blog/issues/48) 87 | 88 | 8. [深入理解 JavaScript 系列(8):call和apply函数](https://github.com/hzzzzzzzq/Blog/issues/49) 89 | 90 | 9. [深入理解 JavaScript 系列(9):bind函数](https://github.com/hzzzzzzzq/Blog/issues/50) 91 | 92 | 10. [深入理解 JavaScript 系列(10):new操作](https://github.com/hzzzzzzzq/Blog/issues/51) 93 | 94 | 95 | ## 待补充 。。。。。。。。静待后续。。。。。。。。。。 96 | -------------------------------------------------------------------------------- /article/JavaScript/6. JavaScript深入之执行上下文.md: -------------------------------------------------------------------------------- 1 | # JavaScript 深入之执行上下文 2 | 3 | 在[《JavaScript 深入之执行上下文栈》]()中提到,当 JavaScript 代码执行代码时,就会创建一个执行上下文。 4 | 5 | 对于执行上下文,都有三个重要属性: 6 | 7 | - 变量对象 (Variable Object - VO) 8 | - 作用域链 9 | - this 10 | 11 | 分别单独介绍了三个属性 - [《JavaScript 深入之变量对象》]()、[《JavaScript 深入之作用域链》]()、[《JavaScript 深入之 this》]()。 12 | 13 | 我们在上面的文章中,不止一次提到过执行上下文这个东西,然后每次都是分开介绍的,并不完全,现在我们就来整合一下执行上下文吧。 14 | 15 | ## 执行上下文 - 例子一 16 | 17 | 我们直接给出一个例子吧,然后来看看什么是执行上下文吧。 18 | 19 | ```javascript 20 | var name = 'hzq'; 21 | function checkName() { 22 | var name = 'hzzzzzzzq'; 23 | function fn() { 24 | return name; 25 | } 26 | return fn(); 27 | } 28 | console.log(checkName()); // hzzzzzzzq 29 | ``` 30 | 31 | ### 执行过程 32 | 33 | **1. 执行全局代码,创建全局上下文,并压入执行上下文栈** 34 | 35 | ```javascript 36 | ECStack = [globalContext]; 37 | ``` 38 | 39 | **2. 全局上下文初始化,同时创建 `checkName` 函数,保存作用域链到函数内部属性 `[[scope]]`** 40 | 41 | ```javascript 42 | globalContext = { 43 | VO: [global], 44 | Scope: [globalContext.VO], 45 | this: globalContext.VO, 46 | }; 47 | checkName.[[scope]] = [ 48 | globalContext.VO 49 | ]; 50 | ``` 51 | 52 | **3. 执行 checkName 函数,创建函数上下文,并压入栈** 53 | 54 | ```javascript 55 | ECStack = [checkNameContext, globalContext]; 56 | ``` 57 | 58 | **4. checkName 函数执行上下文初始化: | 这时候 `fn` 函数也被创建,保存 `[[scope]]`** 59 | 60 | - 复制函数 `[[scope]]` 属性 61 | - arguments 创建活动对象 62 | - 初始化活动对象,加入形参、函数声明、变量声明 63 | - 将活动对象压入函数作用域链顶端 64 | 65 | ```javascript 66 | checkNameContext = { 67 | AO: { 68 | arguments: { 69 | length: 0, 70 | }, 71 | name: undefined, 72 | fn: reference to function fn() {} 73 | }, 74 | Scope: [AO, globalContext.VO], 75 | this: undefined 76 | }; 77 | 78 | // fn 函数保存 [[scope]] 79 | 80 | fn.[[scope]] = [ 81 | checkNameContext.AO, gloablContext.VO 82 | ] 83 | ``` 84 | 85 | **5. 执行 `fn` 函数,创建上下文,压入栈** 86 | 87 | ```javascript 88 | ECStack = [fnContext, checkNameContext, globalContext]; 89 | ``` 90 | 91 | **6. `fn` 函数执行上下文初始化** 92 | 93 | ```javascript 94 | fnContext = { 95 | AO: { 96 | arguments: { 97 | length: 0, 98 | }, 99 | }, 100 | Scope: [AO, checkNameContext.AO, globalContext.VO], 101 | this: undefined, 102 | }; 103 | ``` 104 | 105 | **7. `fn` 通过作用域链查找 `name` 属性,并返回** 106 | 107 | **8. fn 函数指向完毕,出栈** 108 | 109 | ```javascript 110 | ECStack = [checkNameContext, globalContext]; 111 | ``` 112 | 113 | **9. `checkName` 函数执行完毕,出栈** 114 | 115 | ```javascript 116 | ECStack = [globalContext]; 117 | ``` 118 | 119 | **10. 继续执行其他全局代码,直到其他代码执行完毕,全局上下文出栈** 120 | 121 | ## 执行上下文 - 例子二 122 | 123 | ```javascript 124 | var name = 'hzq'; 125 | function checkName() { 126 | var name = 'hzzzzzzzq'; 127 | function fn() { 128 | return name; 129 | } 130 | return fn; 131 | } 132 | checkName()(); // hzzzzzzzq 133 | // 等价于 134 | let fn = checkName(); 135 | fn(); 136 | ``` 137 | 138 | ### 执行过程 - 变化点 139 | 140 | 我们直接来看看例子二与例子一的不同点。 141 | 142 | **5. `checkName` 函数执行完毕,出栈** 143 | 144 | ```javascript 145 | ECStack = [globalContext]; 146 | ``` 147 | 148 | **6. 执行 `fn` 函数,创建上下文,压入栈** 149 | 150 | ```javascript 151 | ECStack = [fnContext, globalContext]; 152 | ``` 153 | 154 | **7. `fn` 函数执行上下文初始化** 155 | 156 | ```javascript 157 | fnContext = { 158 | AO: { 159 | arguments: { 160 | length: 0, 161 | }, 162 | }, 163 | Scope: [AO, checkNameContext.AO, globalContext.VO], 164 | this: undefined, 165 | }; 166 | ``` 167 | 168 | **8. `fn` 函数执行完毕,出栈** 169 | 170 | **9. 执行全局其他代码,执行完毕,全局上下文出栈** 171 | 172 | 是不是很简单呢? 173 | -------------------------------------------------------------------------------- /article/JavaScript/5. JavaScript深入之 this.md: -------------------------------------------------------------------------------- 1 | # JavaScript 深入之 this 2 | 3 | 在[《JavaScript 深入之执行上下文栈》]()中提到,当 JavaScript 代码执行代码时,就会创建一个执行上下文。 4 | 5 | 对于执行上下文,都有三个重要属性: 6 | 7 | - 变量对象 (Variable Object - VO) 8 | - 作用域链 9 | - this 10 | 11 | 我们来介绍一下 this。 12 | 13 | ## this 14 | 15 | 什么是 this 呢?我们可以把 this 的指向当作执行时所指向的执行上下文。在不同的上下文中,this 的确定经常会发生问题。 16 | 17 | this 是执行上下文中的一个属性。 18 | 19 | ```javascript 20 | globalContext = { 21 | VO: {...}, 22 | this: globalContext.VO, 23 | } 24 | ``` 25 | 26 | VO 就是上一节讲到的变量对象了。 27 | 28 | **this 与上下文中可执行代码的类型有直接关系,this 值在进入上下文时确定,并且在上下文运行期间永久不变** 29 | 30 | ## 全局代码中的 this 31 | 32 | 全局代码中的 this 始终是全局对象本身。 33 | 34 | ```javascript 35 | this.a = 1; 36 | console.log(a); // 1 37 | 38 | b = 2; 39 | console.log(this.b); // 2 40 | 41 | var c = 3; 42 | console.log(this.c); // 3 43 | ``` 44 | 45 | 那么全局对象本身是什么呢?在浏览器中就是我们经常使用的 `window`。 46 | 47 | ```javascript 48 | console.log(this); // window 对象 49 | console.log(window); // window 对象 50 | console.log(this === window); // true 51 | ``` 52 | 53 | ## 函数中的 this 54 | 55 | 函数中的 this 是很奇特的,也是很有趣的。它的指向并不是固定的,而且可以通过手动进行修改。 56 | 57 | 我们在上面介绍到,**this 是进入上下文时确定**,所以在一个函数代码中,这个值在每一次完全不同。 58 | 59 | 注意:任何时候不能改变 this 的值。 60 | 61 | ```javascript 62 | let objBind = { value: 2 }; 63 | let obj = { 64 | value: 1, 65 | test: function () { 66 | console.log(this === obj); 67 | console.log(this.value); 68 | // this = objBind; // 报错,任何时候不能改变 this 的值 69 | // console.log(this.value); 70 | }, 71 | }; 72 | 73 | // 我们来执行一下 74 | obj.test(); // true, 1 75 | 76 | objBind.test = obj.test; 77 | 78 | objBind.test(); // false, 2 79 | ``` 80 | 81 | 我们看到结果的结果是不同的。 82 | 发现,指向的结果是不是跟调用它的对象有关呢?事实就是这样,**谁调用就指向谁**。 83 | 84 | 我们使用 `obj` 来调用 `test` 方法时,指向了 `obj`,打印 `true`,而我们将方法赋给 `objBind` 之后,`objBind` 来调用时,指向了 `objBind`。 85 | 86 | 我们来看一下执行 `test` 方法时,`test` 上下文: 87 | 88 | ```javascript 89 | // obj 调用执行 90 | testContext = { 91 | AO: {...}, 92 | this: obj, 93 | }; 94 | // objBind 调用执行 95 | testContext = { 96 | AO: {...}, 97 | this: objBind, 98 | } 99 | ``` 100 | 101 | 通过上下文,我们可以清楚的了解到 `this` 在运行中的指向。 102 | 103 | 我们来看一下还有一种方式,指向了全局对象。 104 | 105 | ```javascript 106 | let test = obj.test; 107 | test(); // false, undefined 108 | ``` 109 | 110 | 这时候执行 test 时的上下文: 111 | 112 | ```javascript 113 | testContext = { 114 | AO: {...}, 115 | this: window 116 | } 117 | ``` 118 | 119 | ## 作为构造函数下的 this 120 | 121 | ```javascript 122 | function Constructor() { 123 | console.log(this); // "a"对象下创建一个新属性 124 | this.value = 1; 125 | } 126 | 127 | let x = new Constructor(); 128 | console.log(x.value); // 1 129 | 130 | // { 131 | // "value": 1 132 | // } 133 | ``` 134 | 135 | ## 函数调用时,手动设置 this 136 | 137 | 在这里就要使用到 `Function.prototype.apply` 或 `Function.prototype.call` 了。 138 | 139 | 在这里也介绍了 `apply` 和 `call` 以及 `bind`,可以看我的这两篇文章 - [《JavaScript 深入之 call 和 apply 函数》]() 与 [《JavaScript 深入之 bind 函数》]() 140 | 141 | ```javascript 142 | let obj = { 143 | value: 1, 144 | }; 145 | function fn(a) { 146 | console.log(this.value); 147 | console.log(a); 148 | } 149 | 150 | fn(2); // undefined, 2 151 | fn.call(obj, 20); // 1, 20 152 | fn.apply(obj, [20]); // 1, 20 153 | ``` 154 | 155 | ## 多言一句 - 箭头函数指向 156 | 157 | 箭头函数的 `this` 指向,不能按照上面的任何一种来。 158 | 159 | 箭头函数的 `this` 指向,**是在定义时决定的,而不是在调用时决定**。 160 | 161 | ```javascript 162 | var value = 1; 163 | let obj = { 164 | value: 2, 165 | test: () => { 166 | console.log(this); // window 对象 167 | console.log(this.value); // 1 168 | }, 169 | }; 170 | // 按照上面的想法,打印出来的应该是 2,而实际打印的是 1 171 | obj.test(); 172 | ``` 173 | -------------------------------------------------------------------------------- /article/JavaScript/7.JavaScript深入之闭包.md: -------------------------------------------------------------------------------- 1 | # 闭包 2 | 3 | ## 介绍 4 | 5 | 闭包,在外面介绍了前面的之后,就可以了解我们的闭包了。 6 | 7 | **概念** 8 | 9 | > 一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域 10 | 11 | 我们先来简单回顾一下执行上下文的第二个例子吧。 12 | 13 | ```javascript 14 | var name = 'hzq'; 15 | function checkName() { 16 | var name = 'hzzzzzzzq'; 17 | return function fn() { 18 | return name; 19 | }; 20 | } 21 | 22 | checkName()(); // hzzzzzzzq 23 | ``` 24 | 25 | 我们这上面这段代码来看一下执行上下文栈和执行上下文的情况。 26 | 27 | 1. 进入全局代码创建全局上下文,`globalContext` 入栈 28 | 2. 全局代码执行 29 | 3. 执行 `checkName` 函数,创建 `checkName` 函数执行上下文,`checkNameContext` 入栈 30 | 4. `checkName` 执行上下文初始化,创建变量对象、作用域链、`this` 等 31 | 5. `checkName` 函数执行完毕,出栈 32 | 6. 执行 `fn` 函数,创建 `fn` 函数执行上下文,`fn` 函数上下文入栈 33 | 7. `fn` 执行上下文初始化,创建变量对象、作用域链、`this` 等 34 | 8. `fn` 函数执行完毕,`fn` 函数上下文弹出 35 | 9. 执行其他全局代码,代码执行完毕,全局上下文弹出 36 | 37 | 我们看这个过程时,发现 `checkName` 函数已经不在执行上下文栈中,为什么还可以取到 `name` 的值呢? 38 | 39 | 从 [《JavaScript 深入之作用域链》]() 中,我们了解到,`fn` 函数,其实维护了一个作用域链,可以看看。 40 | 41 | ```javascript 42 | fnContext = { 43 | Scope: [AO, fnContext.AO, globalContext.VO], 44 | }; 45 | ``` 46 | 47 | 所有,其实 `fn1` 取到的就是上层的函数。就是因为作用域链,实现了父级函数即使被销毁,也可以取到值。 48 | 49 | 我们先举一个简单的闭包使用方式。 50 | 51 | ```javascript 52 | function fn() { 53 | var count = 1; 54 | return function f() { 55 | return ++count; 56 | }; 57 | } 58 | 59 | var fn1 = fn(); 60 | console.log(fn1()); // 2 61 | console.log(fn1()); // 3 62 | console.log(fn1()); // 4 63 | console.log(fn1()); // 5 64 | console.log(fn1()); // 6 65 | ``` 66 | 67 | 我们的执行过程类似,但是在作用域链中保存着值,可以进行修改,也导致了一个问题,也就是内存删除不干净,内存泄露。 68 | 69 | ## 必刷面试题 70 | 71 | 我们来看一道经典的闭包面试题。 72 | 73 | ```javascript 74 | const data = []; 75 | for (var i = 0; i < 5; i++) { 76 | data[i] = function () { 77 | console.log(i); 78 | }; 79 | } 80 | data[2](); // 5 81 | data[3](); // 5 82 | data[4](); // 5 83 | ``` 84 | 85 | 这题是我们经常遇到的题目,为什么打印的全是 `5` 呢? 86 | 87 | 我们来看一下全局上下文中,执行函数之前的 `globalContext`,如果对此有问题,可以去看一下前面的几篇文章。[《JavaScript 深入之执行上下文栈》]()、[《JavaScript 深入之变量对象》]()、[《JavaScript 深入之作用域链》]()、[《JavaScript 深入之 this》]()。 88 | 89 | 我们来看一下上面代码的全局上下文(`globalContext`) 的内容是什么。 90 | 91 | ```javascript 92 | globalContext = { 93 | VO: { 94 | data: [...], // item => function 95 | i: 5 96 | }, 97 | Scope: [globalContext.VO], 98 | } 99 | ``` 100 | 101 | 这样就一定都打印 `5` 了吗? 不是的,我们还需要看看 `data` 中函数的上下文。 102 | 103 | ```javascript 104 | data[0]Context = { 105 | AO: { 106 | arguments: { 107 | length: 0, 108 | }, 109 | }, 110 | Scope: [AO, globalContext.VO], 111 | } 112 | ``` 113 | 114 | 所以,我们在 `data[0]` 函数中没有找到结果 `i`,于是从 `global` 中寻找,于是找到结果为 `5`。 115 | 116 | ```javascript 117 | const data = []; 118 | for (var i = 0; i < 5; i++) { 119 | data[i] = (function () { 120 | return function () { 121 | console.log(i); 122 | }; 123 | })(); 124 | } 125 | data[2](); // 2 126 | data[3](); // 3 127 | data[4](); // 4 128 | ``` 129 | 130 | 这变成了一个立即执行函数。 131 | 132 | 我们在全局上下文的 VO 是没有变化的。 133 | 134 | 但是我们来看看 `data[0]` 函数执行时,其中有一个是匿名函数,我们假设为 `NoName` 函数,我们来看一下 `data[0]` 的上下文 135 | 136 | ```javascript 137 | data[0]Context = { 138 | AO: { 139 | arguments: { 140 | length: 0, 141 | }, 142 | }, 143 | Scope: [AO, NoNameContext.AO, globalContext.VO] 144 | } 145 | ``` 146 | 147 | 在来看看匿名函数的上下文 148 | 149 | ```javascript 150 | NoNameContext = { 151 | AO: { 152 | arguments: { 153 | length: 0, 154 | }, 155 | i: 0, 156 | }, 157 | Scope: [AO, globalContext.VO], 158 | }; 159 | ``` 160 | 161 | 所以,这时候执行时,找到了 `i = 0`,返回结果。 162 | -------------------------------------------------------------------------------- /article/Git/3. 格式化commit命令.md: -------------------------------------------------------------------------------- 1 | # commit 格式化 husky(V7.0.4)让我们的 commit 更规范 2 | 3 | 这里我们来说一下为什么我们做一个 `git commit` 的格式化。 4 | 我们来看看 `commit log` 做格式化之前的样子。 5 | ![1C3B682E-04B3-49C6-8136-0F8288F552D1](https://user-images.githubusercontent.com/66205484/144975728-345548af-e8b2-4b99-aa54-27f41958ed5e.png) 6 | 7 | 我们再来看看 `commit log` 格式化之后的样子。 8 | ![image](https://user-images.githubusercontent.com/66205484/144977548-af392772-7f52-4ec4-8f45-1f9c13300417.png) 9 | 10 | 对比格式化前和格式化后的感觉, 是不是很清晰,也可以让别人看得懂你在做什么,在多人协作开发时,是特别重要的。 11 | 12 | 在开始文章之前,我来说一下我使用的 `node` 和 `npm` 版本。 13 | 14 | > 12.0.1 - macOS Monterey 15 | > 16 | > v16.4.2 - node 17 | > 18 | > 7.24.0 - npm 19 | 20 | ## husky(v7.0.4 21 | 22 | `husky` 是一个可以让配置 `git` 钩子变得更加简单的工具。 23 | 24 | - **首先我们先进行安装 `husky`。** 25 | 26 | ```bash 27 | # 安装 28 | yarn add husky -D 29 | # 或者 30 | npm install husky --save-dev 31 | ``` 32 | 33 | - **安装之后我们需要启动。** 34 | 35 | ```bash 36 | # 启动 37 | npm set-script prepare "husky install" 38 | ``` 39 | 40 | 这时会在 `package.json` 文件中看到下面的代码,说明执行成功。 41 | 42 | ```javascript 43 | "scripts": { 44 | "prepare": "husky install" 45 | } 46 | ``` 47 | 48 | 当然这里可能有人可能会执行下面的命令,并且报错 `set-script` 找不到,改用 `npm` 就可以了。 49 | 50 | ```bash 51 | yarn set-script prepare "husky install" 52 | # error Command "set-script" not found 53 | ``` 54 | 55 | 或者可以直接跳过启动,手动去修改 `package.json` 文件,在 scripts 中添加 `"prepare": "husky install"` 语句,然后执行 `husky install` 命令。 56 | 57 | 执行之后会增加一个 `.husky` 的文件夹。 58 | 59 | ![image](https://user-images.githubusercontent.com/66205484/144980206-a484f643-9116-4c46-92c7-d11ce7d07cd1.png) 60 | 61 | - **安装其他的一些检查规范** 62 | 63 | ```bash 64 | # 安装 lint-staged 65 | yarn add lint-staged -D 66 | # 安装 eslint 67 | yarn add eslint prettier -D 68 | ``` 69 | 70 | 在 `package.json` 文件中需要添加下面的代码 71 | 72 | ```javascript 73 | "lint-staged": { 74 | "src/**/*.{js,jsx,ts,tsx,json}": [ 75 | "prettier --write", 76 | "eslint", 77 | "git add" 78 | ] 79 | }, 80 | ``` 81 | 82 | - 安装 `commitlint` 相关以来 83 | 84 | ```bash 85 | yarn add @commitlint/cli @commitlint/config-conventional -D 86 | ``` 87 | 88 | - 创建 commitlint.config.js 文件, 89 | 90 | ```bash 91 | # 命令创建 92 | echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js 93 | ``` 94 | 95 | 也可以手动创建,然后添加内容。 96 | 97 | ```javascript 98 | module.exports = { 99 | extends: ['@commitlint/config-conventional'], // 以下时我们自定义的规则 100 | rules: { 101 | 'type-enum': [ 102 | 2, 103 | 'always', 104 | [ 105 | 'feat', // 新功能(feature) 106 | 'fix', // 修补 bug 107 | 'docs', // 文档(documentation) 108 | 'style', // 格式(不影响代码运行的变动) 109 | 'refactor', // 重构(即不是新增功能,也不是修改bug的代码变动) 110 | 'test', // 增加测试 111 | 'merge', // 合并分支 112 | ], 113 | ], 114 | }, 115 | }; 116 | ``` 117 | 118 | - 添加 `commit-msg` 和 `pre-commit` 文件 119 | 120 | ```bash 121 | # 添加 commit-msg 122 | yarn husky add .husky/commit-msg 'yarn commitlint --edit "$1"' 123 | # 添加 pre-commit 124 | yarn husky add .husky/pre-commit 'yarn lint-staged --allow-empty "$1"' 125 | ``` 126 | 127 | 这之后我们可以来看看 `.husky` 文件现在的样子 128 | 129 | ![image](https://user-images.githubusercontent.com/66205484/144981602-8c53ab14-4c9c-4340-9a7f-b4dc4f119c2f.png) 130 | 131 | - 最好就是 测试我们的 `git commit` 了 132 | 133 | ```bash 134 | # 添加内容 135 | git add . 136 | # 提交commit 137 | git commmit -m "feat: 优化git commit" 138 | ``` 139 | 140 | - 打印内容 141 | 142 | ![image](https://user-images.githubusercontent.com/66205484/144982485-d2d4ac26-70b6-412e-a58b-5b5f223dcf7a.png) 143 | 144 | 到这里我们就完成啦,当然,如果你的 `commit log` 格式,不符合自己添加的 `rules` 那么就会在 `commit` 时提交失败,这时候就需要你修改 `commit log` 的格式了。 145 | -------------------------------------------------------------------------------- /article/JavaScript/CommandJS.md: -------------------------------------------------------------------------------- 1 | ## 历史 2 | 3 | 历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。而其他语言基本上都有 `import` 导入方式。 4 | 5 | 在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。 6 | 7 | ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。 8 | 9 | ## CommandJS 10 | 11 | `CommandJS` 是服务端 `JavaScript` 的标准规范,主要核心为 `module.exports` 和 `require` ,加载方式是同步的。 12 | 13 | - 单个导出/导入 14 | 15 | ```javascript 16 | // commandJs.js 17 | module.exports.name = 'hzzzzzzzzq'; 18 | module.exports.age = '20'; 19 | module.exports.weight = 178; 20 | ``` 21 | 22 | 我们使用的是 `module.exports` 的导出方式,使用的是单个导出。 23 | 24 | 而我们在导入文件中,可以使用 require 进入导入,然后使用 `info.` 进行调用。 25 | 26 | ```javascript 27 | let info = require('./commandJs.js'); 28 | 29 | console.log(info); 30 | // { name: 'hzzzzzzzzq', age: '20', weight: 178 } 31 | console.log(info.name); // hzzzzzzzzq 32 | console.log(info.age); // 20 33 | console.log(info.weight); // 178 34 | ``` 35 | 36 | - 整体导出/导入 37 | 38 | ```javascript 39 | module.exports = { 40 | info: { 41 | name: 'hzq', 42 | age: '21', 43 | height: '178', 44 | weight: 'noWay', 45 | }, 46 | school: { 47 | name: '大学', 48 | position: '不给', 49 | }, 50 | }; 51 | ``` 52 | 53 | 这样的来取值是可取的 54 | 55 | ```javascript 56 | let info = require('./commandJs.js'); 57 | 58 | console.log(info.info); 59 | // { name: 'hzq', age: '21', height: '178', weight: 'noWay' } 60 | console.log(info.school); 61 | // { name: '大学', position: '不给' } 62 | ``` 63 | 64 | 通常我们会写成下面的样子,结果是一样的。 65 | 66 | ```javascript 67 | let { info, school } = require('./commandJs.js'); 68 | 69 | console.log(info); 70 | // { name: 'hzq', age: '21', height: '178', weight: 'noWay' } 71 | console.log(school); 72 | // { name: '大学', position: '不给' } 73 | ``` 74 | 75 | **循环引用** 76 | 77 | ```javascript 78 | // first.js 79 | module.exports.first = 'first'; 80 | let second = require('./second.js'); 81 | console.log('我是 second 中的内容 ---- ', second); 82 | module.exports.first = 'newFirst'; 83 | ``` 84 | 85 | ```javascript 86 | // second.js 87 | module.exports.second = 'second'; 88 | let first = require('./first.js'); 89 | console.log('我是 first 中的内容 ---- ', first); 90 | module.exports.second = 'newSecond'; 91 | ``` 92 | 93 | ```javascript 94 | // index.js 95 | let info = require('./first.js'); 96 | console.log(info); 97 | // ------- 打印结果如下 -------- 98 | 99 | // 我是 first 中的内容 ---- { first: 'first' } 100 | // 我是 second 中的内容 ---- { second: 'newSecond' } 101 | // { first: 'newFirst' } 102 | ``` 103 | 104 | 运行此段代码结合上面的 `demo`,分析每一步过程: 105 | 106 | 1. `执行 node index.js -> 第一行 require('./first.js')`,( `node` 执行也可以理解为调用了 `require` 方法,我们省略 `require('index.js')` 内容) 107 | 2. 进入 `require('./first.js')` 方法: 判断缓存(无) -> 初始化一个 `module` -> 将 `module` 加入缓存 -> 执行模块 `first.js` 内容,(需要注意 **是先加入缓存, 后执行模块内容**) 108 | 3. `first.js` : 第一行导出 `first = 'first'` ,第二行 `require('./second.js')`( `first.js` 只执行了第一行) 109 | 4. 进入 `require('./second.js')` 内,开始执行 `second.js` 的内容 110 | 5. `second.js` : 第一行导出 `second = 'second'` ,第二行 `require('./first.js')` 111 | 6. `require('./first.js') 此时 a.js 是第二次调用 require -> 判断缓存(有)-> cachedModule.exports -> 回到 b.js`(因为`js`对象引用问题 此时的 `cachedModule.exports = { a: 1 }`) 112 | 7. `second.js` : 第三行输出 `{ first: 'first' }` ,第四行修改 `second = 'newSecond'` ,执行完毕回到 `first.js` 113 | 8. `first.js` : 第三行获取到 `second` 输出 `{ second: 'newSecond' }` ,第四行导出 `first = 'newFirst'` , 执行完毕回到 `index.js` 114 | 9. `index.js` : 获取 `first` 值输出 `{ first: 'newFirst' }` ` 115 | 10. 执行完毕 116 | 117 | 从上面的过程中,我们还可以看出,`CommandJS` 的加载方式是同步的方式。 118 | -------------------------------------------------------------------------------- /article/JavaScript/3. JavaScript深入之变量对象.md: -------------------------------------------------------------------------------- 1 | # JavaScript 深入之变量对象 2 | 3 | 在[《JavaScript 深入之执行上下文栈》]()中提到,当 JavaScript 代码执行代码时,就会创建一个执行上下文。 4 | 5 | 对于执行上下文,都有三个重要属性: 6 | 7 | - 变量对象 (Variable Object - VO) 8 | - 作用域链 9 | - this 10 | 11 | 我们先来介绍一下变量对象。 12 | 13 | ## 变量对象 14 | 15 | 变量对象是与执行上下文相关的数据作用域,存储了在上下文中定义的变量和函数声明。 16 | 17 | 然而,由于不同执行上下文的变量对象都存在不同,所以今天我们分不同模块来聊一下不同的变量对象。 18 | 19 | - 全局上下文的变量对象 20 | 21 | - 函数上下文的变量对象 22 | 23 | ## 全局对象 24 | 25 | 全局上下文中的变量对象就是全局对象。全局变量是在所有作用域都可访问的变量,与之对应的是局部变量 26 | 27 | > 全局对象预定义的对象,作为 JavaScript 的全局函数和全局属性的占位符。通过使用全局对象,可以访问所有其他。 28 | 29 | - 可以通过 `this` 引用,在客户端中,全局对象就是 `Window` 对象,可以通过浏览器查看。 30 | 31 | ```javascript 32 | console.log(this); // window 对象 33 | ``` 34 | 35 | - 全局对象是由 `Object` 构造函数实例化的一个对象。 36 | 37 | ```javascript 38 | console.log(this instanceof Obejct); // true 39 | ``` 40 | 41 | - 全局对象中预定义了一堆函数和属性,比如 `Math` 的一些方法。 42 | 43 | ```javascript 44 | console.log(Math.pow(2, 2)); // 4 45 | ``` 46 | 47 | - 作为全局变量的存储对象。 48 | 49 | ```javascript 50 | var a = 1; 51 | console.log(this.a); // 1 52 | ``` 53 | 54 | - 客户端中,全局对象有 `window` 属性指向自身 55 | 56 | ```javascript 57 | var a = 1; 58 | console.log(window.a); // 1 59 | 60 | this.window.b = 2; 61 | console.log(this.b); // 2 62 | ``` 63 | 64 | ## 函数上下文 65 | 66 | 函数上下文中,`VO` 时不能直接访问的,所以用活动对象(`Activation Object,OA`)来表示变量对象。 67 | 但是其实是一个东西,只不过在变量对象的规范上来说,是有区别的。 68 | `AO` 是在进入函数上下文时才被创建的,它通过 `arguments` 属性来初始化。`arguments` 属性就是 `Argumens` 对象。 69 | 70 | `Arguments` 对象是 `AO` 对象的一个属性,它包括如下属性: 71 | 72 | - `callee` - 指向参数所属的当前执行的函数,指向调用当前函数的函数 73 | - `length` - 传递给函数的参数数量 74 | - `arguments[@@iterator]` - 返回一个新的 Array 迭代器对象,该对象包含参数中每个索引的值 75 | 76 | ## 执行过程 77 | 78 | 执行上下文,会分为两个阶段,分析阶段和执行阶段。 79 | 80 | - 进入执行上下文 81 | - 执行代码 82 | 83 | ### 分析阶段 84 | 85 | 当进入分析阶段时,这时候还没有执行代码。 86 | 87 | 变量对象包括: 88 | 89 | - 函数的所有形参 (如果是函数上下文) 90 | 由名称和对应值组成的一个变量对象的属性被创建,属性值为 undefined 91 | 92 | - 函数声明 93 | 由名称和对应值(函数对象)组成一个变量对象的属性被创建,如果变量对象已经存在相同名称的属性,则完全替换这个属性 94 | 95 | - 变量声明 96 | - 由名称和对应值(`undefined`)组成一个变量对象的属性被创建 97 | - **如果变量对象名称跟已经声明的形式参数或函数相同,则声明变量不会干扰已经存在的这类属性** 98 | 99 | 我们来举个例子 100 | 101 | ```javascript 102 | function fn(age) { 103 | var name = 'hzzzzzzzq'; 104 | function fn2() {} 105 | var fn3 = function () {}; // 其实也算是一个变量 106 | 107 | name = 'hzq'; 108 | } 109 | 110 | fn(18); 111 | ``` 112 | 113 | 我们来看看进入执行上下文的分析阶段的 AO 是 114 | 115 | ```javascript 116 | AO = { 117 | // 函数的形参 118 | arguments: { 119 | 0: 1, 120 | length: 1, 121 | }, 122 | age: 18, 123 | name: undefined, // 变量声明 124 | fn2: reference to function fn2() {}, // 函数声明 125 | fn3: undefined // 变量声明 126 | }; 127 | ``` 128 | 129 | ### 执行阶段 130 | 131 | 在代码执行阶段中,会顺序来执行代码,根据代码,修改变量对象的值。 132 | 133 | 我们将上面的代码执行完毕后,来看看 AO : 134 | 135 | ```javascript 136 | AO = { 137 | arguments: { 138 | 0: 1, 139 | length: 1, 140 | }, 141 | age: 18, 142 | name: 'hzq', 143 | fn2: reference to function fun2() {}, 144 | fn3: reference to FunctionExpression "fn3" 145 | }; 146 | ``` 147 | 148 | 其实到目前为止,我们的介绍已经结束了。但是肯定不过瘾,或许还不太懂,所以我们... 149 | 150 | ## 再来个例子 151 | 152 | 再来看个例子吧。 153 | 154 | ```javascript 155 | function fn1() { 156 | console.log(x); 157 | x = 1; 158 | } 159 | fn1(); 160 | 161 | function fn2() { 162 | x = 1; 163 | console.log(x); 164 | } 165 | fn1(); 166 | ``` 167 | 168 | 可以来看看上面的代码,打印的是什么呢? 169 | 第一个打印 `Uncaught ReferenceError: x is not defined` 170 | 第二个打印 `1` 171 | 172 | 这又是为什么呢? 173 | 174 | 第一个例子中,我们来看看执行上下文时的 `AO`,因为我们在创建时 `AO` 对象中没有找到 `x` 变量,并且往全局变量中找也没有找到,所以报错。 175 | 176 | ```javascript 177 | AO = { 178 | arguments: { 179 | length: 0, 180 | }, 181 | }; 182 | ``` 183 | 184 | 第二个例子中,我们来看看执行上下文时的 `AO`,我们在创建时找到了 `x`,所以会打印结果。 185 | 186 | ```javascript 187 | AO = { 188 | arguments: { 189 | length: 0, 190 | }, 191 | x: 1, 192 | }; 193 | ``` 194 | -------------------------------------------------------------------------------- /article/JavaScript/JavaScript之this指向.md: -------------------------------------------------------------------------------- 1 | ## this-指向 2 | 3 | ### 普通函数的 this 指向 4 | 5 | ```javascript 6 | let obj = { 7 | num: 10, 8 | fun: function () { 9 | console.log(this.num); 10 | return this.num; 11 | }, 12 | }; 13 | obj.fun(); // 10 14 | let newFun = obj.fun; 15 | newFun(); // undefined 16 | ``` 17 | 18 | 上面一个输出 `10` ,`this` 指向的是 **最后调用它的对象**,在上面函数中 `this` 指向了 `obj` 对象,所以可以取到 `this.num` 。 19 | 20 | 而在 `newFun` 中输出为 `undefined`, `fun` 函数在 `obj` 对象中作为方法被引用,但是在赋值给 `newFun` 之后,`newFun` 的执行仍然是在 `window` 的全局环境中,因此指向的是 `window` 对象,而在 `window` 对象中没有定义 `num`。因此输出 `undefined`,它们相当于: 21 | 22 | ```javascript 23 | console.log(window.num); 24 | ``` 25 | 26 | 我们在代码顶部添加一行 27 | 28 | ```javascript 29 | // this.js 30 | window.num = 0; // 设置 window 对象来验证 31 | let obj = { 32 | num: 10, 33 | fun: function () { 34 | console.log(this.num); 35 | return this.num; 36 | }, 37 | }; 38 | 39 | obj.fun(); // 10 40 | 41 | let newFun = obj.fun; 42 | newFun(); // 0 43 | ``` 44 | 45 | 当然在这里我们需要建一个 `html` 文件来引入 `js` 了,然后在 **浏览器** 中执行,如果只是 `js` 在 `node` 中运行是不行的。 46 | 47 | ```html 48 | // index.html 49 | 50 | 51 | 52 | 53 | 54 | 55 | Document 56 | 57 | 58 | 59 | 60 | 61 | ``` 62 | 63 | 那么现在输出的值就是我们设置的 `window.num` 了,也就是 `100`。 64 | 65 | > 注意: **在执行函数时,如果函数中的 this 是被上一级的对象所调用,那么 this 指向的就是上一级的对象;否则指向全局环境。** 66 | 67 | 所以在普通函数中,有一个说法,就是 **谁调用,那就指向谁**。 68 | 69 | 事实上,调用函数会创建新的属于函数自身的执行上下文。执行上下文的调用创建阶段会决定 this 的指向。到此,我们可以得出的一个结论: 70 | 71 | > this 的指向,是在调用函数时, `根据执行上下文所动态确定的`。 72 | 73 | 可以总结为以下几条规律 : 74 | 75 | 1. 在函数体中,简单调用该函数时(非显式/隐式绑定下),严格模式下 `this` 绑定到 `undefined`,否则绑定到全局对象 `window/global`; 76 | 2. 一般构造函数 `new` 调用,绑定到新创建的对象上; 77 | 3. 一般由 `call/apply/bind` 方法显式调用,绑定到指定参数的对象上; 78 | 4. 一般由上下文对象调用,绑定在该对象上; 79 | 5. 箭头函数中,根据外层上下文绑定的 `this` 决定 `this` 指向。 80 | 81 | #### 案例 82 | 83 | **全局环境下的 this** 84 | 85 | 严格模式下为 `undefined`,普通环境下指向的是 window 86 | 87 | ```javascript 88 | function f1() { 89 | console.log(this); 90 | } 91 | function f2() { 92 | 'use strict'; 93 | console.log(this); 94 | } 95 | f1(); // window 对象 96 | f2(); // undefined 97 | ``` 98 | 99 | 来一个进阶题目 100 | 101 | ```javascript 102 | const foo = { 103 | bar: 10, 104 | fn: function () { 105 | console.log(this); 106 | console.log(this.bar); 107 | }, 108 | }; 109 | var fn1 = foo.fn; 110 | fn1(); 111 | ``` 112 | 113 | 这时候的 `this` 仍然指向的是 `window`,所以 `this.bar` 输出 `undefined` 114 | 115 | ### 箭头函数 this 指向 116 | 117 | 箭头函数的 this 指向就是 **在定义函数时所在的作用域指向的对象**,而不是在调用时确认。我们来看段代码验证一下。 118 | 119 | ```javascript 120 | window.a = '我是 window 下的 a'; 121 | let obj = { 122 | a: '我是 obj 下的 a', 123 | func: () => { 124 | return this.a; 125 | }, 126 | }; 127 | console.log(obj.func()); // 我是 window 下的 a 128 | let fun = obj.func; 129 | console.log(fun()); // 我是 window 下的 a 130 | ``` 131 | 132 | 这里的 `func` 函数,因为在定义时就已经决定了 this 的指向,而所在的作用域在定义时就是在 `全局 window 环境` 下,因此指向的是 `window 对象`,无论是 `obj` 调用或者是 `window` 调用输出都是在 `window 环境` 下了. 133 | 134 | 如果有不知道作用域链的读者,就可以去看看之前的一篇文章 [hzq:作用域与作用域链](#1) 135 | 136 | 我们来对代码稍做修改,就会指向 `obj` 对象。 137 | 138 | ```javascript 139 | window.a = '我是 window 下的 a'; 140 | let obj = { 141 | a: '我是 obj 下的 a', 142 | func: function () { 143 | return () => { 144 | console.log(this.a); 145 | }; 146 | }, 147 | }; 148 | let fun = obj.func(); 149 | fun(); // 我是 obj 下的 a 150 | ``` 151 | 152 | 这里我们在定义时,所在的作用域其实就是 外层 `function 作用域`,而外层 `function` 指向的对象就是 `obj 对象`,所以输出的结果就是 `我是 obj 下的 a` 153 | 154 | ### 小结 155 | 156 | 到此为止呢,this 的指向问题就告一段落了。来做一个小结吧,简单概括为以下两句话。 157 | 158 | **普通函数:`this` 指向的是调用时的对象** 159 | 160 | **箭头函数:`this` 指向的是定义函数时所在的作用域指向的对象** 161 | -------------------------------------------------------------------------------- /article/CSS/10. float.md: -------------------------------------------------------------------------------- 1 | # float 2 | 3 | ## 介绍 4 | 5 | `float` 是 `CSS` 属性,指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。 6 | 该元素从正常文档流中移除,尽管仍然保持部分的流动性。 7 | 8 | 我们来看看 `float` 的语法,`float` 属性的值被指定为一个单一的关键字。 9 | 10 | ```css 11 | .float { 12 | float: left | right | none | inline-start | inline-end; 13 | } 14 | ``` 15 | 16 | - **left**:表明元素必须浮动在其所在的块容器左侧 17 | 18 | - **right**:表明元素必须浮动在其所在的块容器右侧 19 | 20 | - **none**:表明元素不进行浮动 21 | 22 | - **inline-start**:表明元素必须浮动在其所在块容器的开始一侧,在 `Itr` 脚本中是左侧,在 `rtI` 脚本中是右侧 23 | 24 | - **inline-end**:表明元素必须浮动在其所在块容器的结束一侧,在 `Itr` 脚本中是右侧,在 `rtI` 脚本中是左侧 25 | 26 | **我们来看看不使用浮动时的显示** 27 | 28 | ![image-20220115082250490](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/html/image-20220115082250490.png) 29 | 30 | **再来看看使用浮动时的样式。** 31 | 32 | ![image-20220115082334837](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/html/image-20220115082334837.png) 33 | 34 | 来看看代码。 35 | 36 | ```css 37 | .main { 38 | border: 1px solid black; 39 | } 40 | .float { 41 | background-color: #f2cda5; 42 | width: 100px; 43 | height: 100px; 44 | float: left; /* 设置浮动 */ 45 | } 46 | ``` 47 | 48 | ```html 49 |
50 |
51 |

52 | 一、越成功、越伟大,就越该谦恭行事;二、努力工作是成就人生不可或缺的要义;三、以高目标为动力,清除不良品质;四、每天进步一点点,不断突破自己;五、成事者都追求完美。 53 |

54 |
55 | ``` 56 | 57 | ## 浮动带来的问题 58 | 59 | ### 高度塌陷 60 | 61 | 我们来演示一下,我们对代码进行修改,修改文案,并给每一个元素添加 `border`。 62 | 63 | ```html 64 |
65 |
66 |

p标签

67 |
68 | ``` 69 | 70 | - 浮动前 71 | 72 | ![image-20220115082636821](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/html/image-20220115082636821.png) 73 | 74 | - 浮动后 75 | 76 | ![image-20220115082716487](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/html/image-20220115082716487.png) 77 | 78 | 这也就导致了,当我们想让元素从底部开始时,返回跟在了 `p` 标签的下面,并不是 `div` 的下面,也就是高度缺失。 79 | 80 | ```html 81 |
82 |
83 |

p标签

84 |
hello world
85 |
86 | ``` 87 | 88 | 我们添加一段代码,来看看效果。 89 | 90 | ![image-20220115082838323](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/html/image-20220115082838323.png) 91 | 92 | 而这可能并不是我们想要的。所以就需要我们接下来介绍的清除浮动了。 93 | 94 | ## 清除浮动 95 | 96 | 清除浮动,首先我们要介绍的当然是 `clear` 了。 97 | 98 | ```css 99 | .clear { 100 | clear: none | left | right | both; 101 | } 102 | ``` 103 | 104 | 当然 `both` 是我们最常用的属性。 105 | 106 | - clear 107 | 我们给底部的 `div` 添加 `clear` 属性。 108 | 109 | ```css 110 | .clear { 111 | clear: both; 112 | } 113 | ``` 114 | 115 | ```html 116 |
hello world
117 | ``` 118 | 119 | ![image-20220115083005924](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/html/image-20220115083005924.png) 120 | 121 | 看结果,我们就可以知道,浮动被清除了,从浮动格子的下面开始显示了。 122 | 123 | - 创建 BFC 124 | 125 | 我们来看看创建 [BFC](https://github.com/hzzzzzzzq/Blog/issues/26) 的方式。 126 | 127 | ```html 128 |
129 |
130 |

p标签

131 |
hello world
132 |
133 | ``` 134 | 135 | 我们在 `main` 中添加以下代码。 136 | 137 | ```css 138 | .main { 139 | overflow: hidden; 140 | } 141 | ``` 142 | 143 | ![image-20220115083450019](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/html/image-20220115083450019.png) 144 | 145 | 这里让 `main` 建立了一个 BFC,所以就出现了上面的情况,由于为把 `hello world` 写在了 `main` 下,所以会只展示这个格子的高度,与上面的 `clear: both` 清除浮动的方式不同。 146 | 147 | 这里不了解 `BFC` 的可以看我之前的文章 - [BFC](https://github.com/hzzzzzzzq/Blog/issues/26); 148 | 149 | - 伪元素 150 | 151 | 给父元素添加伪元素来解决。 152 | 153 | ```css 154 | .clearfix::after { 155 | content: ''; 156 | display: block; 157 | clear: both; 158 | } 159 | ``` 160 | 161 | ```html 162 |
163 |
164 |

p标签

165 |
hello world
166 |
167 | ``` 168 | 169 | 结果与 `BFC` 清除浮动的结果相同。 170 | 171 | ## 参考 172 | 173 | [MDN - float](https://developer.mozilla.org/zh-CN/docs/Web/CSS/float) 174 | [BFC](https://github.com/hzzzzzzzq/Blog/issues/27) 175 | -------------------------------------------------------------------------------- /article/CSS/8. div居中.md: -------------------------------------------------------------------------------- 1 | # div 居中 2 | 3 | 让 `div` 内的元素水平垂直居中。 4 | 5 | 接下来,我们就来看看 div 在高度已知,高度未知的情况下,如何进行水平垂直居中。 6 | 7 | 我们先来看看两段 html 代码,解释下面的内容居中和元素居中。 8 | 9 | - 内容居中 10 | 11 | ```html 12 |
我是内容
13 | ``` 14 | 15 | - 元素居中 16 | 17 | ```html 18 |
19 |
我是内容
20 |
21 | ``` 22 | 23 | ## 高度已知 24 | 25 | ### div 内容居中 26 | 27 | 首先是内容,直接写在 `div` 中的,无嵌套任何元素。 28 | 29 | - 用于内容居中 30 | 31 | ```css 32 | .box { 33 | width: 300px; 34 | height: 300px; 35 | background-color: #efcca1; 36 | color: #fff; 37 | text-align: center; /* 水平居中 */ 38 | line-height: 300px; /* 垂直居中 */ 39 | } 40 | ``` 41 | 42 | 我们设置行高与高度相等时,可以设置对 `line-height` 进行设置,就可以进行垂直居中,然后使用 `text-align` 就可以进行水平居中。 43 | 44 | 当然,我们还是需要来看结果. 45 | 46 | ![div-center1](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/div-center/div-center1.png) 47 | 48 | 其实这种方式,也可以用于元素居中,但是如果外部元素有其他内容时就会出错。我们来看一下 49 | 50 | 首先是内部只有一个元素时。 51 | 52 | ```css 53 | .content { 54 | background-color: #1890ff; 55 | } 56 | ``` 57 | 58 | ![div-center2](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/div-center/div-center2.png) 59 | 60 | 然后我们来看看内部还有其他元素时。 61 | 62 | ```html 63 |
64 | 其他元素 65 |
我是内容
66 |
67 | ``` 68 | 69 | ![div-center3](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/div-center/div-center3.png) 70 | 71 | 所以不建议使用在元素居中的情况下。 72 | 73 | ### position 74 | 75 | 绝对定位当然是要用在元素居中的情况了,需要使用内部元素进行偏移。 76 | 77 | - 用于元素居中 78 | 79 | ```css 80 | .box { 81 | width: 300px; 82 | height: 300px; 83 | background-color: #efcca1; 84 | position: relative; 85 | } 86 | .content { 87 | width: 100px; 88 | height: 100px; 89 | position: absolute; 90 | top: 50%; 91 | left: 50%; 92 | margin: -50px 0 0 -50px; 93 | } 94 | ``` 95 | 96 | ![div-center4](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/div-center/div-center4.png) 97 | 98 | 从结果来看,我们是可以进行居中的。 99 | 100 | 1. 首先我们通过设置父元素 `position: relative`,然后在子元素中设置 `position: absolute`。 101 | 2. 我们对子元素进行偏移,`top 50%`,`left 50%`,当然偏移之后,其实不是居中的。 102 | 3. 我们在对其这是 `margin` 将以往 `top` 以及 `left` 方向挤压,居中。 103 | 104 | ## 高度未知 105 | 106 | ### flex 居中 107 | 108 | 首先,当然要说一下,我们最常见的 [`flex` 布局]()的居中了 109 | 110 | - 用于内容或者元素居中 111 | 112 | 我们来看看 `flex` 怎么居中。 113 | 114 | ```css 115 | .box { 116 | width: 300px; 117 | height: 300px; 118 | background-color: #efcca1; 119 | display: flex; 120 | justify-content: center; 121 | align-items: center; 122 | } 123 | .content { 124 | width: 100px; 125 | height: 100px; 126 | background-color: #1890ff; 127 | color: #fff; 128 | } 129 | ``` 130 | 131 | 我们就可以看到结果了。 132 | 133 | ![div-center5](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/div-center/div-center4.png) 134 | 135 | ### 偏移居中 136 | 137 | 我们需要设置一个**相对定位进行偏移**,然后使用 `transform`,往回偏移一个元素的一半宽度。 138 | 139 | - 用于元素居中 140 | 141 | ```css 142 | .box { 143 | width: 300px; 144 | height: 300px; 145 | background-color: #efcca1; 146 | } 147 | .content { 148 | width: 100px; 149 | height: 100px; 150 | background-color: #1890ff; 151 | position: relative; 152 | top: 50%; /* Y 偏移 50% */ 153 | left: 50%; /* X 偏移 50% */ 154 | transform: translate(-50%, -50%); /* x ,y 分别往回偏移元素的一半宽度 */ 155 | color: #fff; 156 | } 157 | ``` 158 | 159 | 我们可以看到结果跟 `flex` 布局是相同的。 160 | 161 | ![div-center6](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/div-center/div-center4.png) 162 | 163 | ### table-cell 164 | 165 | 设置 table-cell 之后,可以设置 `vertical-align: middle` 进行垂直居中设置。 166 | 167 | - 用于内容居中 168 | 169 | ```css 170 | .box { 171 | width: 300px; 172 | height: 300px; 173 | background-color: #efcca1; 174 | display: table-cell; 175 | text-align: center; 176 | vertical-align: middle; 177 | color: #fff; 178 | } 179 | ``` 180 | 181 | ![div-center7](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/div-center/div-center1.png) 182 | 183 | --- 184 | 185 | 居中方式,大体都介绍了一遍,如果后续发现新方式,可以评论我,让我加一加,谢谢各位。 186 | -------------------------------------------------------------------------------- /article/ES6/3. 变量的解构赋值.md: -------------------------------------------------------------------------------- 1 | # 变量的解构赋值 2 | 3 | 解构赋值:ES6 允许按照一定模式,从数组、字符串和对象中提取值,对变量进行赋值 4 | 5 | 我们来看一下以前赋值的方式 6 | 7 | ```javascript 8 | let a = 1; 9 | let b = 2; 10 | ``` 11 | 12 | 那么现在我们来初步了解一下解构赋值 13 | 14 | ```javascript 15 | let [a, b] = [1, 2]; 16 | ``` 17 | 18 | 上面两段代码的赋值结果是相同的。 19 | 20 | --- 21 | 22 | ## 数组的解构赋值 23 | 24 | ### 基本使用 25 | 26 | 我们来看看数组的解构赋值,在上面中,我们使用了数组的解构赋值,来举例子。 27 | 28 | ```javascript 29 | let [a, b, c, d] = [1, 2, 3, 4]; 30 | ``` 31 | 32 | 这样操作之后,就可以从数组中提取到相应的值,**按照对应位置,对变量赋值**。 33 | 34 | 本质上,也就是模式的匹配,只要等号两边的模式相同,左边的变量就会被赋予对应的值。 35 | 36 | 我们来多举例 37 | 38 | ```javascript 39 | // 例子1 40 | let [a, [b], [c]] = [1, [2], [3]]; 41 | console.log(a); // 1 42 | console.log(b); // 2 43 | console.log(c); // 3 44 | ``` 45 | 46 | 从 `例子1` 中可以看出,这是一种嵌套数组取值方式,可以看出,数组的解构赋值,可以进行嵌套取值。 47 | 48 | ```javascript 49 | // 例子2 50 | let [, a] = [1, 2]; 51 | console.log(a); // 2 52 | ``` 53 | 54 | 从 `例子2` 来看,就证明了数组赋值解构说的这句话,**按照对应的值,对变量进行赋值**,而不是每次都从第一个开始取。 55 | 56 | ```javascript 57 | // 例子3 58 | let [a, ...arr] = [1, 2, 3, 4]; 59 | console.log(a); // 1 60 | console.log(arr); // [2, 3, 4]; 61 | ``` 62 | 63 | 从 `例子3` 来看,我们也可以用 [扩展运算符](https://github.com/hzzzzzzzq/Blog/issues/7) 这里需要一个扩展运算符的项目,来同时将后面的值放到一个数组中。 64 | 65 | ```javascript 66 | // 例子4 67 | let [a, b, ...arr] = [1]; 68 | console.log(a); // 1 69 | console.log(b); // undefined 70 | console.log(arr); // [] 71 | ``` 72 | 73 | 从 `例子4` 来看,我们能发现,如果在右侧找不到值时,就是解构不成功,这时候如果是单变量,则会等于 [`undefined`](数据基本结构),如果是使用了 [扩展运算符](https://github.com/hzzzzzzzq/Blog/issues/7) 的变量,则是空数组。 74 | 75 | ### 默认值 76 | 77 | 接下来,我们来看一下解构赋值中指定默认值 78 | 79 | ```javascript 80 | // 例子5 81 | let [a = 10] = []; 82 | console.log(a); // 10 83 | ``` 84 | 85 | 在上面的 `例子5` 中,可以看到,`a` 对应的右侧是解构失败的,值应该为 `undefined`,但是输出是 `10`,这就是因为**解构赋值中允许指定默认值** 86 | 87 | 但是默认值是有生效条件的:**只有当一个数组成员严格等于 `undefined` 时,默认值才会生效**。 88 | 89 | > ES6 中的严格相等运算符( `===` ),可以判断一个位置是否有值。 90 | 91 | ```javascript 92 | // 例子6 93 | let [a = 1, b = 2, c = 3] = [10, null, undefined]; 94 | console.log(a); // 10 95 | console.log(b); // null 96 | console.log(c); // 3 97 | ``` 98 | 99 | 在 `例子6` 中,就可以看出只有当右侧的值严格相等于 `undefined` 时,默认值才会生效。 100 | 101 | --- 102 | 103 | ## 对象的解构赋值 104 | 105 | 解构赋值并不只是在数组中,在对象中也可以。 106 | 107 | ### 基本使用 108 | 109 | ```javascript 110 | // 例子7 111 | let { a, b } = { a: 'aaa', b: 'bbb' }; 112 | console.log(a); // 'aaa' 113 | console.log(b); // 'bbb' 114 | ``` 115 | 116 | 从 `例子7` 中,我们可以看出对象的解构赋值与数组的解构赋值的一个重要的不同点。数组元素是按照对应的下标次序来排列的,但是在对象中,变量必须与属性同名,才可以取到正确的值 117 | 118 | ```javascript 119 | // 例子8 120 | let { b, c } = { a: 'aaa', b: 'bbb' }; 121 | console.log(b); // 'bbb' 122 | console.log(c); // undefined 123 | ``` 124 | 125 | 从 `例子8` 中,我们可以看到,对象的解构赋值,变量必须与属性同名,且并不是按照次序来对应的。同数组,解构失败时,变量的值等于 `undefined`。 126 | 127 | ```javascript 128 | // 例子9 129 | let { 130 | a: { b }, 131 | } = { a: { b: 20 } }; 132 | console.log(b); // 20 133 | 134 | // 例子10 135 | let { a } = { a: { b: 20 } }; 136 | ``` 137 | 138 | 从 `例子9` 中,我们可以看到,对象的解构赋值,也是同数组一样,可以进行嵌套取值。 139 | 140 | > 注意:在这里 `例子9` 中左侧的 `a` 是模式,不是变量,因此不会被赋值,如果想要 `a` 也被赋值,可以使用 `例子10` 的写法 141 | 142 | ### 默认值 143 | 144 | 我们在数组解构赋值中,可以使用默认值,那么在对象中,是不是也有呢? 145 | 146 | ```javascript 147 | // 例子11 148 | let { a = 1 } = {}; 149 | console.log(a); // 1 150 | 151 | // 例子12 152 | let { a, b = 2 } = { a: 1 }; 153 | console.log(a); // 1 154 | console.log(b); // 2 155 | 156 | // 例子13 157 | let { a: b = 1 } = {}; 158 | console.log(b); // 1 159 | ``` 160 | 161 | 从 `例子11`、`例子12`、`例子13`,可以看出,其实对象的默认值与数组的默认值是类似的。 162 | 163 | --- 164 | 165 | ## 字符串的解构赋值 166 | 167 | 字符串也是可以进行解构赋值的,其实就是相当于将字符串转化成一个类似数组的对象。 168 | 169 | ```javascript 170 | // 例子14 171 | let [a, b, c, d, e] = 'hello'; 172 | console.log(a); // 'h' 173 | console.log(b); // 'e' 174 | console.log(c); // 'l' 175 | console.log(d); // 'l' 176 | console.log(e); // 'o' 177 | ``` 178 | 179 | 从 `例子14` 来看,就可以明白了,数组的解构赋值相当于被转化成一个类数组的对象进行解构赋值。 180 | 181 | --- 182 | 183 | ## 函数参数的解构赋值 184 | 185 | 函数的参数也是可以使用解构赋值 186 | 187 | ```javascript 188 | // 例子15 189 | function add([a, b]) { 190 | return a + b; 191 | } 192 | console.log(add([1, 2])); // 3 193 | ``` 194 | 195 | 从 `例子15` 可以看出,函数的参数是可以进行解构赋值的,既然**数组**可以,那么**对象**也可以,**字符串**也是。 196 | 197 | --- 198 | -------------------------------------------------------------------------------- /article/面试题目/CSS/选择器相关面试题.md: -------------------------------------------------------------------------------- 1 | ## 3. 列举出 css 选择器有哪些分类,并至少写出三个 css 选择器之间的区别,适用场景 2 | 3 | ### (1) css 选择器 4 | 5 | 最基本的选择器:标签名选择器,类选择器,id 选择器 6 | 7 | 其他选择器: 8 | 9 | - 相邻选择器 (h1+p) 10 | - 子选择器(ul > li) 11 | - 后代选择器(li a) 12 | - 通配符选择器(\*) 13 | - 属性选择器(a[rel="external"]) 14 | - 伪类选择器(a:hover, li:nth-child) 15 | 16 | #### 常见的一些选择器 17 | 18 | - `*` 19 | 20 | 通配符选择器,会将页面上所有的元素都选到,通常用来情况 margin 和 padding,练习时使用这个没问题,不建议的生产环境中使用它。有时候也可以用来选择某些元素的所有子元素 21 | 22 | - id 选择器 23 | 24 | 使用 # 可以用 id 来定位某个元素。大家通常这么使用,然后使用的时候大家还是要相当小心。需要问自己一下,我们是不是必须要给这个元素来赋值个 id 来定位它呢? 25 | 26 | id 选择器是很严格的并且你没办法去复用它。如果可能的话,首先适用标签名字,HTML5 中的新元素,或者是伪类。 27 | 28 | - 类选择器 29 | 30 | class 选择器。它跟 id 选择器不同的是,它可以定位多个元素。当你想对多个元素进行样式修饰的时候就可以使用 class。当你要对某个特定的元素进行修饰那就是用 id 来定位它。 31 | 32 | - 后代选择器 `x y` 33 | 34 | ```css 35 | li a { 36 | color: red; 37 | } 38 | ``` 39 | 40 | 如果你想要更加具体的去定位元素,你可以使用它。例如,你不需要定位所有的 a 元素,而只需要定位 li 标签下的 a 标签,这时候你就需要使用这个选择器了 41 | 42 | > 如果你的选择器想 x y z a b.error 这样,那你就错了。时刻都提醒自己,是否真的需要对那么多元素修饰 43 | 44 | - 标签选择器 45 | 46 | ```css 47 | a { 48 | color: red; 49 | } 50 | ul { 51 | margin-left: 0; 52 | } 53 | ``` 54 | 55 | 如果你想定位页面上所有的某标签,不是通过 id 或者 class,这简单,直接使用类型选择器 56 | 57 | - X:visited and x: link 58 | 59 | ```css 60 | a:link { 61 | color: red; 62 | } 63 | a:visited { 64 | color: purple; 65 | } 66 | ``` 67 | 68 | - x + y 69 | 70 | ```css 71 | ul + p { 72 | color: red; 73 | } 74 | ``` 75 | 76 | 相邻选择器。它只会选中指定元素的直接后继元素。上面那个例子就是选中了所有 ul 标签后面的第一段,并将他们的颜色都设置为红色。 77 | 78 | - x>y 79 | 80 | ```css 81 | div > ul { 82 | border: 1px solid black; 83 | } 84 | ``` 85 | 86 | x y 和 x>y 的差别就是后面这个只会选择它的直接子元素 87 | 88 | - x ~ y 89 | 90 | ```css 91 | ul ~ p { 92 | color: red; 93 | } 94 | ``` 95 | 96 | 兄弟节点组合选择器跟 X+Y 很相似,然后它又不是那么的严格。ul + p 选择器只会选择紧挨跟着指定元素的那些元素。而这个选择器,会选择跟在目标元素后面的所有匹配的元素 97 | 98 | - x[title] 99 | 100 | ```css 101 | a[title] { 102 | color: green; 103 | } 104 | ``` 105 | 106 | 属性选择器,上面的这个例子中,只会选择有 title 属性的元素。那些没有此属性的锚点标签将不会被这个代码修饰。 107 | 108 | - X:checked 109 | 110 | ```css 111 | input[type='radio']:checked { 112 | border: 1px solid black; 113 | } 114 | ``` 115 | 116 | 上面这个伪类写法可以定位那些被选中的单选框和多选框 117 | 118 | - x:after 119 | 120 | before 和 after 这俩伪类。好像每天大家都能找到使用它们的创造性方法。它们会在被选中的标签周围生产一些内容 121 | 122 | - X:nth-child(n) 123 | 124 | ```css 125 | li: nth-child(3) { 126 | color: red; 127 | } 128 | ``` 129 | 130 | 注意 nth-child 接受一个整型参数,然后它不是从 0 开始的。如果你想获取第二个元素,那么你就传值 131 | 132 | ### 14. 一个标签的 class 样式的渲染顺序,id、class、标签、伪类的优先级 133 | 134 | #### 优先级 135 | 136 | 浏览器通过优先级来判断哪些属性值与一个元素最为相关,从而在该元素上应用这些属性值。优先级是基于不同种类选择器组成的匹配规则。 137 | 138 | 优先级就是分配给指定的 `css` 声明的一个权重,它由匹配的选择器中的每一种选择器类型的数值决定。 139 | 140 | 而当优先级与多个 css 声明中任意一个声明的优先级相等的时候,css 中最后的那个声明将会被应用到元素上。 141 | 142 | 当同一个元素有多个声明的时候,优先级才会有意义。因为每个直接作用于元素的 CSS 规则总是会接管/覆盖该元素从祖先元素继承而来的规则。 143 | 144 | #### 选择器类型 145 | 146 | 在下面列表中,选择器类型的优先级是递减的 147 | 148 | - ID 选择器 149 | - 类选择器,属性选择器和伪类 150 | - 类型选择器和伪元素 151 | 152 | 所以一个标签的 class 样式渲染的顺序为:id > class/伪类 > 标签 153 | 154 | ```html 155 | 178 |
样式渲染顺序
179 | ``` 180 | 181 | 上面最后展示的是红色。 182 | 183 | 通配符选择器 关系选择器(+, >, ~, ' ', ||)和 否定伪类(:not()对优先级没有影响),但是,在:not()内部声明的选择器会影响优先级 184 | 185 | #### 优先级参考图 186 | 187 | ![优先级参考图](https://img-blog.csdnimg.cn/20210424142602510.png) 188 | 189 | ### 31. 一下 css 最后是什么颜色 190 | 191 | ```html 192 | 203 |
abc
204 | ``` 205 | 206 | #### 题解 207 | 208 | 最后是黄色 209 | 210 | css 权重分析 211 | 212 | 假设: 213 | 214 | - id 选择器权重:100 215 | - class 选择器权重:10 216 | - 标签选择器权重:1 217 | 218 | 则 219 | 220 | ```css 221 | div => 1 222 | #title => 100 223 | div .title => 10+1 = 11 224 | 所以权重的id选择器 color生效 225 | ``` 226 | -------------------------------------------------------------------------------- /article/JavaScript/10. JavaScript深入之new操作.md: -------------------------------------------------------------------------------- 1 | # new 关键字 2 | 3 | new 操作,我们在类对象,函数中都会使用到,那么它到底是用来干什么的呢?又是怎么实现的呢? 4 | 5 | ## 第一版 - 基础完成 6 | 7 | 我们先看看 MDN 的定义: 8 | 9 | > new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。 10 | 11 | 我们先来举个例子吧 12 | 13 | ```javascript 14 | function Person(name, age) { 15 | this.name = name; 16 | this.age = age; 17 | } 18 | Person.prototype.weight = 70; 19 | Person.prototype.getInfo = function () { 20 | console.log(this.name, this.age, this.weight); 21 | }; 22 | const person = new Person('hzzzzzzzq', 18); 23 | console.log(person.name); // hzzzzzzzq 24 | console.log(person.age); // 18 25 | console.log(person.weight); // 70 26 | person.getInfo(); // hzzzzzzzq 18 70 27 | ``` 28 | 29 | 我们从例子中来看,我们创建的实例 person 可以做到 30 | 31 | - 获取构建函数里的属性 32 | - 获取构建函数的原型里的属性 33 | 34 | 所以由此我们来推断 new 操作做了什么。 35 | 36 | - new 的返回时一个对象 37 | - 需要为对象添加属性 38 | - 需要将对象原型指向构造函数的原型 39 | 40 | 但是由于 `new` 操作是关键字,所以就是用一个创建方法 `objectFactory` 来替代了。 41 | 42 | ```javascript 43 | let pserson = new Person(...arguments); 44 | 45 | // 等价我们创建的方法 46 | 47 | let person = objectFactory(Person, ...arguments); 48 | ``` 49 | 50 | 由此,我们来看第一版代码吧。 51 | 52 | ```javascript 53 | function objectFactory() { 54 | const obj = {}; // 创建一个新对象,也可以使用 new Object() 55 | const Constructor = [].shift.call(arguments); // 获取构造函数,传入参数的第一个值 56 | obj.__proto__ = Constructor.prototype; // 将对象的原型指向构造函数的原型 57 | Constructor.apply(obj, arguments); // 绑定对象,为对象添加属性 58 | return obj; // 返回对象 59 | } 60 | ``` 61 | 62 | 接下来,我们来测试一下 63 | 64 | ```javascript 65 | function Person(name, age) { 66 | this.name = name; 67 | this.age = age; 68 | } 69 | Person.prototype.weight = 70; 70 | Person.prototype.getInfo = function () { 71 | console.log(this.name, this.age, this.weight); 72 | }; 73 | 74 | function objectFactory() { 75 | const obj = {}; // 创建一个新对象,也可以使用 new Object() 76 | const Constructor = [].shift.call(arguments); // 获取构造函数,传入参数的第一个值 77 | obj.__proto__ = Constructor.prototype; // 将对象的原型指向构造函数的原型 78 | Constructor.apply(obj, arguments); // 绑定对象,为对象添加属性 79 | return obj; // 返回对象 80 | } 81 | // const person = new Person('hzzzzzzzq', 18); 82 | const person = objectFactory(Person, 'hzzzzzzzq', 18); 83 | console.log(person.name); // hzzzzzzzq 84 | console.log(person.age); // 18 85 | console.log(person.weight); // 70 86 | person.getInfo(); // hzzzzzzzq 18 70 87 | ``` 88 | 89 | 发现,结果是一样的,这样就实现了吗? 90 | 当然不是,我们的构造函数如果有返回值呢?那会怎么样呢? 91 | 92 | ## 第二版 - 返回值 93 | 94 | 我们来看看例子,由此,我们可以看见,如果构造函数带有返回值,则会导致返回值以外定义的值无效。 95 | 96 | - 如果是函数,则返回类型错误 97 | - 如果是变量,返回 undefined 98 | 99 | ```javascript 100 | function Person(name, age) { 101 | this.weight = 70; 102 | 103 | return { 104 | name: name, 105 | age: age, 106 | }; 107 | } 108 | Person.prototype.getInfo = function () { 109 | console.log(this.name, this.age, this.weight); 110 | }; 111 | const person = new Person('hzzzzzzzq', 18); 112 | console.log(person.name); // hzzzzzzzq 113 | console.log(person.age); // 18 114 | console.log(person.weight); // undefined 115 | person.getInfo(); // TypeError: person.getInfo is not a function 116 | ``` 117 | 118 | 但是返回值就一定是对象吗?结果显然是不一定。 119 | 120 | 所有,我们来看看不是对象时是什么情况: 121 | 122 | ```javascript 123 | function Person(name, age) { 124 | this.name = name; 125 | this.age = age; 126 | this.weight = 70; 127 | 128 | return 'hello'; 129 | } 130 | const person = new Person('hzzzzzzzq', 18); 131 | console.log(person.name); // hzzzzzzzq 132 | console.log(person.age); // 18 133 | console.log(person.weight); // 70 134 | ``` 135 | 136 | 我们发现,都正确返回了,所以我们需要进行判断 137 | 138 | - 构造函数返回的是一个对象,则返回这个对象 139 | - 返回的是一个值,则忽略 140 | 141 | 接下来我们来更改我们的代码. 142 | 143 | ```javascript 144 | function objectFactory() { 145 | const obj = {}; 146 | const Constructor = [].shift.call(arguments); 147 | obj.__proto__ = Constructor.prototype; 148 | const result = Constructor.apply(obj, arguments); // 获取 返回值 149 | 150 | return typeof result === 'object' ? result : obj; // typeof 进行判读 151 | } 152 | ``` 153 | 154 | ## 小结 155 | 156 | 我们来小结一下 new 做的事情。 157 | 158 | - 创建一个空的简单 `JavaScript` 对象(即`{}`) 159 | - 为对象添加属性`__proto__`,将该属性链接至构造函数的原型对象 160 | - 将该对象作为 `this` 的上下文 ; 161 | - 如果该函数没有返回对象,则返回 `this`。 162 | 163 | 到此,我们就完美复刻出了 `new` 操作喽。 164 | -------------------------------------------------------------------------------- /article/ES6/2. let 和 const 命令.md: -------------------------------------------------------------------------------- 1 | # Let 和 const 命令 2 | 3 | --- 4 | 5 | ## let 命令 6 | 7 | ### **简单实用** 8 | 9 | ES6 中新增了 `let` 命令,用来声明变量。使用方式同 `var` 命令,但是 `let` 命令只在所在的代码块内有效。 10 | 11 | ```javascript 12 | { 13 | let a = 10; 14 | var b = 10; 15 | } 16 | console.log(a); // 报错,a 为定义 ReferenceError: a is not defined 17 | console.log(b); // 10 18 | ``` 19 | 20 | 在上面的使用案例中,我们可以看出 `let` 命令只在代码块中生效,而在代码块以外使用则无效。 21 | 22 | ### **for 循环中使用** 23 | 24 | 我们来看看在 `for` 循环中使用 `var` 命令. 25 | 26 | 下面这段代码,打印出来的会是什么呢?可以跑一下代码,看一下控制台。 27 | 28 | ```javascript 29 | for (var i = 0; i < 5; i++) { 30 | console.log(i); 31 | } 32 | console.log(i); // 5 33 | ``` 34 | 35 | 好了,你会发现,所有的打印都是 `5`,为什么呢?是因为 `var` 命令是在全局范围内有效,所以全局只有一个变量 `i`,每一次循环,变量 `i` 的值都会发生改变,所以当你打印是,打印的就是全局的 `i` ,也就是经过多次变化赋值的 `5`。 36 | 37 | 上面代码中,我在外面打印了一下 `i` ,来证明 `var` 定义的是一个全局变量。 38 | 39 | 来,让我们将 `var` 改成 `let`,现在打印的结果又是什么呢? 40 | 41 | ```javascript 42 | for (let i = 0; i < 5; i++) { 43 | console.log(i); 44 | } 45 | console.log(i); // ReferenceError: i is not defined 46 | ``` 47 | 48 | 当然,我想很多人都猜到了结果,就是 `0 1 2 3 4` ,那么这里又是为什么呢? 49 | 50 | `let` 变量只在所在的代码块内有效,在子代码块中依然有效。在上述循环中 `i` 只在本轮循环内有效,所以每一次循环的 `i` 其实都是一个新定义的变量,所以会输出当前 `i` 的值,每次循环对应输出。 51 | 52 | 当然,这里可能会出现一个问题,每轮的变量都是一个新变量,那它是怎么知道上一轮循环的值的?稍做解释:[JS 引擎(v8)](https://jsshou.cn/blog/frontend/V8study.html#%E5%89%8D%E8%A8%80)内部会记住上一轮循环的值,初始化本轮的变量时,就在上一轮循环的基础上进行计算。 53 | 54 | 上面我们说,`let` 命令在子代码块中也有效,可以从 `for` 循环上来看,`()` 内部其实就是一个父级作用域,而 `{}` 内部就是一个单独的子作用域。 55 | 56 | ### 不存在变量提升 57 | 58 | 变量提升,即变量可以在声明之前使用,值为 `undefined`,`var` 命令存在,而 `let` 命令并没有变量提升,照样,我们来看看使用的案例。 59 | 60 | ```javascript 61 | console.log(a); // undefined 62 | var a = 10; 63 | 64 | console.log(b); // ReferenceError 65 | let b = 10; 66 | ``` 67 | 68 | 可以在控制台中跑一下这段代码,进行尝试。你会发现,`a` 变量进行了变量提升,而 `b` 变量没有发生,这表明了在声明之前使用,变量 `b` 是不存在的。 69 | 70 | ### 暂时性死区 71 | 72 | **代码块中,使用 `let` 命令声明变量之前,该变量都是不可用的**。 73 | 74 | 在外部有一个全局变量 `x`,但是在内部使用 `let` 声明了一个 `x`,于是内部的 `x` 绑定了这个代码块,不受部影响。 75 | 76 | 但是在内部,声明变量之前的这个区域就是**暂时性死区**,我们来从下面的代码来看。 77 | 78 | ```javascript 79 | var x = 100; 80 | if (true) { 81 | // 暂时性死区 开始点 82 | x = 10; // 报错 83 | console.log(x); // 报错 84 | let x; // 暂时性死区结束点 85 | console.log(X); // undefined 86 | 87 | x = 20; 88 | console.log(x); // 20 89 | } 90 | ``` 91 | 92 | **暂时性死区**的存在,也就意味着 `typeof` 的操作会变的不安全,在没有声明变量时,使用 `typeof` 并不会报错,返回一个 `undefined`,然而因为暂时性死区,会使得 `typeof` 报错 `ReferenceError`。 93 | 94 | ```javascript 95 | if (true) { 96 | console.log(typeof x); // undefined 97 | console.log(typeof y); // ReferenceError 98 | let y; 99 | } 100 | ``` 101 | 102 | 在[函数默认值](https://github.com/hzzzzzzzq/Blog/issues/6)中也存在暂时性死区,而且会不容易发现。 103 | 104 | ```javascript 105 | function add(x = y, y = 1) { 106 | return x + y; 107 | } 108 | add(); // ReferenceError 109 | ``` 110 | 111 | 在上面的代码中,就是如此,给[函数赋默认值](https://github.com/hzzzzzzzq/Blog/issues/6)时,使用后面的值赋值给前面的 `x`,而这时候 `y` 还没有定义,所以会报错。 112 | 113 | ### 不允许重复声明 114 | 115 | `var` 变量是允许进行重复声明的,但是 `let` 变量是不允许的。 116 | 117 | 来,上代码。 118 | 119 | ```javascript 120 | var a = 10; 121 | var a = 20; 122 | console.log(a); // 20 123 | 124 | var b = 10; 125 | let b = 20; 126 | console.log(b); // 20 127 | 128 | let c = 10; 129 | var c = 20; 130 | // 报错 131 | 132 | let d = 10; 133 | let d = 20; 134 | // 报错 135 | ``` 136 | 137 | --- 138 | 139 | ## const 命令 140 | 141 | `const` 命令 声明一个只读的常量。一旦声明,常量的值就不能改变 142 | 143 | ### 基本用法 144 | 145 | ```javascript 146 | const PI = 3.14159; 147 | console.log(PI); // 3.14159 148 | 149 | PI = 3.14; // TypeError: Assignment to constant variable 150 | ``` 151 | 152 | `const` 声明时,必须立即进行初始化,不能进行赋值。 153 | 154 | ```javascript 155 | cosnt PI; // 报错 SyntaxError 156 | ``` 157 | 158 | `const` 只声明,不赋值就会报错。 159 | 160 | `const` 作用域与 `let` 相同:只在声明所在的块级作用域内有效。 161 | 162 | ```javascript 163 | { 164 | const PI = 3.14159; 165 | } 166 | console.log(PI); //Uncaught ReferenceError 167 | ``` 168 | 169 | `const` 命令也不存在变量提升,但是存在暂时性死区,只能在声明后使用。 170 | 171 | 与 `let` 一样,不可进行重复声明。 172 | 173 | ### 本质 174 | 175 | 首先,我们来看一个对象的例子: 176 | 177 | ```javascript 178 | const obj = {}; 179 | obj.prop = 1; 180 | console.log(obj.prop); // 1 181 | 182 | obj = {}; // TypeError 183 | ``` 184 | 185 | 由上面可以看出,常量 `obj` 储存的是一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把 obj 指向另一个地址,但对象本身是可变的,所以依然可以添加新属性。 186 | 187 | 再来看一个数组的例子: 188 | 189 | ```javascript 190 | const arr = []; 191 | arr.push(1); 192 | console.log(arr); // 1 193 | 194 | arr = []; 195 | ``` 196 | 197 | 同对象,常量 `arr` 是一个数组,这个数组本身是可写的,但是如果将另一个数组赋值给 `arr`,就会报错。 198 | 199 | 由此可见 200 | 201 | - `const` 保证的 实际上并不是变量的值不改动,而是变量指向的那个内存地址所保存的数据不得改动。 202 | 203 | - `const` 只能保证这个指针式固定的,至于他指向的数据结构是不是可变的,就完全不能控制了。 204 | -------------------------------------------------------------------------------- /article/JavaScript/9. JavaScript深入之bind函数.md: -------------------------------------------------------------------------------- 1 | # bind 2 | 3 | bind 函数与 `call`,`apply` 的区别是什么呢? 4 | 5 | - `bind` 函数并不是直接调用的,且返回函数可以参数 6 | - 参数一 与 `call、apply` 同样,指定的对象(该函数的执行上下文 7 | - 其他参数与 `call` 相同,都作为参数传入,但是 `apply` 只传入一个数组参数 8 | 9 | 具体对照,可以看我上面的一篇文章,[JavaScript 深入之 call 和 apply 函数]()。 10 | 11 | 我们来看 `bind` 的特点 12 | 13 | - 返回函数 14 | - 返回函数可以传参数 15 | 16 | ## 第一版 - 返回函数 17 | 18 | 我们来看一下 `bind` 执行的返回效果吧: 19 | 20 | ```javascript 21 | let obj = { 22 | name: 'hzzzzzzzq', 23 | age: 18, 24 | }; 25 | function log() { 26 | console.log(this.name, this.age); 27 | } 28 | let print = log.bind(obj); 29 | print(); 30 | // hzzzzzzzq 18 31 | ``` 32 | 33 | 由此,我们来写文吗的第一版代码。 34 | 35 | ```javascript 36 | Function.prototype.myBind = function (context) { 37 | let self = this; 38 | return function () { 39 | return self.apply(context); 40 | }; 41 | }; 42 | ``` 43 | 44 | 我们来看看结果,是不是一样了呢? 45 | 46 | ```javascript 47 | let obj = { 48 | name: 'hzzzzzzzq', 49 | age: 18, 50 | }; 51 | function log() { 52 | console.log(this.name, this.age); 53 | } 54 | let print = log.myBind(obj); 55 | print(); 56 | // hzzzzzzzq 18 57 | ``` 58 | 59 | 这时候,我们得到了一个返回值,并且绑定。 60 | 61 | ## 第二版 - 传入参数 62 | 63 | 我们来看看,不仅在 `bind` 函数中可以传入参数,其返回的函数也可以传入参数。 64 | 我们看下面的例子: 65 | 66 | ```javascript 67 | let obj = { 68 | value: 1, 69 | }; 70 | function log(name, age) { 71 | console.log(this.value, name, age); 72 | } 73 | let print = log.bind(obj, 'hzzzzzzzq'); 74 | print(18); 75 | // 1 hzzzzzzzq 18 76 | ``` 77 | 78 | 我们怎么加入参数呢? 79 | 80 | 1. 我们要获取调用 bind 函数时除了第一个绑定对象以外的参数 81 | 2. 我们要获取内部返回函数的参数 82 | 83 | ```javascript 84 | Function.prototype.myBind = function (context) { 85 | let self = this; 86 | const args = [].slice.call(arguments, 1); // 获取从第二个开始的全部参数 87 | return function () { 88 | const subArgs = [].slice.call(arguments); // 获取 bind 返回函数的内部参数 89 | return self.apply(context, args.concat(subArgs)); 90 | }; 91 | }; 92 | ``` 93 | 94 | 第二版写完了。 95 | 96 | ## 第三版 - 作为构造函数使用的绑定函数 97 | 98 | 接下来就是构造函数啦,最难的部分了。 99 | 100 | > 绑定函数自动适应于使用 `new` 操作符去构造一个由目标函数创建的新实例。当一个绑定函数是用来构建一个值的,原来提供的 `this` 就会被忽略 101 | 102 | 我们来举个例子,看一下。 103 | 104 | ```javascript 105 | var value = 2; 106 | let obj = { 107 | value: 1, 108 | }; 109 | function log(name, age) { 110 | this.sport = 'playing'; 111 | console.log(this.value, name, age); 112 | } 113 | let print = log.bind(obj, 'hzzzzzzzq'); 114 | let obj2 = new print('18'); 115 | // undefined hzzzzzzzq 18 116 | console.log(obj2.sport); // playing 117 | ``` 118 | 119 | 从上面结果,我们可以看出,使用 `new` 进行创建新实例时,`this` 指向绑定的 `obj` 已经失效了,返回 `undefined`。 120 | 121 | 但是为什么不会指向全局变量呢?其实就是 `new` 操作,让现在的 `this` 指向了 `obj2`。 122 | 123 | 可以来看看 `new` 操作是怎么实现的,参考我的这篇文章 - [《JavaScript 深入之 new 操作》]()。 124 | 125 | ```javascript 126 | Function.prototype.myBind = function (context) { 127 | let self = this; 128 | const args = [].slice.call(arguments, 1); // 获取从第二个开始的全部参数 129 | const resultFn = function () { 130 | const subArgs = [].slice.call(arguments); // 获取调用时传入的参数 131 | return self.apply( 132 | this instanceof resultFn ? this : context, 133 | args.concat(subArgs) // 拼接参数 134 | ); 135 | }; 136 | resultFn.prototype = this.prototype; 137 | return resultFn; 138 | }; 139 | ``` 140 | 141 | 肯定有人会对这句代码有疑问 `this instanceof resultFn ? this : context`,我们来解释一下。 142 | 143 | 这里我们根据 `this` 与 `resultFn` 进行 `instanceof` 来判断是构造函数还是普通函数调用。 144 | 145 | - 构造函数,`this` 指向实例,判断结果为 `true`,将绑定函数的 `this` 指向该实例,可以让实例获得来自绑定函数的值。 146 | - 普通函数,`this` 指向 `window`,结果为 `false`,绑定函数的 `this` 指向 `context` 147 | 148 | 上面的代码真的实现了吗? 149 | 150 | 好像还不够,存在问题,那就是返回函数的值修改时,也会导致原函数值的修改。 151 | 152 | ```javascript 153 | let bindObj = log.myBind(null); 154 | bindObj.prototype.name = 'hzzzzzzzq'; 155 | console.log(obj.prototype.name); // hzzzzzzzq 156 | ``` 157 | 158 | ## 第四版 - 汇总 159 | 160 | 我们来汇总一下,我们实现 `bind` 函数的步骤。 161 | 162 | 我们还会对上面的问题进行优化 - 就是通过一个额外的函数进行中转。 163 | 164 | > 1. 判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可能出现使用 `call` 等方式调用的情况 165 | > 2. 保存当前函数的引用,获取其余传入参数值 166 | > 3. 创建一个函数返回 167 | > 4. 函数内部使用 `apply` 来绑定函数调用,需要判断函数作为构造函数的情况,这个时候需要传入当前函数的 `this` 给 `apply` 调用,其余情况都传入指定的上下文对象 168 | 169 | ```javascript 170 | Function.prototype.myBind = function (context) { 171 | if (typeof this !== 'function') { 172 | throw new Error('只有函数可以调用 myBind'); 173 | } 174 | const self = this; 175 | const args = [].slice.call(arguments, 1); 176 | const fn = function () {}; // 中转函数 177 | const resultFn = function () { 178 | const subArgs = [].slice.call(arguments); // 获取调用时传入的参数 179 | return self.apply( 180 | this instanceof fn ? this : context, 181 | args.concat(subArgs) // 拼接参数 182 | ); 183 | }; 184 | fn.prototype = self.prototype; 185 | resultFn.prototype = new fn(); 186 | return resultFn; 187 | }; 188 | ``` 189 | 190 | ## 文章参考 191 | 192 | [JavaScript 深入之 bind 的模拟实现](https://github.com/mqyqingfeng/Blog/issues/12) 193 | -------------------------------------------------------------------------------- /article/github-pages/4. gitalk和disgus评论.md: -------------------------------------------------------------------------------- 1 | # Hexo - next 主题下 配置 gitalk/Disqus 评论系统 2 | 3 | 因为在 next 主题下,都已经带有 gitalk 和 Disques 的配置了,所以不需要我们去修改主题内的文件,只与主题编辑文件有关。 4 | 5 | ## gitalk 设置 - 不需要科学上网 6 | 7 | ### 主要流程 8 | 9 | - 需要创建一个 Github 账号 - [创建地址](https://github.com/signup?source=login) 10 | - 创建一个 OAuth application - [创建地址](https://github.com/settings/applications/new) 11 | - 创建一个仓库用来放置评论内容 12 | - 修改主题配置文件下的 gitalk 13 | 14 | ### 我们现在开始分步操作教学 15 | 16 | - 创建账号就不用我多说啦。 17 | 18 | - 创建一个 OAuth application 19 | 20 | `Application name`:根据你自己来填即可 21 | 22 | `Homepage URL`:填写你的博客域名 23 | 24 | `Authorization callback URL`:还是填写你博客的域名 25 | 26 | ![image-20220119171611982](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220119171611982.png) 27 | 28 | 点击 Register application 之后,会进入这个页面,在这里 `Client ID` 和 `Client secrets` 两个值,是需要存下来的,一会儿要用。 29 | 30 | ![image-20220119172332985](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220119172332985.png) 31 | 32 | Client secrets 是需要自己创建一个的不会给你自动创建的,点击之后,就会创建一个。 33 | 34 | ![image-20220119172501736](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220119172501736.png) 35 | 36 | - 创建一个仓库 - [地址](https://github.com/new) 37 | 38 | ![image-20220120083817190](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220120083817190.png) 39 | 40 | `Repository name` 仓库名称 41 | 42 | 添加一个 `README file`,点击创建就可以了。 43 | 44 | 如果你看过我的第一篇文章[《hexo-githubPages》](),你就可以直接用你 `githubpages` 的仓库(`yourname.github.io`),不需要新建一个仓库了。 45 | 46 | - 我们来修改主题编辑文件-进行配置 47 | 48 | `enable`: 打开 gitalk 评论。 49 | 50 | `github_id`:就是仓库的拥有者,也就是你的 github 名称。 51 | 52 | `repo`:就是仓库,输入你的仓库名。 53 | 54 | `client_id`:就是我们刚刚创建 `OAuth Application` 之后,拿到的值。 55 | 56 | `client_secret`:也是我们刚刚拿到的值。 57 | 58 | `admin_user`:是你的仓库拥有者。 59 | 60 | `language`:修改语言。 61 | 62 | ![](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220120084754458.png) 63 | 64 | 配置完成之后,执行 65 | 66 | ```bash 67 | $ hexo clean && hexo g -d # 清理缓存并发布 68 | $ hexo s # 查看本地情况 69 | ``` 70 | 71 | 你在本地或者你部署的网站,找到一篇文章,拉到底部,会看到这样的情况。 72 | 73 | ![image-20220123104356814](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220123104356814.png) 74 | 75 | 点击登陆 `github` 即可。 76 | 77 | - 可能遇到错误 78 | 79 | > error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https%3A%2F%2Fdocs.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-authorization-request-errors%2F%23redirect-uri-mismatch 80 | 81 | 首先,确认是不是在本地点击的 `使用 Github 登陆`,如果本地,请先执行 `hexo d`,然后去部署的网站上点击登陆。如果还会有其他问题,[可以看一下 gitalk 可能出现问题的解决方案](https://developer.github.com/apps/managing-oauth-apps/troubleshooting-authorization-request-errors/#redirect-uri-mismatch)。 82 | 83 | - 最后成功结果 84 | 85 | ![image-20220125135325746](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220125135325746.png) 86 | 87 | ## Disqus 设置 - 需要科学上网才能显示 88 | 89 | - [Disqus 评论系统官网](https://disqus.com/) 90 | 91 | 如果您的评论会有许多人,可以选择一个订阅购买,但是如果人数较少,可以选择底下的 `Basic`. 92 | 93 | ![image-20220119141616333](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220119141616333.png) 94 | 95 | ![image-20220119141706654](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220119141706654.png) 96 | 97 | - 下一步,会让我们选择在哪个平台,而我们会发现没有 hexo,所以我们选择 `I don't see...` 98 | 99 | ![image-20220119142042285](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220119142042285.png) 100 | 101 | - 选择之后,就会出现 2.2 步骤,教您怎么安装程式码 102 | 103 | ![image-20220119142214404](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220119142214404.png) 104 | 105 | - 因为,我们需要的是 short-name,我们跳过这一步,直接来到第三步,是设置一些您要应用的网站留言板的相关设定,填写您想填的资料或是都不填也可以,但要记得 `Website Name` 不要改动,或是再另外改成你想要的即可 106 | 107 | ![image-20220119142457348](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220119142457348.png) 108 | 109 | - 然后我们点击 next 就来到最后一步了,选择评论的审核机制,具体的可以根据翻译选择。我们可以选择 `Balanced`。 110 | 111 | ![image-20220119142532859](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220119142532859.png) 112 | 113 | - 到此,我们已经完成 [Disqus](https://disqus.com/) `site` 的配置了,接下来,就是进入我们的 `next` 主题中的配置了。 114 | 115 | ![](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220119142808820.png) 116 | 117 | ## hexo - next 主题设置 118 | 119 | 在 next 主题中,以及为我们提供了 [next 主题下 Disqus 相关配置](https://theme-next.iissnan.com/third-party-services.html#disqus)。 120 | 121 | 我们只需要编辑**主题配置文件**下的内容就可以了 ,在配置文件中,搜索 Disques,找到下面的代码。 122 | 123 | ![image-20220119143343104](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220119143343104.png) 124 | 125 | - 将配置的 shortname 内容输入,并将 enable 修改为 true 即可 126 | 127 | - 然后我们执行 `hexo g -d` 就可以查看效果了,选择一篇文章,看最底部,就出现评论功能了。 128 | 129 | ![image-20220119144044662](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220119144044662.png) 130 | -------------------------------------------------------------------------------- /article/ES6/4. 字符串的扩展.md: -------------------------------------------------------------------------------- 1 | # 字符串的扩展 2 | 3 | ## 字符串的遍历 4 | 5 | ES6 中添加了字符串的遍历器接口,字符串就可以使用 `for...of` 来遍历了。 6 | 7 | ```javascript 8 | let s = 'Hello'; 9 | for (let c of s) { 10 | console.log(c); // H e l l o 11 | } 12 | ``` 13 | 14 | ## `JSON.stringify()` 和 `JSON.parse()` 15 | 16 | 在有时候,我们需要将一个 `JSON` 格式的数据,转成字符串进行页面传递。 17 | 所以这时候采用 `JSON.stringify()` 进行序列化。然后传递,在目的页面使用 `JSON.parse()` 转为 `JavaScript` 对象。在进行大数据传递时,时常需要。 18 | 19 | ```javascript 20 | let person = { 21 | name: 'hzzzzzzzq', 22 | age: 18, 23 | height: 1.8, 24 | weight: 140, 25 | skills: ['JavaScript'], 26 | }; 27 | let s = JSON.stringify(person); 28 | console.log(s); 29 | // {"name":"hzzzzzzzq","age":18,"height":1.8,"weight":140,"skills":["JavaScript"]} 30 | 31 | let str = JSON.parse(s); 32 | console.log(str); 33 | // { 34 | // "name": "hzzzzzzzq", 35 | // "age": 18, 36 | // "height": 1.8, 37 | // "weight": 140, 38 | // "skills": [ 39 | // "JavaScript" 40 | // ] 41 | // } 42 | ``` 43 | 44 | ## 模版字符串 45 | 46 | 什么是模版字符串呢?简单来说,其实就是加强版的字符串,使用 ( **`** )作为标识符 。可以作为普通的字符串使用,也可以用来定义多行字符串,或者在字符串中使用变量。 47 | 48 | 我们来看看使用普通字符串时 是怎么进行换行,或者加入变量的。 49 | 50 | ```javascript 51 | let name = 'hzzzzzzzq'; 52 | let age = 18; 53 | let info = 'my name is ' + name + '\n my age is ' + age; 54 | console.log(info); 55 | // my name is hzzzzzzzq 56 | // my age is 18 57 | ``` 58 | 59 | 然后我们再来看看模版字符串的写法。 60 | 61 | ```javascript 62 | let name = 'hzzzzzzzq'; 63 | let age = 18; 64 | let info = `my name is ${name} 65 | my age is ${age}`; 66 | console.log(info); 67 | // my name is hzzzzzzzq 68 | // my age is 18 69 | ``` 70 | 71 | 换行,直接就使用回车就可以换行,你输入的样子是怎样的,打印基本上就是怎样的。 72 | 73 | 变量采用 `${}` 来嵌入,也可以直接写入一个字符串中,少写了许多没必要的 `+` 号。 74 | 75 | ## 字符串中的新增方法 76 | 77 | 在这里就列举一些常用的实例方法 78 | 79 | ### includes() 80 | 81 | `includes()` 实例方法,返回的是一个布尔值(`true`和`false`),**表示是否找到了参数字符串**。 82 | 参数二来表示开始搜索的位置。 83 | 84 | ```javascript 85 | let s = 'Hello hzzzzzzzq'; 86 | console.log(s.includes('Hello')); // true 87 | console.log(s.includes('x')); // false 88 | console.log(s.includes('zzzzzzz')); // true 89 | console.log(s.includes('H', 2)); // false 90 | ``` 91 | 92 | ### startsWith()、endsWith() 93 | 94 | - **startsWith()** 95 | `startsWith()` 返回也是布尔值,**表示参数是否在原字符串的头部**。 96 | 第二参数也表示开始搜索的位置。 97 | 98 | ```javascript 99 | let s = 'Hello hzzzzzzzq'; 100 | console.log(s.startsWith('Hello')); // true 101 | console.log(s.startsWith('e')); // false 102 | // 表示从 1 开始 103 | console.log(s.startsWith('Hello', 1)); // false 104 | ``` 105 | 106 | - **endsWith()** 107 | `endsWith()` 返回也是布尔值,**表示参数是否在原字符串的尾部**。 108 | 注意:这里的第二参数表示的是到 n 为止,不像 `startsWith()` 是从 `n` 开始到字符串结尾。 109 | 110 | ```javascript 111 | let s = 'Hello hzzzzzzzq'; 112 | console.log(s.endsWith('q')); // true 113 | console.log(s.endsWith('zzzzq')); // true 114 | // 表示看前 5 个字符 115 | console.log(s.endsWith('o', 5)); // true 116 | // 表示看前 4 个字符 117 | console.log(s.endsWith('o', 4)); // false 118 | ``` 119 | 120 | ### repeat() 121 | 122 | `repeat()` 返回一个新字符串,表示将原字符串重复 `n` 次。 123 | 124 | - 如果传入的是小数,则会往下取整。 125 | - 传入参数不能是 `Infinity` 和 小于 `-1` 的值 126 | - `0` 到 `-1` 之间的小数,则按照等同于 `0` 来计算。 127 | - `NaN` 会被转为 `0` 128 | - 参数是字符串则先转为数字,如果不能转为数字,则为 `0` 129 | 130 | ```javascript 131 | let s = 'a'; 132 | console.log(s.repeat(4)); // 'aaaa' 133 | console.log(s.repeat(3.6)); // 'aaa' 134 | console.log(s.repeat(-0.6)); // '' 135 | console.log(s.repeat('aaa')); // '' 136 | ``` 137 | 138 | ### padStart、padEnd() 139 | 140 | 两个实例方法,就是用于字符串的补齐。 141 | **第一参数表示想要字符串的长度,第二参数表示字符串没达到第一参数时使用参数二字符串进行补齐。** 142 | 143 | - **padStart()** 144 | 很明显,`Start`,就是在字符串的头部补全。 145 | 146 | ```javascript 147 | let s = 'aaa'; 148 | // 如果原长度大于或等于想要补齐长度,则不生效。 149 | console.log(s.padStart(2, 'b')); // aaa 150 | console.log(s.padStart(10, 'b')); // bbbbbbbaaa 151 | // 如果补齐字符串长度大于剩余格数,则会省略后面字符串 152 | console.log(s.padStart(4, 'bcde')); // baaa 153 | // 如果,第二参数无内容,则使用空格补齐 154 | console.log(s.padStart(4)); // ' aaa' 155 | ``` 156 | 157 | - **padEnd()** 158 | `End` 就是在字符串的尾部补全。 159 | 160 | ```javascript 161 | let s = 'aaa'; 162 | // 如果原长度大于或等于想要补齐长度,则不生效。 163 | console.log(s.padEnd(2, 'b')); // aaa 164 | console.log(s.padEnd(10, 'b')); // aaabbbbbbb 165 | // 如果补齐字符串长度大于剩余格数,则会省略后面字符串 166 | console.log(s.padEnd(4, 'bcde')); // aaab 167 | // 如果,第二参数无内容,则使用空格补齐 168 | console.log(s.padEnd(4)); // 'aaa ' 169 | ``` 170 | 171 | ### trimStart()、trimEnd() 172 | 173 | 这两个实例都是用来**去除字符串空格用的**。 174 | 175 | ```javascript 176 | let s = ' x '; 177 | // start 去除前面空格 178 | console.log(s.trimStart()); // 'x ' 179 | // end 去除后面空格 180 | console.log(s.trimEnd()); // ' x' 181 | ``` 182 | 183 | ### replaceAll() 184 | 185 | `replaceAll()` 实例方法是用来替换字符串中的字符用的。 186 | 187 | 在提到这个之前,我们先看看 `replace()` ,**参数一是被替换的值,参数二是替换值**,简单来讲就是,**参数二用来替换参数一**。 188 | 189 | ```javascript 190 | let s = 'abcabc'; 191 | console.log(s.replace('a', 'x')); // xbcabc 192 | ``` 193 | 194 | `replace()` 只能替代一个,是第一个遇到的。 195 | 196 | 那我们来看看 `replaceAll()`,是全部替换。 197 | 198 | ```javascript 199 | let s = 'abcabc'; 200 | console.log(s.replaceAll('a', 'x')); // xbcxbc 201 | ``` 202 | 203 | 这里是简单的用法,当然在 `replaceAll()` 第二参数还可以传入一个函数,具体可以看看 [MDN 的 replaceAll()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll) 204 | -------------------------------------------------------------------------------- /article/JavaScript/1. JavaScript深入之原型与原型炼.md: -------------------------------------------------------------------------------- 1 | # 原型与原型链 2 | 3 | ## 原型 4 | 5 | ### 构造函数创建对象 6 | 7 | 我们来写一个构造函数用来创建一个对象 8 | 9 | ```javascript 10 | function Person() {} 11 | let person = new Person(); 12 | person.name = 'hzzzzzzzq'; 13 | console.log(person.name); // hzzzzzzzq 14 | ``` 15 | 16 | 从例子中,我们使用 `new` 创建了一个实例对象 `person`。 17 | 18 | 这我们都是可以理解的,`new` 创建实例对象。 19 | 20 | ### prototype 21 | 22 | 每一个函数都有一个 `prototype` 属性,那么这个属性指向什么呢? 23 | 24 | 其实,函数的 `prototype` 属性指向了一个对象,这个对象就是调用该构造函数而创建的实例的原型,也就是例子中,`person` 的原型。 25 | 26 | 我们来打印一下 `Person` 的 `prototype`,来看看是什么。 27 | 28 | ```javascript 29 | function Person() {} 30 | 31 | console.log(Person.prototype); 32 | ``` 33 | 34 | ![prototype1](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/js/prototype1.png) 35 | 36 | 说了这么多,还是不知道什么是原型(0_o)。我们可以这样来理解原型:每一个 JS 对象(null 除外)在创建的时候就会有一个与之关联的另一个对象,而这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。 37 | 38 | 我们简单来表示一下构造函数与实例原型之间的关系: 39 | 40 | ![prototype2](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/js/prototype2.png) 41 | 42 | 我们从这张图中,可以看出,`Object.prototype` 表示实例原型。 43 | 那么我们该怎么表示实例(`person`)与实例原型(`Person.prototype`)之间的关系呢?所以我们来看看第二个属性 44 | 45 | ### `__proto__` 46 | 47 | 这是每一个 JS 对象(除了 `null`) 都具有的一个属性,叫 `__proto__`,这个属性会指向该对象的原型。 48 | 49 | 我们来验证一下。 50 | 51 | ```javascript 52 | function Person() {} 53 | let person = new Person(); 54 | console.log(person.__proto__ === Person.prototype); 55 | // true 56 | console.log(person.__proto__ === Object.getPrototypeOf(person)); // true 57 | ``` 58 | 59 | **注意: 当然,在这里我们要提一嘴,`__proto__` 在 `web` 标准中,以及删除,但是一些浏览器目前还是支持的。** 60 | 61 | > 所以在这里,我顺便提一个 `Object.getPrototypeOf(Object)`,用来获取实例的原型。 62 | 63 | 于是,我们可以将图进行更新了: 64 | 65 | ![prototype3](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/js/prototype3.png) 66 | 67 | 我们现在,构造函数指向原型,实例指向原型,那么原型能否指向构造函数或者指向实例呢? 68 | 69 | 其实这时候我们就要提到下一个属性了,但是,指向实例的是没有的,因为一个构造函数可以生成多个实例。 70 | 71 | ### constructor 72 | 73 | 这是我们提到的第三个属性了,而这个属性,就是用来实现由原型指向构造函数,每一个原型都会有一个 `constructor` 属性来指向关联的构造函数。 74 | 75 | ```javascript 76 | function Person() {} 77 | 78 | console.log(Person === Person.prototype.constructor); 79 | // true 80 | ``` 81 | 82 | 所以我们继续更新关系图: 83 | 84 | ![prototype4](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/js/prototype4.png) 85 | 86 | 到目前为止,我们已经得出来一些结论了。 87 | 88 | ```javascript 89 | function Person() {} 90 | let person = new Person(); 91 | console.log(person.__protp__ === Person.prototype); //true 92 | console.log(Person.prototype.constructor === Person); // true 93 | ``` 94 | 95 | 了解了构造函数、实例原型和实例之间的关系后,我们来看看实例和原型的关系: 96 | 97 | ### 实例与原型 98 | 99 | 在我们读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就会去找原型的原型,直到最顶层为止。 100 | 101 | ```javascript 102 | function Person() {} 103 | Person.prototype.name = 'hzzzzzzzq'; 104 | 105 | let person = new Person(); 106 | 107 | person.name = 'qzzzzzzzh'; 108 | coonsole.log(person.name); // qzzzzzzzh 109 | 110 | delete person.name; 111 | coonsole.log(person.name); // hzzzzzzzq 112 | ``` 113 | 114 | 从例子来看,我们给原型对象添加了 `name` 属性,然后在给实例对象添加了 `name` 属性,而首先打印时,打印了实例对象的 `name`。 115 | 116 | 但是当我们删除了实例对象的 `name` 属性时,在实例中就找不到该属性,则会从实例的原型是那个去查找,所以在 `Person.prototype` 中找到。 117 | 118 | 但是,如果我们的原型中没找到呢?原型的原型又是什么呢? 119 | 120 | ### 原型的原型 121 | 122 | 原型是什么?其实原型也是一个对象,既然是对象,那我们就可以用 `new Object()` 来创建它: 123 | 124 | ```javascript 125 | let obj = new Object(); 126 | obj.name = 'hzzzzzzzq'; 127 | console.log(obj.name); // hzzzzzzzq 128 | ``` 129 | 130 | 而我们再来看一下,Person.prototype 与 Object 的关系. 131 | 132 | ```javascript 133 | function Person() {} 134 | console.log(Person.prototype.__proto__ === Object.prototype); // true 135 | ``` 136 | 137 | 其实原型对象就是通过 `Object` 构造函数生成的,实例的 `__proro__` 指向构造函数的 `prototype`,现在我们再来更新一下关系图: 138 | 139 | ![prototype5](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/js/prototype5.png) 140 | 141 | ## 原型链 142 | 143 | 其实,看完原型的原型,还是会有疑问,Object.prototype 的原型是什么呢? 144 | 145 | 其实就是 `null`,我们可以来验证一下: 146 | 147 | ```javascript 148 | console.log(Obejct.prototype.__proto__ === null); 149 | // true 150 | ``` 151 | 152 | 而 `null` 是什么呢? 153 | 154 | > null 就是表示"没有对象",即在这里不应该有值。 155 | 156 | 因为 `Object.prototype.__proto__` 的值为 `null`。所以查找属性的时候其实查到 `Object.prototype` 就可以停止了。 157 | 158 | 我们在来更新一下关系图: 159 | 160 | ![prototype6](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/js/prototype6.png) 161 | 162 | 那什么是原型链呢?相互关联的原型组成的链状结构就是原型链,也就是这条红色的线。 163 | 164 | ## 补充 165 | 166 | 你以为这就结束了吗? 167 | 168 | 我们来看看在来补充一些神奇的事情,我们来看看打印。 169 | 170 | ```javascript 171 | function Person() {} 172 | console.log(Person.__proto__ === Function.prototype); // true 173 | console.log(Object.prototype.constructor.__proto__ === Function.prototype); //true 174 | console.log(Object.prototype === Function.prototype.__proto__); // true 175 | ``` 176 | 177 | 经过测试我们会发现,都会 `true`。 178 | 179 | 这意味着什么呢? 180 | 181 | - `Person` 函数的原型是 `Function.prototype` 182 | - `Function.prototype` 也是 `Object` 构造函数的 `__proto__` 183 | - `Function.prototype.__proto__` 就是 `Object.prorotype` 184 | 185 | 于是,我们的图就可以更新为如下关系图: 186 | 187 | ![prototype7](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/js/prototype7.png) 188 | 189 | 至此,我们的关系图已经基本完善。 190 | 191 | 再次,我也需要补充一张找到的图,应该说,真的很好,因为我自己画的比较乱。(0_o) 192 | 193 | ![prototype8](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/jsprototype8.png) 194 | 195 | ## 下一篇文章 196 | 197 | [JavaScript 深入之执行栈]() 198 | -------------------------------------------------------------------------------- /article/JavaScript/8. JavaScript深入之call和apply函数.md: -------------------------------------------------------------------------------- 1 | # call/apply 2 | 3 | ## call bind apply 的区别 4 | 5 | 首先,我们先来了解一下 `call`,`apply`,`bind` 的区别,方便我们去手写实现自己的 `call、apply、bind`。 6 | 7 | | 区别 | bind | call | apply | 8 | | ------------ | ------------------------------ | ------------------------------ | ------------------------------ | 9 | | 是否立即调用 | 否 | 是 | 是 | 10 | | 参数一 | 指定的对象(该函数的执行上下文 | 指定的对象(该函数的执行上下文 | 指定的对象(该函数的执行上下文 | 11 | | 其他参数 | 后面的参数都是传入函数的值 | 后面的参数都是传入函数的值 | 只有两个参数,第二个参数是数组 | 12 | 13 | ## call 实现 14 | 15 | 我们可以分为七个步骤: 16 | 17 | > 1. 判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可能出现使用 `call` 等方式调用的情况 18 | > 2. 判断传入上下文对象是否存在,如果不存在,则设置为 `window` 19 | > 3. 处理传入的参数,截取第一个参数后的所有参数 20 | > 4. 将函数作为上下文对象的一个属性 21 | > 5. 使用上下文对象来调用这个方法,并保存返回结果 22 | > 6. 删除刚才新增的属性 23 | > 7. 返回结果 24 | 25 | ### 第一版 26 | 27 | `call` 在使用一个指定的 `this` 值和若干个指定的参数值的前提下调用某个参数或方法。 28 | 29 | ```javascript 30 | let value = 1; 31 | const foo = { 32 | value: 2, 33 | }; 34 | function fn() { 35 | console.log(this.value); 36 | } 37 | fn.call(foo); // 2 38 | ``` 39 | 40 | 我们来看看步骤: 41 | 42 | - 第一步就不用多说了,你可以直接使用一个 `Object` 对象去调用试一下,是抛出了一个错误的,这里我们用打印来表示。 43 | - 第二步就是获取该方法的上下文对象,并调用这个方法了。 44 | - 第三步就是删除新增的属性。 45 | 46 | ```javascript 47 | Function.prototype.myCall = function (context) { 48 | if (typeof this !== 'function') { 49 | console.log('只有函数可以调用 myCall'); 50 | return; 51 | } 52 | context.fn = this; 53 | context.fn(); 54 | delete context.fn; 55 | }; 56 | ``` 57 | 58 | 这时候我们会发现打印结果对上了,也是 `2`。 59 | 60 | ### 第二版 61 | 62 | 接下来就是处理参数了,从区别可以知道,`call` 是可以有无数参数的,我们在第二步之前添加一个步骤。 63 | 64 | 先来看看真实 `call` 的测试。 65 | 66 | ```javascript 67 | let value = 1; 68 | const foo = { 69 | value: 2, 70 | }; 71 | function fn(name, age) { 72 | console.log(this.value); 73 | console.log(name); 74 | console.log(age); 75 | } 76 | fn.call(foo, 'hzzzzzzzq', 18); 77 | // 2 78 | // hzzzzzzzq 79 | // 18 80 | ``` 81 | 82 | - 获取第二个参数开始的全部参数 83 | 84 | ```javascript 85 | Function.prototype.myCall = function (context) { 86 | if (typeof this !== 'function') { 87 | console.log('只有函数可以调用 myCall'); 88 | return; 89 | } 90 | let args = [...arguments].slice(1); // 截取参数 91 | context.fn = this; 92 | context.fn(...args); // 给函数传入参数 93 | delete context.fn; 94 | }; 95 | ``` 96 | 97 | 使用我们的 `myCall` 执行,发现结果是相同的。 98 | 99 | ### 最后版 100 | 101 | 在这里我们需要注意两个问题 102 | 103 | - 传入的对象是 `null` 104 | 105 | 注意,我将外层的定义 `let` 改成了 `var`,因为 `var` 设置了全局变量,如果设置 `let` 则会打印 `undefined`,并没有在 `window` 对象中定义。 106 | 107 | ```javascript 108 | var value = 1; 109 | const foo = { 110 | value: 2, 111 | }; 112 | function fn(name, age) { 113 | console.log(this.value); 114 | } 115 | fn.call(null); // 1 116 | ``` 117 | 118 | 执行代码,可以知道,传入 `null` 时,指向了我们的 `window` 对象。 119 | 120 | - 对象可以有返回值 121 | 122 | ```javascript 123 | var value = 1; 124 | const foo = { 125 | value: 2, 126 | }; 127 | function fn(name, age) { 128 | return { 129 | value: this.value, 130 | name, 131 | age, 132 | }; 133 | } 134 | const result = fn.call(foo, 'hzzzzzzzq', 18); 135 | console.log(result); 136 | // { 137 | // value: 2, 138 | // name: 'hzzzzzzzq', 139 | // age: 18 140 | // } 141 | ``` 142 | 143 | - 最后代码全代码 144 | 145 | 首先处理传入 null 的时候,判断传入上下文对象是否存在,如果不存在,则设置为 `window`。 146 | 处理第二个问题则是将方法执行结果进行保留,返回结果。 147 | 148 | ```javascript 149 | Function.prototype.myCall = function (context) { 150 | if (typeof this !== 'function') { 151 | // 判断,在手写过程中 可以不需要 152 | console.log('只有函数可以调用 myCall'); 153 | return; 154 | } 155 | context = context || window; // 判断上下文对象是否存在 156 | context.fn = this; // 将函数作为上下文的一个属性 157 | let args = [...arguments].slice(1); // 获取传入的参数,从第二个参数起的所有参数 158 | const result = context.fn(...args); // 执行该函数,并使用上面的参数 159 | delete context.fn; // 删除新增对象 160 | return result; // 返回结果 161 | }; 162 | ``` 163 | 164 | 测试一下我们自己写的 `call` 代码 165 | 166 | ```javascript 167 | var value = 2; 168 | let obj = { 169 | value: 1, 170 | }; 171 | function test(name, age) { 172 | console.log(this.value); 173 | return { 174 | value: this.value, 175 | name: name, 176 | age: age, 177 | }; 178 | } 179 | console.log(test.myCall(obj, 'hzq', 18)); 180 | // 1 181 | // { 182 | // "value": 1, 183 | // "name": "hzq", 184 | // "age": 18 185 | // } 186 | ``` 187 | 188 | ## apply 实现 189 | 190 | 我们首先了解了三者的区别,我们发现 `apply` 与 `call` 的区别,就在于传入的参数,针对这一区别,我们开始实现 `apply`,就只需要对 `call` 的代码进行部分修改即可。 191 | 192 | > 1. 判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可能出现使用 `call` 等方式调用的情况 193 | > 2. 判断传入上下文对象是否存在,如果不存在,则设置为 `window` 194 | > 3. 将函数作为上下文对象的一个属性 195 | > 4. 判断参数值是否传入 196 | > 5. 使用上下文对象来调用这个方法,并保存返回结果 197 | > 6. 删除刚才新增的属性 198 | > 7. 返回结果 199 | 200 | ```javascript 201 | Function.prototype.myApply = function (context, arr) { 202 | if (typeof this !== 'function') { 203 | console.log('只有函数可以调用 myApply'); 204 | return; 205 | } 206 | context = context || window; 207 | context.fn = this; 208 | let result = null; 209 | if (!arr) { 210 | // 数组没有值时,直接调用 211 | result = context.fn(); 212 | } else { 213 | // 数组有值,传入参数 214 | result = context.fn(...arr); 215 | } 216 | delete context.fn; 217 | return result; 218 | }; 219 | ``` 220 | 221 | 测试与 `call` 类似,只是修改了传入参数为数组, 打印结果相同。 222 | 223 | ```javascript 224 | console.log(test.myApply(obj, ['hzq', 18])); 225 | ``` 226 | 227 | ## 文章参考 228 | 229 | [JavaScript 深入之 call 和 apply 的模拟实现](https://github.com/mqyqingfeng/Blog/issues/11) 230 | -------------------------------------------------------------------------------- /article/Git/2. git 实践.md: -------------------------------------------------------------------------------- 1 | # git 实践 2 | 3 | 今天来一篇 `git` 的在实际开发过程中的操作。 4 | 5 | ## 拷贝 6 | 7 | - 先到自己想要放项目的目录之下 8 | 9 | ![image](https://user-images.githubusercontent.com/66205484/145941855-ee376157-ea50-4815-b072-f6e17388bf3c.png) 10 | 11 | - 然后拷贝项目,后面的 `url` 放置自己的项目地址 12 | 当然,可能会进行密码输入之类的问题 比如 **GitHub 不再支持密码验证解决方案:SSH 免密与 Token 登录配置**。 13 | 这时候的链接,可能是需要 `SSH` 命令的 `git@github.com:hzzzzzzzq/git-application-docs.git`。 14 | 15 | ```bash 16 | git clone https://github.com/hzzzzzzzq/git-application-docs.git 17 | # 或者 18 | git clone git@github.com:hzzzzzzzq/git-application-docs.git 19 | 20 | # 拷贝之后我们 cd 到目录文件 21 | cd git-application-docs 22 | ``` 23 | 24 | ![image](https://user-images.githubusercontent.com/66205484/145945033-c6a0cd8d-fd48-48df-8c70-493dafe38e90.png) 25 | 26 | 现在,就是我们 `clone` 下来的项目。 27 | 28 | ## 提交和推送 29 | 30 | - 先添加想要加入的文件夹 31 | 我们这里加入 `git` 文件夹,以及 `branchTry.md` 用于分支合并,和 `gitTry.md` 用于 `git` 提交等。 32 | ![image](https://user-images.githubusercontent.com/66205484/145945306-950914ca-082a-4277-aa98-59ed75dfd584.png) 33 | 34 | - 将添加的文件加入**暂存区** 35 | 36 | ```bash 37 | # 单个文件添加 38 | git add git/gitTry.md 39 | 40 | # 全部一起添加 41 | git add . 42 | 43 | # 如果该文件被忽略,则需要添加 -f 强制添加 44 | git add -f git/branchTry.md 45 | ``` 46 | 47 | - 然后使用 `git commit` 提交 48 | `git commit` 是将文件提交到本地仓库,用来记录本次修改的内容 49 | 50 | ```bash 51 | git commit -m "feat: 添加文件" 52 | ``` 53 | 54 | ![image](https://user-images.githubusercontent.com/66205484/145946832-6365b89f-1bbc-49db-bdee-b629e38da6a5.png) 55 | 56 | 其中包含了修改的文件内容。 57 | 58 | **补充:提交信息的规范** 59 | 60 | > feat: 新功能 61 | > fix: 修补 bug 62 | > docs: 文档修改 63 | > style: 格式修改 64 | > refactor: 重构 65 | > merge: 合并 66 | 67 | - 提交本地仓库代码到远端仓库 68 | 69 | ```bash 70 | git push 71 | ``` 72 | 73 | ![image](https://user-images.githubusercontent.com/66205484/145946928-94db41fa-ce35-4c8d-b89f-a90e624bfb7e.png) 74 | 75 | `git push` 提交远端仓库的结果。 76 | 77 | ## 分支管理 78 | 79 | - 创建一个新分支,并切换入该分支 80 | `feat-branch` 是分支名,这里基本是按照功能来命名。 81 | 82 | ```bash 83 | git checkout -b feat-branch 84 | ``` 85 | 86 | - 切换分支 87 | 88 | ```bash 89 | # main 就是你要切换的分支名 90 | # 切回主分支 91 | git checkout main 92 | ``` 93 | 94 | - 删除分支 95 | 96 | ```bash 97 | # feat-branch 就是想要删除的分支名称 98 | # 因为该分支还需要使用,就不做操作了。 99 | git branch -d feat-branch 100 | ``` 101 | 102 | - 将分支提交到远端分支 103 | 104 | ```bash 105 | git push git@github.com:hzzzzzzzq/git-application-docs.git feat-branch 106 | ``` 107 | 108 | ![image](https://user-images.githubusercontent.com/66205484/145948538-7a1b1cfa-68a2-4331-93c1-b7ccd4233e4b.png) 109 | 110 | 这时候,在远端仓库中,就可以看到该分支了。 111 | 112 | ![image](https://user-images.githubusercontent.com/66205484/145948592-28bfcf8d-bbc9-4bd4-abea-3677f5166223.png) 113 | 114 | ## 拉取 115 | 116 | 一个项目经常是多个人一起进行开发的,当别人提交代码时,我们就需要拉取他人的代码了。这时候 `git pull` 的作用就来了。 117 | 118 | ```bash 119 | git pull 120 | ``` 121 | 122 | 为了演示 `git pull`,我在这边新建一个 `git` 本地仓库,用来演示共同开发时的拉取以及冲突。 123 | 124 | `clone` 一个新项目,我们然后对文件进行部分修改,然后进行提交。 125 | 126 | ![image](https://user-images.githubusercontent.com/66205484/145949740-f16e3a5f-37a0-4a9e-84d0-d949b81250a4.png) 127 | 128 | ![image](https://user-images.githubusercontent.com/66205484/145949825-3bdd4f02-b9d4-4fff-b7e1-5acef06fcb0b.png) 129 | 130 | 接下来,我们重新切回到我们之前的文件,然后进行 `git pull`。 131 | 132 | ```bash 133 | # 切换原项目 134 | cd ../git-application-docs 135 | 136 | # 切到 main 分支 137 | git checkout main 138 | 139 | # 拉取远端代码 140 | git pull 141 | ``` 142 | 143 | ![image](https://user-images.githubusercontent.com/66205484/145950387-c9287701-4fa0-45fe-b4fe-40fbd0536277.png) 144 | 145 | ## 合并与冲突 146 | 147 | 在 `main` 分支下,修改标题内容。 148 | 149 | ![image](https://user-images.githubusercontent.com/66205484/145951381-1dcf6294-2fed-4604-b1b7-15ff41c8e38d.png) 150 | 151 | 然后提交。 152 | 153 | ![image](https://user-images.githubusercontent.com/66205484/145951973-5b9d95a9-e398-4cf5-a918-cb87aacf7106.png) 154 | 155 | 切换到 `feat-branch`,并修改同文件的标题,并提交。 156 | 157 | ```bash 158 | # 切分支 159 | git checkout feat-branch 160 | # 添加到暂存区 161 | git add . 162 | # 提交 163 | git commit -m "feat: change branch title" 164 | # 推送到远端 165 | git push 166 | ``` 167 | 168 | ![image](https://user-images.githubusercontent.com/66205484/145952854-b3002d2b-5002-403e-9911-351e77114f98.png) 169 | 170 | - 合并 171 | 172 | 我们切回 `main` 分支,然后将 `feat-branch` 合并到 `main` 分支。 173 | 174 | ```bash 175 | # 切分支 176 | git checkout main 177 | # 合并 178 | git merge feat-branch 179 | # 没有冲突的情况,直接推送即可 180 | git push 181 | ``` 182 | 183 | 如果合并没有问题,就可以直接进行 `push` 操作。 184 | 但是,由于我们在两个分支,同时对同一个文件的同一个地方进行了修改,于是,就产生了以下问题,`merge` 失败,有冲突。 185 | 186 | ![image](https://user-images.githubusercontent.com/66205484/145953252-68c50a45-491c-45e4-8fe0-9547b848bf2e.png) 187 | 188 | - 冲突 189 | 190 | 我们需要打开文件夹,我们发现一些奇奇怪怪的符号,这些就是冲突的标识,我们需要对冲突进行处理。 191 | 将文件进行修改,调整到你希望的样子。并对全局进行检查是否,还有其他冲突文件。 192 | 193 | 我们看到有 `<<<<<<` 以及 `======` 因为在 `.md` 文件中,我打开了源形式,否则可能看不到 `=====` 或者 `<` 被转化。 194 | 195 | ![image](https://user-images.githubusercontent.com/66205484/145954659-f1b01667-b998-4dfb-876a-bc0df63ce0f7.png) 196 | 197 | 现在我演示一下,我想保留 `feat-branch` 的内容,则删除 `main` 分支的内容。 198 | 将 `main` 分支内容删除之后的样子。 199 | ![image](https://user-images.githubusercontent.com/66205484/145954865-71a2a7a6-a0d4-4ddf-b1aa-1bc3fa2e5225.png) 200 | 201 | - 提交推送 202 | 203 | ```bash 204 | # 添加冲突文件到暂存区 205 | git add . 206 | # 提交到本地 207 | git commit -m "merge: 合并冲突" 208 | # 推送到远端 209 | git push 210 | ``` 211 | 212 | ![image](https://user-images.githubusercontent.com/66205484/145955245-05b5c18b-88b0-41c1-a84a-e44d255ea3c0.png) 213 | 214 | 这时,我们在远端仓库 `main` 分支下,看到的就是我们 `feat-branch` 分支中的内容了。 215 | 216 | ## 提交记录 217 | 218 | - git log 查看提交记录 219 | 220 | ```bash 221 | git log 222 | ``` 223 | 224 | ![image](https://user-images.githubusercontent.com/66205484/145955543-29fc882d-7a25-418c-9e9e-35bd77ccd8c4.png) 225 | 226 | - 只看某个人的提交记录 227 | 这里结果是一样的,因为都是我自己完成的。 228 | 229 | ```bash 230 | git log --author=hzzzzzzzq 231 | ``` 232 | -------------------------------------------------------------------------------- /article/CSS/9. css3 新特性.md: -------------------------------------------------------------------------------- 1 | # css3 新特性 - 常用 2 | 3 | 我们来聊聊 `css3` 的一些新特性,但是不会仔细的去讲,会让你们了解一个大概,具体的可以自行去 `MDN` 查看。 4 | 5 | ## 圆角 - border-radius 6 | 7 | 圆角,顾名思义,其实就是个格子的四个角设置圆角,设置方式也很简单。就简简单单提一下。 8 | 9 | ```css 10 | .main { 11 | width: 100px; 12 | height: 100px; 13 | border-radius: 10px; 14 | } 15 | ``` 16 | 17 | 我们来看效果,其实就是四个角设置一个弧度。 18 | 19 | ![图1. border-radius](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/html/image-20220115143358046.png) 20 | 21 | ## 阴影 - box-shadow 22 | 23 | 在 `css3` 中,增加了阴影,以前的实现只能用图片,或者在添加一个阴影格子来实现。 24 | 25 | ### 语法 26 | 27 | 语法很简单,就是直接使用 `box-shadow` 来设置。 28 | 29 | ```css 30 | .shadow { 31 | box-shadow: 水平阴影位置偏移 | 垂直阴影位置偏移 | 模糊距离 | 阴影大小 | 32 | 阴影颜色 | 阴影开始方向; 33 | } 34 | ``` 35 | 36 | ### 例子 37 | 38 | ```css 39 | .main { 40 | width: 100px; 41 | height: 100px; 42 | background-color: #f2cda5; 43 | box-shadow: 5px 5px 10px #999; 44 | } 45 | ``` 46 | 47 | ![图2. box-shadow](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/html/image-20220115144035655.png) 48 | 49 | ## 过渡效果 - transition 50 | 51 | 什么是过渡呢?其实很好理解,类似于动画,在两个切换之间,让它看起来有一个过渡。 52 | 53 | 我们来举个例子,鼠标放上时变色。 54 | 55 | ```css 56 | .main { 57 | width: 100px; 58 | height: 100px; 59 | background-color: #f2cda5; 60 | } 61 | .main:hover { 62 | background-color: #1890ff; 63 | transition: all 2s; /* 设置一个两秒的过渡 */ 64 | } 65 | ``` 66 | 67 | 我们来看看效果吧。 68 | 69 | ![图3. transition](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/html/%E5%B1%8F%E5%B9%95%E5%BD%95%E5%88%B62022-01-15%20%E4%B8%8B%E5%8D%883.gif) 70 | 71 | 很明显,有了一个缓慢变色的过程,这就是过渡。 72 | 73 | ## 翻转 - transform 74 | 75 | transform 允许我们做一些旋转、缩放、倾斜或平移给定元素。这是通过修改 CSS 视觉格式化模型的坐标空间来实现的。 76 | 77 | 我们也举一个简单的例子,就是翻转。 78 | 79 | ```css 80 | .main { 81 | width: 100px; 82 | height: 100px; 83 | background-color: #f2cda5; 84 | transform: rotate(45deg); 85 | } 86 | ``` 87 | 88 | 在这里,我们添加了 `rotate` 对元素进行翻转 `45度` 角。 89 | 90 | 我们来看看结果吧,就是这么神奇。 91 | 92 | ![图4. transform](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/html/image-20220115151143676.png) 93 | 94 | ## 动画 - animation 95 | 96 | [MDN 中的定义](https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Animations/Using_CSS_animations)。 97 | 98 | > **CSS animations** 使得可以将从一个 CSS 样式配置转换到另一个 CSS 样式配置。动画包括两个部分:描述动画的样式规则和用于指定动画开始、结束以及中间点样式的关键帧 99 | 100 | 我们还是使用一个简单的例子来演示一下旋转、变色、放大。 101 | 102 | ```css 103 | .main { 104 | width: 20px; 105 | height: 20px; 106 | background-color: #f2cda5; 107 | animation: turnAround 2s ease 0s infinite; 108 | } 109 | @keyframes turnAround { 110 | 0% { 111 | transform: rotate(0deg); 112 | width: 30px; 113 | height: 30px; 114 | } 115 | 25% { 116 | transform: rotate(45deg); 117 | background-color: #f8dca3; 118 | width: 40px; 119 | height: 40px; 120 | } 121 | 50% { 122 | transform: rotate(90deg); 123 | background-color: #c6ce93; 124 | width: 50px; 125 | height: 50px; 126 | } 127 | 75% { 128 | transform: rotate(135deg); 129 | background-color: #95b5c0; 130 | width: 60px; 131 | height: 60px; 132 | } 133 | 100% { 134 | transform: rotate(180deg); 135 | background-color: #1890ff; 136 | width: 70px; 137 | height: 70px; 138 | } 139 | } 140 | ``` 141 | 142 | 我们来看看实现动画的效果。 143 | 144 | ![animation]() 145 | 146 | ## 媒体查询 - @media 147 | 148 | 媒体查询,第一次听到肯定很多人都觉得很奇特,那么它是做什么的呢? 149 | 150 | 具体的可以去查看 [MDN 媒体查询](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Media_Queries/Using_media_queries),我们来看看上面对媒体查询的解释。 151 | 152 | > **媒体查询**(**Media queries**)非常实用,尤其是当你想要根据设备的大致类型(如打印设备与带屏幕的设备)或者特定的特征和设备参数(例如屏幕分辨率和浏览器视窗\宽度)来修改网站或应用程序时。 153 | 154 | 当然理论很难理解,我们举一个简单的例子。 155 | 156 | 我们来看看代码。 157 | 158 | ```css 159 | .main { 160 | height: 200px; 161 | width: 200px; 162 | background-color: #f2cda5; 163 | } 164 | @media screen and (max-width: 600px) { 165 | /* 媒介查询,最大宽度小于等于 600 时,显示的样式 */ 166 | .main { 167 | background-color: #95b5c0; 168 | } 169 | } 170 | ``` 171 | 172 | ```html 173 |
174 | ``` 175 | 176 | 我们来看看结果。 177 | 178 | ![图.6 媒介查询 media 结果](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/html/%E5%B1%8F%E5%B9%95%E5%BD%95%E5%88%B62022-01-15%20%E4%B8%8B%E5%8D%882.gif) 179 | 180 | 可以看到,在宽度 `600` 的时候,颜色发生了变化,所以,媒体查询 `max-width` 定义了,宽度最大 `600` 或以下生效。 181 | 182 | ## 弹性盒子 - flex 183 | 184 | `flex` 布局,在这里就不进行赘述了,在我的 [flex](https://github.com/hzzzzzzzq/Blog/issues/28) 文章中,已经详细进行叙说了,有兴趣的可以直接去看。在这里,我就直接放一下 `flex` 的属性了。 185 | 186 | ### 容器属性 187 | 188 | - flex-direction: 决定了**主轴的方向**。 189 | - flex-wrap:设置在轴线上是否进行换行。 190 | - flex-flow:属性就是 `flex-direction` 和 `flex-wrap` 两个属性的简写方式,默认值为 `row nowrap`。 191 | - justify-content:用来设置项目在主轴方向上的对齐方式 192 | - align-items:用来设置项目在交叉轴方向上的对齐方式 193 | - align-centent:用来设置多根轴线的对齐方式,如果只有一根轴线,则不起作用。 194 | 195 | ### 项目属性 196 | 197 | - order:调整项目的排列顺序,数值越小,排列在越前面,默认为 `0`。 198 | - flex-grow:定义了项目的放大比例,默认为 `0`,如果空间又剩余,也不放大 199 | - flex-shrink:定义了项目的缩小比例,默认为 `1`,如果空间不足,该项目会缩小。 200 | - flex-basis:定义了分配多余空间之前,项目占据的主轴空间。默认值为 `auto`,即项目的本来大小。 201 | - flex: `flex-grow`,`flex-shrink`,`flex-basis` 三个属性的缩写,默认值为 `0 1 auto` 202 | - align-self:允许单个 `item` 可以有其他项目不一样的对齐方式,可以覆盖容器属性中 `align-items` 属性,默认值为 `auto`。 203 | 204 | ## 参考资料 205 | 206 | 1. [个人总结(css3 新特性)](https://segmentfault.com/a/1190000010780991) 207 | 2. [MDN transform](https://developer.mozilla.org/zh-CN/docs/Web/CSS/transform) 208 | 3. [MDN transition](https://developer.mozilla.org/zh-CN/docs/Web/CSS/transition) 209 | 4. [MDN 动画 animation](https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Animations/Using_CSS_animations) 210 | 5. [MDN 媒体查询](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Media_Queries/Using_media_queries) 211 | 6. [myBlog - flex](https://github.com/hzzzzzzzq/Blog/issues/28) 212 | -------------------------------------------------------------------------------- /article/面试题目/CSS/flex相关面试题.md: -------------------------------------------------------------------------------- 1 | 记录题目: 6,29,38,46 2 | 3 | ### 6. flex:1 的完整写法是? 分别是什么意思? 4 | 5 | Flex: 1 1 auto; 6 | 7 | 利用 flex:1 可以实现三个不同内容的 div 平分空间 8 | 9 | ```html 10 | 28 |
    29 |
  • 1
  • 30 |
  • 2
  • 31 |
  • 3
  • 32 |
  • 4
  • 33 |
34 | ``` 35 | 36 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210424153913452.png) 37 | 38 | #### 6.2 flex 属性 39 | 40 | flex 属性 flex-grow、flex-shrink、flex-basis 的简写,默认值为 0,1,auto 41 | 42 | - flex-grow 定义项目的放大比例,默认为 0,即如果存在剩余空间,也不放大 43 | - Flex-shrink 定义了项目的缩小比例,默认为 1,即如果空间不足,该项目将缩小 44 | - Flex-basis 给上面两个属性分配多余空间之前,计算项目是否有多余空间,默认为 auto,即项目本身的大小 45 | 46 | #### 6.3 flex:1 完整写法 47 | 48 | Flex:1 的完整写法是 49 | 50 | ```css 51 | flex-grow: 1; 52 | flex-shrink: 1; 53 | flex-basis: auto; 54 | ``` 55 | 56 | #### 6.4 flex 赋值情况 57 | 58 | - Flex:none 59 | 60 | ```css 61 | flex-grow: 0; 62 | flex-shrink: 0; 63 | flex-basis: auto; 64 | ``` 65 | 66 | - Flex:auto 67 | 68 | ```css 69 | flex-grow: 1; 70 | flex-shrink: 1; 71 | flex-basis: auto; 72 | ``` 73 | 74 | - Flex: 非负数字 75 | 76 | 该数字为 flex-grow 的值,flex-shrink 为 1,flex-basis 为 0% 77 | 78 | ```css 79 | flex-grow: 1; 80 | flex-shrink: 1; 81 | flex-basis: 0%; 82 | ``` 83 | 84 | - flex 取值为一个长度或百分比 85 | 86 | 这时这个值则视为是 flex-basis 的值,flex-grow 为 1,flex-shrink 为 1 87 | 88 | ```css 89 | .item { 90 | flex: 0%; 91 | } 92 | /* 等价于 */ 93 | .item { 94 | flex-grow: 1; 95 | flex-shrink: 1; 96 | flex-basis: 0%; 97 | } 98 | 99 | .item2 { 100 | flex: 10px; 101 | } 102 | /* 等价于 */ 103 | .item2 { 104 | flex-grow: 1; 105 | flex-shrink: 1; 106 | flex-basis: 10px; 107 | } 108 | ``` 109 | 110 | - Flex 取两个非负数字 111 | 112 | 这时则视为 flex-grow 和 flex-shrink 的值,flex-basis 为 0% 113 | 114 | ```css 115 | .item { 116 | flex: 2 3; 117 | } 118 | /* 等价于 */ 119 | .item { 120 | flex-grow: 2; 121 | flex-shrink: 3; 122 | flex-basis: 0%; 123 | } 124 | ``` 125 | 126 | - Flex 取值为一个非负数字和一个长度或百分比 127 | 128 | 这时则视为 flex-grow 和 flex-basis 的值,flex-shrink 的值为 1. 129 | 130 | ### 29. flex 布局,如何实现把八个元素分成两行摆放 131 | 132 | - 父盒子排序方式为 flex-start,从起点开始放置盒子;通过 flex-wrap 设置换行 133 | - 子盒子设置,设置 flex: 0 0 25%,flex 属性是 flex-grow,flex-shrink,flex-basis 的简写,默认值是 0 1 auto 134 | - flex-grow:默认值 0,不放大 135 | - flex-shrink:默认值 0,不缩小 136 | - flex-basis:项目占据主轴的空间 137 | 138 | ```html 139 | 155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 | ``` 166 | 167 | ### 38. 介绍下 flex 布局,属性都有哪些,都是干啥的 168 | 169 | #### 父元素属性 170 | 171 | - display:flex 定义了一个 flex 容器 172 | - Flex-direction 决定主轴的方向 173 | - row 默认值,水平从左到右 174 | - column 垂直从上倒下 175 | - row-reverse 水平从右到左 176 | - column-reverse 水平从下到上 177 | - flex-wrap 定义如何换行 178 | - nowrap 默认值,不换行 179 | - wrap 换行 180 | - wrap-reverse 换行,且颠倒行顺序,第一行在下方 181 | - flex-flow 属性是 flex-direaction 属性 和 flex-wrap 属性的简写形式,默认值是 row nowrap 182 | - justify-content 设置主轴方向上的对齐方式 183 | - flex-start 默认值,弹性盒子元素将向行起始位置对齐 184 | - flex-end 弹性盒子元素将向行结束为止对齐 185 | - center 弹性盒子元素将向行中间位置对齐。改行的子元素将相互对齐并在行中居中对齐 186 | - space-between 弹性盒子元素会平均地分布在行里,左右定到界面 187 | - space-around 弹性盒子元素会平均地分布在行里,两端保留子元素和子元素之间间距大小的一半 188 | - align-items 设置或检索弹性盒子子元素在侧轴方向上的对齐方式 189 | - flex-start 弹性盒子元素的侧轴起始位置的边界紧靠住该行的侧轴起始边界 190 | - flex-end 弹性盒子元素的侧轴起始位置的边界紧靠住该行的侧轴结束边界 191 | - center 侧轴 居中 192 | - baseline 如果弹性盒子元素的行内轴与侧轴为同一条,则该值与 flex-start 等效。其他情况下,该值将参与基线对齐 193 | - stretch 如果指定侧轴大小的属性值为:auto,则其值会使项目的边距盒的尺寸尽可能接近所在行的尺寸,但同时会遵照‘min/max-width/height’ 属性的限制 194 | - align-content 设置或检索弹性盒堆叠伸缩行的对齐方式 195 | - flex-start 196 | - flex-end 197 | - center 198 | - space-between 199 | - space-around 200 | - stretch 201 | 202 | #### 子元素上属性 203 | 204 | - .order 默认情况下 flex order 会按照书写顺序呈现,可以通过 order 属性改变,数值小的在前面,还可以是负数 205 | - flex-grow 设置或检索弹性盒的扩展比率,根据弹性盒子元素所设置的扩展因子作为比率来分配剩余空间 206 | - flex-shrink 设置或检索弹性盒的收缩比率,根据弹性盒子元素所设置的收缩因子作为比率来收缩空间 207 | - flex-basis 设置或检索弹性盒伸缩基准值,如果所以子元素的基准值之和大于剩余空间,则会根据每项设置的基准值,按比率伸缩剩余空间 208 | - flex flex 属性是 flex-grow,flex-shrink,flex-basis 的简写,默认值为 0 1 auto。后两个属性可选。 209 | - align-self 设置或检索弹性盒子元素在侧轴方向上的对齐方式,可以覆盖父容器 align-items 的设置 210 | 211 | ### 46. space-between 和 space-around 的区别 212 | 213 | space-between 使每个块之间产生相同的间隔,但是不会跟容器之间产生 214 | 215 | ![image-20210422090155036](/Users/hzq/Library/Application Support/typora-user-images/image-20210422090155036.png) 216 | 217 | space-around 则会在每个块的两边产生一个相同大小的间隔,也就是说最外层块和容器之间的间隔大小刚好是两块之间间隔大小的一半 218 | 219 | ![image-20210422090257273](/Users/hzq/Library/Application Support/typora-user-images/image-20210422090257273.png) 220 | 221 | ```html 222 | 243 |
244 |
245 |
246 |
247 |
248 | ``` 249 | -------------------------------------------------------------------------------- /article/ES6/10. 三种异步之Generator函数.md: -------------------------------------------------------------------------------- 1 | # Generator 函数 2 | 3 | ## 介绍 4 | 5 | `Generator` 是 `ES 6` 提供的一种异步编程解决方案。 6 | 7 | - 函数定义时,在 `funciton` 后面添加一个星号(`*`) 8 | - 函数体内部使用 `yield` 表达式 9 | 10 | ```javascript 11 | // 普通函数 12 | function a() {} 13 | 14 | // Generator 15 | function* generator() { 16 | yield 'hello'; 17 | yield 'hzzzzzzzq'; 18 | return 'good'; 19 | } 20 | ``` 21 | 22 | `Generator` 函数的调用方式与普通函数是一样的,在函数名后面加上一对圆括号。 23 | 24 | ### yield 表达式 25 | 26 | `yield` 表达式就是 `Generator` 的暂停标志。 27 | 28 | - 遇到 `yield` 表达式,就会停止执行后面的操作,`yield` 后面表达式的值,作为返回对象的 `value` 属性值 29 | - 下次调用 `next` 方法时,才会继续执行代码,直到下一个 `yield` 30 | - 如果没有遇到遇到 `yield`,则运行至结束,看是否有 `return`,如果有,则 `return` 后面的值作为返回对象的 `value` 31 | - 如果没有 `yield` 或 `return`,则返回 `value` 为 `undefined` 32 | 33 | ```javascript 34 | function* generator() { 35 | yield 'hello'; // 第一个 next 时,执行 36 | yield 'hzzzzzzzq'; // 第二个 next 时,执行 37 | return 'good'; // 第三个 next 时,执行 38 | } 39 | ``` 40 | 41 | 在上面的代码中,我们可以来感受上面的用途。 42 | 43 | 只有在调用 `next` 方法将指针移到这一句时,才会进行求值。 44 | 45 | 与 `return` 不同的地方在于,`return` 不具备记忆功能,也就说,在一个函数中,`return` 只能执行一次,而 yield 具备记忆功能,可以通过 `next` 方法继续执行代码。 46 | 47 | ## next 方法 48 | 49 | ### next 普通使用 50 | 51 | `next` 方法就是 `generator` 函数的内置执行器,如果遇到 `yield` 时,只有通过调用 `next`,才会继续执行代码。 52 | 53 | 而 `next` 代码的执行值,我们可以打印来看,会是一个对象,带有 `value` 和 `done` 两个属性。 54 | 55 | ```javascript 56 | function* generator() { 57 | yield 'hello'; 58 | yield 'hzzzzzzzq'; 59 | return 'good'; 60 | } 61 | 62 | const gen = generator(); 63 | console.log(gen.next()); // { value: 'hello', done: false } 64 | console.log(gen.next()); // { value: 'hzzzzzzzq', done: false } 65 | console.log(gen.next()); // { value: 'good', done: true } 66 | console.log(gen.next()); // { value: undefined, done: true } 67 | ``` 68 | 69 | - `value` 值显示的是 `yield` 或者 `return` 后面的返回值。 70 | - `done` 是一个布尔值,表示遍历是否结束,`true` 表示结束。 71 | - 当然,`return` 只能有一个,且 `return` 之后不能有 `yield`,因为 `return`,就会让 `done` 变成 `true`。 72 | 73 | ### next 方法参数 74 | 75 | `next` 方法可以带一个参数,**该参数会被当作上一个 `yield` 表达式的值**。 76 | 77 | ```javascript 78 | function* generator() { 79 | while (true) { 80 | let value = yield null; 81 | console.log(value); 82 | } 83 | } 84 | const gen = generator(); 85 | console.log(gen.next()); 86 | console.log(gen.next('world')); 87 | // { value: null, done: false } 88 | // world 89 | // { value: 'null', done: false } 90 | ``` 91 | 92 | 当然,这个是会被当作上一个 `yield` 表达式的值,是在函数内部使用,并不是在 `next` 返回对象中作为 `value` 的键值返回。他会替换 `generator` 函数体内的上一个 `yield` 值并赋值给我们定义的变量 `value`。 93 | 94 | ## for...of 循环 95 | 96 | `for...of` 循环可以自动遍历 `Generator` 函数运行时生成的 `Interator` 对象,不需要手动调用 `next` 方法。 97 | 98 | ```javascript 99 | function* gen() { 100 | yield 'one'; 101 | yield 'two'; 102 | yield 'three'; 103 | yield 'four'; 104 | return 'five'; 105 | } 106 | for (let v of gen()) { 107 | console.log(v); 108 | } 109 | // one two three four 110 | ``` 111 | 112 | 注意:如果 `done` 为 `true`,则会被立刻终止,所有最后一句 `return` 语句不在循环中。 113 | 114 | 处理 `for...of` 循环之外,扩展运算符,解构赋值和 `Array.from` 方法内部调用的,都是遍历器接口。 115 | 都可以将 `Generator` 函数作为返回的 `Interator` 对象,作为参数。 116 | 117 | ```javascript 118 | function* gen() { 119 | yield 'one'; 120 | yield 'two'; 121 | yield 'three'; 122 | yield 'four'; 123 | return 'five'; 124 | } 125 | console.log([...gen()]); 126 | // ['one', 'two', 'three', 'four'] 127 | 128 | console.log(Array.from(gen())); 129 | // ['one', 'two', 'three', 'four'] 130 | 131 | let [x, y, z] = gen(); 132 | console.log(x, y, z); 133 | // one two three 134 | ``` 135 | 136 | ## yield\* 137 | 138 | `yield*` 就是 用来在一个 `Generator` 函数里面执行另一个 `Generator` 函数。 139 | 140 | ```javascript 141 | function* generator1() { 142 | yield 'hello'; 143 | yield 'hzzzzzzzq'; 144 | yield 'good'; 145 | } 146 | function* generator() { 147 | yield* generator1(); 148 | } 149 | const gen = generator(); 150 | console.log(gen.next().value); // hello 151 | console.log(gen.next().value); // hzzzzzzzq 152 | console.log(gen.next().value); // good 153 | console.log(gen.next().value); // undefined 154 | ``` 155 | 156 | 我们在 `generator` 函数中,使用了 `yield*` ,后面调用 `generator1` 函数。 157 | 158 | 然后我们就可以直接使用 `next` 函数,跟普通的 `generator` 函数一样使用就可以。 159 | 160 | ## Generator.prototype.throw() / return() 161 | 162 | ### throw() 163 | 164 | `Generator` 函数返回的遍历器对象,都会有个 `throw` 方法,可以在函数体外抛出错误,然后在 `Generator` 函数体内捕获。 165 | 166 | ```javascript 167 | function* generator() { 168 | try { 169 | yield 1; 170 | } catch (e) { 171 | console.log('内部', e); 172 | } 173 | } 174 | let gen = generator(); 175 | gen.next(); 176 | try { 177 | gen.throw('错误1'); 178 | gen.throw('错误2'); 179 | } catch (e) { 180 | console.log('外部', e); 181 | } 182 | // 内部 错误1 183 | // 外部 错误2 184 | ``` 185 | 186 | 在上面的例子中,我们可以看出,第一个 `throw` 被函数体内部的 `catch` 语句捕获,然而第二个错误,在内部已经执行过 `catch`,所有这个错误就被抛出来了,被外面的 `try...catch` 捕获。 187 | 188 | ### return() 189 | 190 | `Generator` 函数返回的对象中,还有一个 `return` 方法,可以返回给定的值,并且结束 `Generator` 函数。 191 | 192 | ```javascript 193 | function* generator() { 194 | yield 'hello'; 195 | yield 'hzzzzzzzq'; 196 | yield 'good'; 197 | } 198 | const gen = generator(); 199 | gen.next(); // { value: 'hello', done: false } 200 | gen.return('world'); // { value: 'world', done: true } 201 | gen.next(); // { value: undefined, done: true } 202 | ``` 203 | 204 | 从上面的例子,我们可以看出,执行 `return` 之后,后面的 `done` 就会变为 `true`,且传入的参数会作为返回对象的 `value` 值。 205 | 206 | 在以后调用时,都会被调整为 `undefined`,其实就相当于,将 `generator` 函数中的添加一个 `return` 。 207 | 208 | ## Generator 函数的异步操作 209 | 210 | 我们使用一个 `readFile`,使用 `setTimeout` 假装调用接口,然后调用 `gen.next()` 接口返回对象的 `value` 属性值进行下一步操作。 211 | 212 | ```javascript 213 | const readFile = function (fileName, ms) { 214 | return new Promise((resolve, reject) => { 215 | setTimeout(() => { 216 | resolve('异步请求成功回调'); // 需要给 `Promise` 一个状态转化,就是异步执行是否成功 217 | }, ms); 218 | }); 219 | }; 220 | 221 | function* generator() { 222 | const str = yield readFile('fileName1', 1000); 223 | console.log(str); 224 | } 225 | const gen = generator(); 226 | const result = gen.next(); // fileName1 227 | result.value 228 | .then((val) => { 229 | console.log(val); 230 | return val; 231 | }) 232 | .then((val2) => { 233 | gen.next('异步请求结果'); 234 | }); 235 | // 异步请求成功回调 236 | // 异步请求结果 237 | ``` 238 | 239 | `yield` 后面用来调用异步函数,然后返回结果输出。 240 | -------------------------------------------------------------------------------- /article/面试题目/浏览器和网络/网络常考面试题.md: -------------------------------------------------------------------------------- 1 | ## 1. http 2 | 3 | **超文本传输协议(HTTP)**是一个用于传输超媒体文档(例如 HTML)的[应用层](https://en.wikipedia.org/wiki/Application_Layer)协议。它是为 Web 浏览器与 Web 服务器之间的通信而设计的,但也可以用于其他目的。HTTP 遵循经典的[客户端-服务端模型](https://en.wikipedia.org/wiki/Client–server_model),客户端打开一个连接以发出请求,然后等待直到收到服务器端响应。HTTP 是[无状态协议](http://en.wikipedia.org/wiki/Stateless_protocol),这意味着服务器不会在两个请求之间保留任何数据(状态)。尽管通常基于 TCP/IP 层,但它可以在任何可靠的[传输层](https://zh.wikipedia.org/wiki/传输层)上使用,也就是说,该协议不会像 UDP 那样静默的丢失消息。[RUDP](https://en.wikipedia.org/wiki/Reliable_User_Datagram_Protocol)——作为 UDP 的可靠化升级版本——是一种合适的替代选择。 4 | 5 | 总结一下: 6 | 7 | HTTP 是一个应用层协议,用于浏览器和服务器之间通信,通常基于 TCP/IP 层,但是可以在任何传输层上使用。 8 | 9 | ## 2. https 10 | 11 | ## 3. http 与 https 区别 12 | 13 | HTTP 传输的数据都是未加密的,也就是明文的,HTTPS 协议是由 HTTP 和 SSL 协议构建的可进行加密传输和身份认证的网络协议,比 HTTP 协议的安全性更高。 14 | HTTPS 协议需要 CA 证书,费用较高; 15 | 使用不同的链接方式,端口也不同,一般而言,HTTP 协议的端口为 80,HTTPS 的端口为 443; 16 | 17 | ## 4. http1.1 与 http 1.0 区别 18 | 19 | - 长连接,1.0 打开 tcp/ip 后只发送一个请求,发送完后关闭。1.1 如果制定了 connection:keep-alive(默认),则可以发起 http 请求 20 | - 分块发送 head 和 body,为了节省带宽,1.0 如果 token 过期了,整个报文发送给接收端,返回 401,链接终止。这样请求报文太大,可以先发送 html head 试探,如果是 401 没必要继续发送 body 21 | - 新增 host 字段 22 | - 新增`Chunked transfer-coding`,范围请求,实现断点续传(实际上就是利用 HTTP 消息头使用分块传输编码,将实体主体分块传输) 23 | - 请求管道化,Pipeling 解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,因为传输格式是文本的,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞 24 | 25 | ## 5. HTTP2.0 和 HTTP1.1 的区别 26 | 27 | - 二进制分帧 28 | 29 | - 头部压缩:使用 HPACK 对 HTTP/2 头部压缩 30 | 31 | - 服务器推送 32 | 33 | - **多路复用**:最重要的特点,(MultiPlexing),即连接共享,即每一个 request 都是是用作连接共享机制的。一个 request 对应一个 id,这样一个连接上可以有多个 request,每个连接的 request 可以随机的混杂在一起,接收方可以根据 request 的 id 将 request 再归属到各自不同的服务端请求里面。 34 | 35 | 多个请求可同时在一个连接上并行执行(由于支持二进制的格式,可以无序)某个请求任务耗时严重,不会影响到其它连接的正常执行 36 | http2 与 http1.1 相比有如下几个优点 37 | 38 | - 解析速度快 39 | 40 | 服务器解析 Http1.1 的请求时,必须不断地读入字节,直到遇到分隔符 CRLF 为止。而解析 HTTP2 的请求就不用这么麻烦,因为 HTTP2 是基于帧的协议,每个帧都有表示帧长度的字段 41 | 42 | - 多路复用 43 | 44 | Http1.1 如果要同时发起多个请求,就得建立多个 TCP 连接,因为一个 TCP 连接同时只能处理一个 HTTP。1 的请求。 45 | 46 | 在 HTTP2 上,多个请求可以共用一个 TCP 连接,这称为多路复用。同一个请求和响应用一个流来表示,并有唯一的流 ID 来标识。 47 | 48 | 多个请求和响应在 TCP 连接中可以乱序发送,到达目的地后在通过流 ID 重新组建 49 | 50 | - 首部压缩 51 | 52 | Http2 提供了首部压缩功能,http2 在客户端和服务端使用“首部表”来跟踪和存储之前发送的键值对。对于相同的数据,不再通过每次请求和响应发送。 53 | 54 | - 优先级 55 | 56 | Http2 可以对比较紧急的请求设置一个较高的优先级,服务器在收到这样的请求后,可以优先处理 57 | 58 | - 流量控制 59 | 60 | 由于一个 TCP 连接流量带宽(根据客户端到服务器的网络带宽而定)是固定的,当有多个请求并发时,一个请求占的流量多,另一个请求占的流量就会少。流量控制可以对不同的的流的流量进行精确控制 61 | 62 | - 服务器推送 63 | 64 | HTTP2 新增的一个强大的新功能,就是服务器可以对一个客户端请求发送多个响应。换句话说,除了对最初请求的响应外,服务器还可以额外向客户端推送资源,而无需客户端明确地请求 65 | 66 | 例如当浏览器请求一个网站时,除了返回 HTML 页面外,服务器还可以根据 HTML 页面中的资源的 URL,来提前推送资源。 67 | 68 | ## 6.TCP 的三次握手和四次挥手 69 | 70 | 三次握手 71 | 72 | 第一次握手:客户端发送一个 SYN 码给服务器,要求建立数据连接; 73 | 第二次握手: 服务器 SYN 和自己处理一个 SYN(标志);叫 SYN+ACK(确认包);发送给客户端,可以建立连接 74 | 第三次握手: 客户端再次发送 ACK 向服务器,服务器验证 ACK 没有问题,则建立起连接; 75 | 76 | 四次挥手 77 | 78 | 第一次挥手: 客户端发送 FIN(结束)报文,通知服务器数据已经传输完毕; 79 | 第二次挥手: 服务器接收到之后,通知客户端我收到了 SYN,发送 ACK(确认)给客户端,数据还没有传输完成 80 | 第三次挥手: 服务器已经传输完毕,再次发送 FIN 通知客户端,数据已经传输完毕 81 | 第四次挥手: 客户端再次发送 ACK,进入 TIME_WAIT 状态;服务器和客户端关闭连接; 82 | 83 | ## 7. 为什么建立连接是三次握手,而断开连接是四次挥手呢? 84 | 85 | 建立连接的时候, 服务器在 LISTEN 状态下,收到建立连接请求的 SYN 报文后,把 ACK 和 SYN 放在一个报文里发送给客户端。 86 | 而关闭连接时,服务器收到对方的 FIN 报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送 FIN 报文给对方来表示同意现在关闭连接,因此,己方 ACK 和 FIN 一般都会分开发送,从而导致多了一次。 87 | 88 | ## 8. get 和 post 区别 89 | 90 | HTTP 协议中的两种发送请求的方法。 91 | HTTP 是什么? HTTP 是基于 TCP/IP 的关于数据如何在万维网中如何通信的协议。 92 | HTTP 的底层是 TCP/IP。所以 GET 和 POST 的底层也是 TCP/IP,也就是说,GET/POST 都是 TCP 链接。GET 和 POST 能做的事情都是一样的。你要给 GET 加上 request body,给 POST 带上 url 参数,技术上完全行得通的。 93 | 94 | GET 和 POST 的一个大区别, 95 | 96 | - GET 产生一个 TCP 数据包;POST 产生两个 TCP 数据包 97 | 98 | - 对于 GET 方式的请求,浏览器会把 `http header` 和 `data` 一并发送出去,服务器响应 200(返回数据); 99 | - 对于 POST,浏览器先发送 `header`,服务器响应 `100 continue`,浏览器再发送 `data`,服务器响应 `200 ok` 100 | 101 | 也就是说,GET 只需要汽车跑一趟就把货送到了,而 POST 得跑两趟,第一趟,先去和服务器打个招呼"嗨,我等下要送一批货来,你们打开门迎接我",然后再回头把货送过去。 102 | 103 | 因为 POST 需要两步,时间上消耗的要多一点,看起来 GET 比 POST 更有效。因此 Yahoo 团队有推荐用 GET 替换 POST 来优化网站性能。但这是一个坑!跳入需谨慎。为什么? 104 | 105 | 1. GET 与 POST 都有自己的语义,不能随便混用。 106 | 2. 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的 TCP 在验证数据包完整性上,有非常大的优点 107 | 3. 并不是所有浏览器都会在 POST 中发送两次包,Firefox 就只发送一次 108 | 109 | - get 参数通过 url 传递,post 放在请求体中 110 | - get 请求在 url 中传递的参数是有长度限制的,而 post 没有 111 | - get 比 post 更不安全,因为参数直接暴露在 url 中,所以不能用来传递敏感信息 112 | - get 请求只能进行 url 编码,而 post 支持多种编码方式 113 | - get 请求参数会被完整保留在浏览器记录里,而 post 参数不会 114 | - get 产生一个 TCP 数据包;post 产生两个 TCP 数据包 115 | get 请求,浏览器会吧 http header 和 data 一并发出,服务器响应 200 116 | post,浏览器先发送 header,服务器响应 100 continue,浏览器再发送 data,服务器响应 200 ok 117 | 118 | ## 9. POST 一定会发送两个 HTTP 请求么 119 | 120 | **先说结论,并不是一定,但是大部分是。** 121 | 122 | 这个涉及到客户端的实现,一般来说,HTTP 请求大致可以分为“请求头”个“请求体”两个部分,一般来说使用 HTTP 时候会默认约定,所有控制类的请求信息放在请求头中,具体数据放在请求体里面。 123 | 124 | 那么服务端在解析的时候总是会先解析请求头,然后再去决定当前请求如何处理。 125 | 126 | 所有一般浏览器的方案为: 127 | 128 | - 客户端先发送所有请求头的数据给服务器,服务器如果通过,返回 100-continue 字节码,客户端再继续发送请求体。 129 | 130 | 这样子做好处在于,如果请求体过大,请求一旦失败,浪费大量带宽,如果先发送请求头,直接返回报错,我们就不需要再次发送请求体了,节省带宽。 131 | 132 | 坏处在于会多一次 Round Trip,如果请求体的数据刚好也不多呢?那么也许一次发送会更好。 133 | 134 | 因此,很多客户端(浏览器、移动设备等等)会做一些优化,比如内部设定一次 POST 请求的数据超过 1KB 就将请求头和请求体分开发送,如果不超过则一次性发送完成。 135 | 136 | 甚至,客户端可以做一些策略,加入之前请求的发送成功率很高,那么就总是全部一起发送,如果失败率很高,则全部分开发送,等到成功率上来了,再改动策略。 137 | 138 | 因此到底是否一次发送两个 HTTP 请求,这并非是 GET 和 POST 的本质区别(很多人愿意将其成为 GET 和 POST 之间的本质区别)无论发几次,这都是客户端的策略而已,是一种实现的优化。 139 | 140 | ## 10. 状态码 141 | 142 | 状态码表示了响应的⼀个状态,可以让我们清晰的了解到这⼀次请求是成功还 是失败,如果失败的话,是什么原因导致的,当然状态码也是⽤于传达语义 的。如果胡乱使⽤状态码,那么它存在的意义就没有了 143 | 144 | - 1XX continue 145 | 100 continue,继续 146 | 101 切换协议 147 | - 2XX 成功 148 | 200 OK ,表示从客户端发来的请求在服务器端被正确处理 149 | 204 No content ,表示请求成功,但响应报⽂不含实体的主体部分 150 | 205 Reset Content ,表示请求成功,但响应报⽂不含实体的主体部分,但是与 204 响应不同在于要求请求⽅重置内容 151 | 206 Partial Content ,进⾏范围请求 152 | - 3XX 重定向 153 | 301 moved permanently ,永久性重定向,表示资源已被分配了新的 URL 154 | 302 found ,临时性重定向,表示资源临时被分配了新的 URL 155 | 303 see other ,表示资源存在着另⼀个 URL ,应使⽤ GET ⽅法获取资源 156 | 304 not modified ,表示服务器允许访问资源,但因发⽣请求未满⾜条件的情况 157 | 307 temporary redirect ,临时重定向,和 302 含义类似,但是期望客户端保持请求 ⽅法不变向新的地址发出请求 158 | - 4XX 客户端错误 159 | 400 bad request ,请求报⽂存在语法错误 160 | 401 unauthorized ,表示发送的请求需要有通过 HTTP 认证的认证信息 161 | 403 forbidden ,表示对请求资源的访问被服务器拒绝 162 | 404 not found ,表示在服务器上没有找到请求的资源 163 | - 5XX 服务器错误 164 | 500 internal sever error ,表示服务器端在执⾏请求时发⽣了错误 165 | 501 Not Implemented ,表示服务器不⽀持当前请求所需要的某个功能 166 | 502 错误网关 167 | 503 service unavailable ,表明服务器暂时处于超负载或正在停机维护,⽆法处理请 求 168 | 504 响应超时 169 | -------------------------------------------------------------------------------- /article/CSS/6. css优先级.md: -------------------------------------------------------------------------------- 1 | # css 优先级 2 | 3 | 我们来介绍一下 `css` 优先级,当然这时候,要拿出我收藏的宝图了。 4 | 5 | ![priority1](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/priority/priority1.png) 6 | 7 | 当然,这图一开始不仔细看,肯定是懵的,所以可以先收藏图片,看完文章,再回头看图片,就可以掌握 `css` 优先级了。 8 | 9 | ## 什么是权重 10 | 11 | - 权重决定了 `css` 规则怎样被浏览器解析,关系到 `css` 规则如何显示 12 | - 许多样式被应用到同一个元素上时,权重可以决定那种样式生效 13 | - 每种选择器都有字的权重,权重可以由不同的选择器加权计算 14 | - 多种选择器同时应用到同一个元素上时,权重高者生效 15 | 16 | 为了方便记忆,我们按照下面来对各种选择器的权重值进行假设。 17 | 18 | > ∞ 无穷大 -- !important 19 | > 10000 -- 行内样式 20 | > 1000 -- id 选择器 21 | > 100 -- 属性/class/伪类选择器 22 | > 10 -- 元素选择器/伪元素 23 | > 1 -- 通配符选择器 24 | 25 | ## ![priority2](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/priority/priority2.png)样式重复多写 26 | 27 | 在设置样式时,重复使用同一个 `css` 样式,后面的会覆盖前面的样式,并不是整个进行替换,而是对相同的 `css` 规则进行覆盖,我们举个例子。 28 | 29 | ```css 30 | .box { 31 | width: 300px; 32 | height: 300px; 33 | background-color: #efcca1; 34 | } 35 | /* 颜色会在 这条生效 */ 36 | .box { 37 | background-color: #1890ff; 38 | } 39 | ``` 40 | 41 | ```html 42 |
43 | ``` 44 | 45 | ![priority3](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/priority/priority3.png) 46 | 47 | 后面的 `css` 规则颜色,覆盖了上面的背景颜色。 48 | 49 | ## 不同的选择器,权重值高生效 50 | 51 | 权重值假设我们已经在上面做过了,可以看顶部。 52 | 53 | 我们使用 `id` 选择器,和 `class` 选择器来举例。 54 | 55 | `id` 选择器权重值为 `1000`,`class` 是 `100`。所以生效应该是 `id` 选择器 `css` 规则 56 | 57 | ```css 58 | .box { 59 | width: 300px; 60 | height: 300px; 61 | background-color: #efcca1; 62 | } 63 | #boxId { 64 | background-color: #1890ff; 65 | } 66 | ``` 67 | 68 | ```html 69 |
70 | ``` 71 | 72 | 显示结果与样式重复写的结果是相同的,`id` 选择器的规则生效。 73 | 74 | ## !important(提升样式优先级) 75 | 76 | `!important` 可以提升样式的优先级,不过 `!important` 尽量还是少使用比较好。 77 | 我们还是拿上面的例子举例,但是在 `class` 选择器中 加入 `!important`。 78 | 79 | ```css 80 | .box { 81 | width: 300px; 82 | height: 300px; 83 | background-color: #efcca1 !important; 84 | } 85 | ``` 86 | 87 | ![priority4](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/priority/priority4.png) 88 | 89 | 只有 `class` 选择器设置时,颜色改变。优先级被提升到了最前面。 90 | 91 | 但是如果两个均设置 `!important` 时,依然是看哪个的权重值大,显示哪个。 92 | 93 | ## 行内、内联和外联样式优先级 94 | 95 | 这时候很多人会奇怪,内联盒外联是什么? 96 | 97 | - 行内当然都知道啦,就是写在标签的 `style` 属性中的 `css` 规则 98 | - 内联其实就是 ` 122 | 123 | 124 | 125 |
126 | 127 | 128 | ``` 129 | 130 | ```css 131 | /* choise.css */ 132 | .box { 133 | background-color: #1890ff; 134 | } 135 | ``` 136 | 137 | 根据权重值来计算,行内样式的权重值最大,所以行内样式生效了。 138 | 139 | ![priority5](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/priority/priority5.png) 140 | 141 | 但是在上图中,我们并不能看出内联和外联样式的优先级。 142 | 143 | ### 内联和外联样式优先级 144 | 145 | 首先我们将上面的例子中将行内样式中的背景颜色除去,就变成了下面的样子。 146 | 147 | ```html 148 |
149 | ``` 150 | 151 | 我们再来看结果。 152 | 153 | ![priority6](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/priority/priority4.png) 154 | 155 | 我们发现结果变成了淡黄色,那么说明内联样式的优先级更高吗? 156 | 157 | 现在,我们将两个顺序调换,将 `link` 标签与 `style` 标签顺序调换。 158 | 159 | ```html 160 | 168 | 169 | 170 | ``` 171 | 172 | 我们再来看看结果。 173 | 174 | ![priority7](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/priority/priority3.png) 175 | 176 | 这时候我们发现,外联样式的优先级更高了。 177 | 178 | 所以总结一下,**外联与内联样式的优先级和加载顺序有关**,相当于就是同选择器下,后出现的会覆盖前面出现的。 179 | 180 | - 外联在前,内联在后,则内联优先级高 181 | - 内联在前,外联在后,则外联优先级高 182 | 183 | ## 样式应用中嵌套 184 | 185 | ### 非应用于目标 186 | 187 | 我们在很多时候,比如在开发中,会定义一个全局的字体颜色。而全局设置的颜色,有时候并不是直接应用于目标的,而是应用于目标父级,甚至父级的父级。 188 | 而这时候,我们 `css` 规则是以怎样的优先级展示呢? 189 | 190 | ```html 191 |
192 |
193 |

content

194 |
195 |
196 | ``` 197 | 198 | ```css 199 | #box { 200 | width: 300px; 201 | height: 300px; 202 | background-color: #efcca1; 203 | color: #1890ff; 204 | } 205 | .child { 206 | color: #fff; 207 | } 208 | ``` 209 | 210 | ![priority8](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/priority/priority8.png) 211 | 212 | 从结果上看,文字显示的是白色,我们就可以知道,它其实就是离目标越近者优先。 213 | 214 | 可能会有疑惑,例如如果权重更大的情况呢? 215 | 216 | - 我们将 `.box` 改成 `#box`,`class="box"` 改成 `id="box"`,我们设置为 `id` 选择器,然而结果相同一样是白色。 217 | 218 | - 当然可能还不相信时,可以为外层的 `color` 语句添加 `!important`,这时候权重值变为无穷大,但是显示的结果还是白色。 219 | 220 | 所以可以明白,在非应用于目标的情况下,会优先选择最近的父级 `css` 规则来显示。 221 | 222 | ### 权重相等的情况下 223 | 224 | 那么接下来,我们来看看在权重相等的情况下是怎么展示的。 225 | 226 | - 显示最近的 `css` 规则 227 | 228 | 我们计算权重值可以知道,是相同的,为了避免有人觉得是下面的覆盖上面的,我们将代码顺序调整 229 | 230 | ```css 231 | .box { 232 | width: 300px; 233 | height: 300px; 234 | background-color: #efcca1; 235 | } 236 | /* 权重值: 100 + 100 + 10 --- 离目标更近 */ 237 | .box .box2 { 238 | color: #fff; 239 | } 240 | /* 权重值: 100 + 100 + 10 */ 241 | .box .child { 242 | color: #1890ff; 243 | } 244 | ``` 245 | 246 | ```html 247 |
248 |
249 |
250 |

content

251 |
252 |
253 |
254 | ``` 255 | 256 | 我们就会看到,显示的颜色是白色。 257 | 258 | ## 总结 259 | 260 | 我们来总结一下 `css` 优先级吧。 261 | 262 | 首先,肯定是我们在介绍权重的时候展示了一张图。 263 | 264 | - !importtant(无穷大) > 行内样式(10000) > id 选择器(1000) > class/伪类/属性(100) > 标签选择器/伪元素(10) > 通配符(1) 265 | 266 | 这里我们在添加一张图,那就是行内样式、内联、外联样式 267 | 268 | ![priority9](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/css/priority/priority9.png) 269 | 270 | - 行内样式 > 内联样式 & 外联样式 271 | 272 | 内联样式与外联样式是根据加载顺序来显示的。 273 | -------------------------------------------------------------------------------- /article/github-pages/1. hexo-githubPages.md: -------------------------------------------------------------------------------- 1 | # hexo + github pages + next 主题,十分钟学会 2 | 3 | ## 介绍一下 hexo 的主要命令 4 | 5 | 首先,我们先介绍一下 `hexo` 的一些主要命令,具体可以查看 [hexo 官网 - 命令](https://hexo.io/zh-cn/docs/commands)。 6 | 7 | | 命令 | 作用 | 简写 | 8 | | --------------------------- | ------------------------------------------------------------ | -------- | 9 | | `hexo init ` | 新建一个网站。如果没有设置 `file` ,Hexo 默认在当前的文件夹建立网站 | | 10 | | `hexo generate` | 生成静态文件(`public`) | `hexo g` | 11 | | `hexo new [layout] ` | 编写文章,默认在`source/_post` 文件夹下,`layout` 就是文章的布局,`post |draft |page ` | | 12 | | `hexo server` | 启动服务器。默认情况下,访问网址为: `http://localhost:4000/` | `hexo s` | 13 | | `hexo deploy` | 部署网站 | `hexo d` | 14 | | `hexo clean` | 清除缓存文件 (`db.json`) 和已生成的静态文件 (`public`)。在某些情况(尤其是更换主题后),如果发现您对站点的更改无论如何也不生效,您可能需要运行该命令 | | 15 | 16 | ## 创建一个仓库 17 | 18 | - 创建仓库页面 19 | 20 | ![image-20220117153956920](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220117153956920.png) 21 | 22 | - 仓库名称固定,必须是 `username.github.io` ,`username` 就是你 `github` 的名称 23 | 24 | ![image-20220117154056202](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220117154056202.png) 25 | 26 | - 进入设置页面 27 | 28 | ![image-20220117154209325](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220117154209325.png) 29 | 30 | - 然后找到下面的 `pages` 31 | 32 | ![image-20220117154336407](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220117154336407.png) 33 | 34 | - 选择主题(`choose a theme`)之后,就会自动跳转到 `readme` 的提交页面 35 | 36 | ![image-20220117154539668](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220117154539668.png) 37 | 38 | - 根据提供给的链接打开网址,我们就可以看到我们选择的主题(这一步其实不重要,因为我们会用别的主题替换) 39 | 40 | ![image-20220117154713730](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220117154713730.png) 41 | 42 | ## 安装并运行 hexo 43 | 44 | ```bash 45 | # 安装 hexo 46 | $ npm install -g hexo-cli 47 | ``` 48 | 49 | ```bash 50 | # 建立文档 51 | # file - 文件路径 52 | $ cd <file> 53 | $ hexo init 54 | 55 | # 或者 56 | # 建立的文件路径/以及名称 57 | # desktop/Blog。desktop为路径 Blog 为文件名称 58 | $ hexo init <file> 59 | ``` 60 | 61 | 来演示一次。 62 | 63 | ![image-20220118144154623](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220118144154623.png) 64 | 65 | - 安装依赖 66 | 67 | ```bash 68 | # file 到文件目录 69 | $ cd <file> 70 | 71 | # 安装依赖 72 | $ npm install 73 | ``` 74 | 75 | ![image-20220118144310872](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220118144310872.png) 76 | 77 | - 可以看到现在的目录结构是这样的 78 | 79 | ![image-20220118151322761](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220118151322761.png) 80 | 81 | - 本地运行 82 | 83 | ```bash 84 | $ hexo server 85 | ``` 86 | 87 | ![image-20220118144332639](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220118144332639.png) 88 | 89 | 我们通过 `http://localhost:4000/` 就可以打开页面了,这就是默认页面了。 90 | 91 | ![image-20220118144408105](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220118144408105.png) 92 | 93 | ## 部署到 github pages 94 | 95 | 部署其实很简单,就是修改 `hexo` 文件的 `_config.yml` 底部的 `deploy` 部署代码。 96 | 97 | ```yml 98 | # gitname: your github name 99 | # branch: 分支 100 | 101 | # 下面注释掉的这种方式在2021年8月起,可能会报错,还是使用 ssh 的方式较好 102 | # github: https://github.com/<gitname>/<gitname>.github.io.git 103 | deploy: 104 | type: git 105 | repo: 106 | github: git@github.com:<gitname>/<gitname>.github.io.git 107 | branch: <branch> 108 | ``` 109 | 110 | - 还需要下载一个自动部署插件 111 | 112 | ```bash 113 | $ npm install hexo-deployer-git 114 | ``` 115 | 116 | 所有上面的东西,部署好之后,就可以进行部署了,我们通过一下 `hexo d` 命令对 `github` 进行部署。 117 | 118 | ```bash 119 | $ hexo generate 120 | $ hexo deploy 121 | ``` 122 | 123 | 这时候我们的代码就部署到我们的 `github` 上了。 124 | 125 | 我们可以直接打开链接看一下 `<gitname>.github.io`,就可以看到我们部署的项目了,与 `hexo s` 运行结果相同。 126 | 127 | ## 下载使用 next 主题 128 | 129 | 我们来下载 `next` 主题 130 | 131 | ```bash 132 | # 方式一 133 | $ npm install hexo-theme-next@latest 134 | 135 | # 方式二 136 | $ git clone https://github.com/next-theme/hexo-theme-next themes/next 137 | $ git pull #更新 138 | ``` 139 | 140 | 使用方法一更好一些,但是如果就更改内容来说,可能方法二比较方便。 141 | 142 | 我们使用方法一来实现一次。 143 | 144 | ![image-20220118151413475](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220118151413475.png) 145 | 146 | 我们在修改 `_config.yml` 中的 `theme` 配置 147 | 148 | ```yml 149 | theme: next 150 | ``` 151 | 152 | 然后我们执行命令,并对 github 进行部署。 153 | 154 | ```bash 155 | $ hexo g -d 156 | ``` 157 | 158 | 我们来看看,我们的成果吧,打开你自己的网页,`username.github.io`。 159 | 160 | 当然,部署命令执行之后,需要等待一会儿,不是马上就有的,如果你需要马上就有,可以执行 `hexo s`,先在本地看看是不是成功了。 161 | 162 | ![image-20220118151655445](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220118151655445.png) 163 | 164 | 这时候,我们就已经成功了。 165 | 166 | 但是有许多配置项可能都还不理解,我们进行分篇幅介绍。 167 | 168 | 我们再来介绍一个命令,如果你的主题是第一种下载方式(`npm install hexo-theme-next@latest`)。 169 | 170 | ```bash 171 | $ cp node_modules/hexo-theme-next/_config.yml _config.next.yml 172 | ``` 173 | 174 | 使用上面的命令,将主题配置文件,移到根目录下。 175 | 176 | 我们再来看看现在的文件结构。 177 | 178 | ![image-20220123115412196](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220123115412196.png) 179 | 180 | 可以发现,多出来一个 `_config.next.yml` 配置文件。 181 | 182 | 我们在里面找到 `menu `,然后打开这四个路由 183 | 184 | ![image-20220123115524563](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220123115524563.png) 185 | 186 | 在运行,看一下我们首页,就会多出一些标签路由。 187 | 188 | ![image-20220123115647543](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220123115647543.png) 189 | 190 | 当然,除了归档,其他点击都为空路由,因为,我们还没设置这两个文件夹。 191 | 192 | ```bash 193 | $ hexo new page tag 194 | $ hexo new page categories 195 | ``` 196 | 197 | 这是我们 `source` 文件夹下,多了两个文件夹。 198 | 199 | ![image-20220123135642800](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220123135642800.png) 200 | 201 | 这时候,在打开网站时,就可以打开相关页面了,其他路由同理。 202 | 203 | ## 相关文章 204 | 205 | [hexo 配置项]() 206 | 207 | [next 配置项]() 208 | -------------------------------------------------------------------------------- /article/github-pages/2. hexo配置项.md: -------------------------------------------------------------------------------- 1 | # hexo 配置 - 常用 2 | 3 | `hexo` 的配置是在哪里设置的呢?其实就是根目录下的 `_config.yml` 文件中进行配置。 4 | 5 | ![image-20220121110419337](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220121110419337.png) 6 | 7 | ## 网站配置 8 | 9 | ```yml 10 | # Site 11 | title: MyBlog # 设置网站的标题 12 | subtitle: 'Welcome to my blog' # 设置网站的子标题 13 | description: 'I am a description' # 设置网站描述 14 | keywords: # 网站的关键词,支持多个,多用于网站搜索 15 | author: hzzzzzzzq # 作者 16 | language: zh-CN # 设置网站使用的语言。我们常用的当然就是 `zh-CN`。默认为 `en`。 17 | timezone: '' # 设置网站的时区。`hexo` 默认使用电脑的时区。 18 | ``` 19 | 20 | ![image-20220121111002144](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220121111002144.png) 21 | 22 | ## 网址 23 | 24 | 提醒一点,`url` 直接使用你配置的 `url` 即可,不要随意去增加 `path`,而 `root` 虽然时网站的根目录,但是我研究了一周了,如果添加了根目录,可能就会导致 `css` 加载的问题。 25 | 26 | 所以上面的 `url` 和 `root` 尽量不要进行添加 `path`,除非你愿意手动去更改文件目录信息,较为繁琐,容易导致全站出问题。 27 | 28 | 来看看,我的配置吧。首先 `url` 使用的是 `github` 创建的。 29 | 30 | ```yml 31 | # URL 32 | ## Set your site url here. For example, if you use GitHub Page, set url as 'https://username.github.io/project' 33 | url: https://hzzzzzzzq.github.io # 网址 34 | # 必须以 `http://` 或 `https://` 开头,与以往 `//` 开头的方式不同 35 | 36 | root: / # 网站根目录 37 | # 在这里,我并没有修改,你也可以将 root 删除,或者默认就是无 root 的情况。 38 | 39 | permalink: /Blog/:abbrlink.html # 文章的永久链接格式 默认 - :year/:month/:day/:title/ 40 | # abbrlink config 41 | abbrlink: 42 | alg: crc32 # 算法: crc16(default) and crc32 43 | rep: hex # 进制: dec(default) and hex 44 | permalink_defaults: # 永久链接中各部分的默认值 45 | # 保持默认就可以了,除非你要加一个 link path 的默认值 46 | 47 | pretty_urls: # 改写 permalink 的值来美化 URL 48 | # 下面两个也保持默认就好 49 | trailing_index: true # Set to false to remove trailing 'index.html' from permalinks 50 | # 是否在永久链接中保留尾部的 index.html,设置为 false 时去除 51 | 52 | trailing_html: true # Set to false to remove trailing '.html' from permalinks 53 | # 是否在永久链接中保留尾部的 .html,设置为 false 时去除 54 | ``` 55 | 56 | 上面保持默认的代码,我已经进行注释,那么接下来,就要聊一下重点了,那就是永久链接。 57 | 58 | ```yml 59 | permalink: /Blog/:abbrlink.html 60 | # abbrlink config 61 | abbrlink: 62 | alg: crc32 # 算法: crc16(default) and crc32 63 | rep: hex # 进制: dec(default) and hex 64 | ``` 65 | 66 | 从表格来看,`permalink` 的默认值是 `:year/:month/:day/:title/`。 67 | 68 | 为了演示,这个,我们来新建一篇文章名称为 `myBlog`。 69 | 70 | ```bash 71 | $ hexo new "myBlog" 72 | ``` 73 | 74 | 然后我们点进这篇文章,来看看地址 `http://localhost:4000/2022/01/21/myBlog/`,所以上面都是对呀代码的时间值和文章名称。而如果你的博客文章是中文时,就会出现乱码,导致链接很长,这不是我们希望看到的,所以就要用到下面的宝贝了。 75 | 76 | 我使用的是 `abbrlink`,是一个 `hexo-abbrlink` 插件,用来修改我们的文章地址。 77 | 78 | ```bash 79 | $ npm install hexo-abbrlink --save 80 | ``` 81 | 82 | 当然我这里配置的 `/Blog/`,其实就是定死在前面,证明这些都是博客文章,你也可以进行自定义,例如`posts/:abbrlink` 等。 83 | 84 | 这里就要毫不吝啬的放上博主的链接了[https://hzzzzzzzq.github.io/Blog/599a1ad9.html](https://hzzzzzzzq.github.io/Blog/599a1ad9.html),看起来是不是简介多了?该插件就是用来生成唯一的标识所用。 85 | 86 | ## 文章 87 | 88 | ```yml 89 | # Writing 90 | new_post_name: :title.md # 博客文件名格式 91 | default_layout: post # 默认布局 可选值 post(文章) | draft(草稿) | page(页面) 92 | titlecase: false # 标题是否小写 93 | external_link: 94 | enable: true # 是否在新的标签页打开链接 - 默认 true 95 | field: site # Apply to the whole site 默认 - tite 96 | exclude: '' # 排除,默认 - '' 97 | filename_case: 0 # 把文件名转换成大写(-2)或小写(-1),默认 - 0 98 | render_drafts: false # 显示草稿,默认 - false 99 | post_asset_folder: false # 启动 Asset 文件夹,默认 - false 100 | relative_link: false # 把链接改为与根目录的相对地址,默认 - false 101 | future: true # 显示未来的文章,默认 - false 102 | highlight: # 代码高亮设置 103 | enable: true # 是否启用,默认 - true 104 | line_number: true # 显示行号,默认 - true 105 | auto_detect: false # 自动侦测,默认 - false 106 | tab_replace: '' # 替换 tab,默认 - '' 107 | wrap: true # 换行,默认 - true 108 | hljs: false # 使用 hljs 渲染,默认 - false 109 | prismjs: # 代码块高亮工具 110 | enable: false # 是否启用,默认 - false 111 | preprocess: true # 预处理,默认 - true 112 | line_number: true # 显示行号,默认 - true 113 | tab_replace: '' # 替换 tab,默认 - '' 114 | ``` 115 | 116 | [highlight 代码高亮 参考](https://hexo.io/docs/syntax-highlight#PrismJS) 117 | 118 | [Prisms 代码高亮 参考](<[prismjs](https://hexo.io/docs/syntax-highlight#PrismJS)>) 119 | 120 | ## 分类 & 标签 121 | 122 | ```yml 123 | # Category & Tag 124 | default_category: uncategorized # 默认标签 125 | category_map: # 分类别名,用来将分类标签转化成英文分类,修改分类路由, 配置文件中获取使用 `:category` 126 | 博客: blog # 将分类 博客 转为 blog 127 | 其他: other # 将分类 other 转为 other 128 | tag_map: # 标签别名,用来将中文标签转化成英文标签,修改标签路由 129 | 中文标签: tag # 将标签 中文标签 转为 tag 130 | ``` 131 | 132 | ## 首页分页 133 | 134 | ```yml 135 | # Home page setting 首页设置 136 | # path: Root path for your blogs index page. (default = '') 137 | # per_page: Posts displayed per page. (0 = disable pagination) 138 | # order_by: Posts order. (Order by date descending by default) 139 | index_generator: 140 | path: /default-index/ # 博客根目录 141 | per_page: 10 # 每页多少条 142 | order_by: -date # 按照什么顺序排序,-date 表示时间倒序 143 | ``` 144 | 145 | ## 分页 146 | 147 | | 参数 | 描述 | 默认值 | 148 | | ---------------- | ---- | ------ | 149 | | `per_page` | | 10 | 150 | | `pagination_dir` | | `page` | 151 | 152 | ![image-20220123111354713](https://raw.githubusercontent.com/hzzzzzzzq/Blog/main/asseats/images/hexo/image-20220123111354713.png) 153 | 154 | 来看看文件中的默认配置吧。 155 | 156 | ```yml 157 | # 分页 158 | ## per_page 为零表示不分页 159 | per_page: 10 # 每一页文章显示的文章 默认 - 10 160 | pagination_dir: page # 分页目录 161 | ``` 162 | 163 | ## 其他配置 164 | 165 | | 参数 | 描述 | 166 | | -------- | ---------------------------------------------------------------------- | 167 | | `theme` | 主题名称,如果值为 `false`,就是禁用主题 | 168 | | `deploy` | 部署部分的配置 | 169 | | `search` | 这是配置中没有的,但是我们在网站中,也常需要搜索操作,所以增加一个配置 | 170 | 171 | - `theme` 172 | 173 | `theme` 主题的设置就不说了,只是提供主题的名称即可,前提是你下载了该主题。 174 | 175 | - `deploy` 176 | 177 | `deploy` 也在上一篇文章 - 《hexo+githubpages+next》中提到过。 178 | 179 | 简单的配置说一下 180 | 181 | ```yml 182 | # Deployment 183 | ## Docs: https://hexo.io/docs/one-command-deployment 184 | deploy: 185 | type: git # 类型 186 | repo: # 仓库 187 | github: # git@github.com:yourname/yourname.github.io.git 188 | branch: master # 分支 189 | ``` 190 | 191 | - `search` 192 | 193 | 这功能,估计也是很常用的吧,方便找寻具体的文章。 194 | 195 | 我们使用 本地搜索(`LocalSearch`),话不多上,首先我们需要下载插件。 196 | 197 | ```bash 198 | $ npm install hexo-generator-searchdb --save 199 | ``` 200 | 201 | 有兴趣可以具体看一看每一个参数的具体作用,[hexo-generator-search](https://github.com/theme-next/hexo-generator-search) 202 | 203 | ```yml 204 | search: 205 | path: search.xml # 会在 public 中生存 search.xml 文件,保存全站所有 post 类型的页面生成结构化的数据 206 | field: post # 设置搜索的范围,默认 post,可选: post | page | all 207 | format: html # 页面内容的形式,默认 html, 可选: html | raw | excerpt | more 208 | limit: 1000 # 设置搜索的最大数量 209 | ``` 210 | 211 | 其实这样并不够,我们使用的是 `NexT` 主题,还需要修改主题配置文件的 `local_search` 212 | 213 | ```yml 214 | local_search: 215 | enable: true 216 | ``` 217 | 218 | ## 参考链接 219 | 220 | [hexo - 配置](https://hexo.io/zh-cn/docs/configuration.html) 221 | -------------------------------------------------------------------------------- /article/ES6/8. Set 和 Map.md: -------------------------------------------------------------------------------- 1 | # Set 和 Map 2 | 3 | ## Set 4 | 5 | ### 介绍 6 | 7 | `Set` 是 `ES 6` 提供的新的数据结构。类似于数组,但是都是唯一值,没有重复值。 8 | `Set` 就是一个构造函数,用来生成 `Set` 数据结构。 9 | `add()` 就是为 `Set` 添加成员,我们来试试。 10 | 11 | ```javascript 12 | const set = new Set(); 13 | set.add(1); 14 | set.add(2); 15 | set.add(3); 16 | set.add(2); 17 | set.add(1); 18 | for (let s of set) { 19 | console.log(s); 20 | } 21 | // 1 2 3 22 | ``` 23 | 24 | 代码中可以看出 `Set` 的数据结构,是不会添加重复的值。 25 | 26 | `Set` 构造函数可以接受一个数组或者具有 iterable 接口的其他数据结构作为参数,用来初始化 `Set`。 27 | 28 | ```javascript 29 | const arr = [1, 2, 2, 2, 3]; 30 | const set = new Set(arr); 31 | 32 | console.log(set); 33 | // [1, 2, 3] 34 | ``` 35 | 36 | 从这里,我们也可以看出,用于数组去重是一个很好的选择 37 | 38 | ```javascript 39 | const arr = [1, 2, 2, 2, 3, 4]; 40 | const arr1 = [...new Set(arr)]; 41 | console.log(arr1); 42 | // [1, 2, 3, 4] 43 | ``` 44 | 45 | ### Set 实例属性和方法 46 | 47 | **实例属性** 48 | 49 | - `Set.prototype.constructor`: 构造函数,默认就是 `Set()`。 50 | - `Set.prototype.size`: 返回 `Set` 成员总数。 51 | 52 | **实例方法** 53 | 54 | - `Set.prototype.add(value)`: 添加元素到 `Set`,返回 `Set` 本身。 55 | - `Set.prototype.delete(value)`: 删除某个值,返回一个布尔值。 56 | - `Set.prototype.has(value)`: 返回一个布尔值,表示该值是否为 `Set` 的值。 57 | - `Set.prototype.clear()`: 清除所有值。 58 | 59 | ```javascript 60 | const set = new Set([1, 2, 3, 4]); 61 | 62 | set.add(1); 63 | set.add(5); 64 | set.add(3); 65 | 66 | console.log(set.size); // 5 67 | console.log(set.has(5)); // true 68 | console.log(set.has(2)); // true 69 | 70 | set.delete(5); 71 | set.delete(4); 72 | 73 | console.log(set.has(5)); // false 74 | console.log(set.has(4)); // false 75 | ``` 76 | 77 | ### 遍历操作 78 | 79 | 四个遍历方法。 80 | 81 | - `Set.prototype.keys()`: 返回 `key` 的遍历器 82 | - `Set.prototype.values()`: 返回 `value` 的遍历器 83 | - `Set.prototype.entries()`: 返回 `key: values` 的遍历器 84 | - `Set.prototype.forEach()`: 回调函数遍历,类似数组的 `forEach` 85 | 86 | ```javascript 87 | const set = new Set(['key1', 'key2', 'key3']); 88 | for (let key of set.keys()) { 89 | console.log(key); 90 | } 91 | // key1 92 | // key2 93 | // key3 94 | for (let val of set.values()) { 95 | console.log(val); 96 | } 97 | // key1 98 | // key2 99 | // key3 100 | for (let [k, v] of set.entries()) { 101 | console.log(k, v); 102 | } 103 | // key1 key1 104 | // key2 key2 105 | // key3 key3 106 | 107 | set.forEach((val, key) => console.log(key, val)); 108 | // key1 key1 109 | // key2 key2 110 | // key3 key3 111 | ``` 112 | 113 | 由遍历,我们可以看出,`key` 与 `value` 的值是相同的。 114 | 115 | ## Map 116 | 117 | ### 介绍 118 | 119 | `ES 6` 提供了 `Map` 数据结构。类似于对象,也是键值对的集合,但是 `key` 不限制于字符串,其他类型的值均可以作为 `key`。 简单来说 `Map` 结构提供了 `val - val`,而对象必须是 **字符串 - val**。 120 | 121 | `map` 的简单用法。也看看将对象作为 `key` 的时候。 122 | 123 | ```javascript 124 | const map = new Map(); 125 | const obj = {}; 126 | map.set(obj, 'object'); 127 | console.log(map.get(obj)); // 'object' 128 | map.set('string', 'hello hzzzzzzzq'); 129 | console.log(map.get('string')); // 'hello hzzzzzzzq' 130 | 131 | console.log(map.has(obj)); // true 132 | console.log(map.has('string')); // true 133 | console.log(map.delete('string')); // true 134 | console.log(map.has('string')); // false 135 | ``` 136 | 137 | 上面我们就可以看出,我们将对象 `obj` 作为一个`Map` 的键传入,使用 `get` 获取值,`delete` 删除,`has` 作为判断是否有这个值。 138 | 139 | 我们在来看看,`Map` 作为构造函数,怎么添加成员。 140 | 其实在[对象的扩展]()中,我们已经提到过了。 141 | 142 | - 接受数组作为参数,而数组的成员是一个个表示键值对的数组。 143 | 144 | ```javascript 145 | const map = new Map([ 146 | ['x', 1], 147 | ['y', 2], 148 | ]); 149 | console.log(map.size); // 2 150 | console.log(map.has('x')); // true 151 | console.log(map.get('x')); // 1 152 | 153 | console.log(map.has('y')); // true 154 | console.log(map.get('y')); // 2 155 | ``` 156 | 157 | - 任何具有 `Iterator` 接口,且每个成员都是一个双元素的数组的结构都可以当作 `Map` 的参数。`Set` 和 `Map` 自身也可以作为参数。 158 | 159 | ```javascript 160 | const set = new Set([['x', 1]]); 161 | 162 | const map1 = new Map(set); 163 | console.log(map1.get('x')); // 1 164 | 165 | const map2 = new Map(); 166 | map2.set('y', 2); 167 | 168 | const map3 = new Map(map2); 169 | console.log(map3.get('y')); // 2 170 | ``` 171 | 172 | - Map 与 Set 类似,如果有重复 `key` 时,后面的 `val` 会覆盖前面的 `val`,也就是说,`map` 也是唯一的。 173 | - Map 中若是没有找到这个 `key`,则返回 `undefined`。 174 | 175 | ```javascript 176 | const map = new Map(); 177 | map.set('x', 1); 178 | map.set('x', 2); 179 | console.log(map.get('x')); // 2 180 | console.log(map.get('y')); // undefined 181 | ``` 182 | 183 | ### Map 属性和操作 184 | 185 | - size 186 | `size` 返回 `Map` 的成员数量。 187 | 188 | ```javascript 189 | const map = new Map(); 190 | map.set('x', 1); 191 | console.log(map.size); // 1 192 | map.set('y', 2); 193 | console.log(map.size); // 2 194 | ``` 195 | 196 | - Map.prototype.set(key, val) 197 | `set(key, val)` 方法就是为 Map 添加新的值了。 198 | 199 | ```javascript 200 | const map = new Map(); 201 | 202 | map.set('x', 1); // 键是字符串 203 | map.set(1, 2); // 键是数值 204 | map.set(undefined, 3); // 键是 undefined 205 | map.set(null, 4); // 键时 null 206 | 207 | console.log(map.get('x')); // 1 208 | console.log(map.get(1)); // 2 209 | console.log(map.get(undefined)); // 3 210 | console.log(map.get(null)); // 4 211 | ``` 212 | 213 | - Map.prototype.get(key) 214 | `get(key)` 方法获取 `key` 对应的 `val`,找不到则返回 undefined。 215 | 216 | ```javascript 217 | const map = new Map(); 218 | 219 | map.set('x', 1); 220 | console.log(map.get('x')); // 1 221 | console.log(map.get('y')); // undefined 222 | ``` 223 | 224 | - Map.prototype.has(key); 225 | `has(key)` 方法判断键名 `key` 是否在 `Map` 对象中。 226 | 227 | ```javascript 228 | const map = new Map(); 229 | map.set('x', 1); 230 | console.log(map.has('x')); // true 231 | console.log(map.has('y')); // false 232 | ``` 233 | 234 | - Map.prototype.delete(key) 235 | `delete(key)` 方法删除某个键,返回一个布尔值,成功为 `true`。 236 | 237 | ```javascript 238 | const map = new Map(); 239 | map.set('x', 1); 240 | 241 | console.log(map.delete('x')); // true 242 | console.log(map.delete('y')); // false 243 | ``` 244 | 245 | - Map.prototype.clear(); 246 | `clear()` 就是清除 Map 对象的所有成员。 247 | 248 | ```javascript 249 | const map = new Map(); 250 | map.set('x', 1); 251 | map.set('y', 2); 252 | map.clear(); 253 | 254 | console.log(map.get('x')); // undefined 255 | console.log(map.get('y')); // undefined 256 | ``` 257 | 258 | ### 遍历 259 | 260 | 与 `Set` 类似。 261 | 262 | - Map.prototype.keys(): 返回 `Map` 对象的所有 `key`。 263 | - Map.prototype.values():返回 `Map` 对象的所有 `val`。 264 | - Map.prototype.entries():返回 `Map` 对象的所有成员的遍历器。 265 | - Map.prototype.forEach():遍历 `Map` 的所有成员。 266 | 267 | ```javascript 268 | const map = new Map(); 269 | map.set('x', 1); 270 | map.set('y', 2); 271 | map.set('z', 3); 272 | 273 | for (let key of map.keys()) { 274 | console.log(key); 275 | } 276 | // 'x' 277 | // 'y' 278 | // 'z' 279 | 280 | for (let val of map.values()) { 281 | console.log(val); 282 | } 283 | // 1 284 | // 2 285 | // 3 286 | 287 | for (let [k, v] of map.entries()) { 288 | console.log(k, v); 289 | } 290 | // 'x' 1 291 | // 'y' 2 292 | // 'z' 3 293 | 294 | map.forEach((val, key) => { 295 | console.log(key, val); 296 | }); 297 | // 'x' 1 298 | // 'y' 2 299 | // 'z' 3 300 | ``` 301 | --------------------------------------------------------------------------------