├── docs
├── .keep
└── design-mode
│ ├── strategy-mode.md
│ └── singleton-mode.md
├── .gitignore
├── .vuepress
├── public
│ └── assets
│ │ └── img
│ │ ├── bg.jpeg
│ │ ├── avatar.png
│ │ ├── md
│ │ ├── baidu_PV.png
│ │ └── leancloud.png
│ │ └── javascript
│ │ ├── scope_chain.jpg
│ │ └── JavaScript_Process.png
├── enhanceApp.js
└── config.js
├── blogs
├── webpack
│ └── todo.md.del
└── JavaScript
│ └── Closure.md
├── package.json
├── index.md
├── README.md
└── LICENSE
/docs/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | yarn.lock
4 | yarn.error
5 | dist/
--------------------------------------------------------------------------------
/.vuepress/public/assets/img/bg.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liutaohz/record-blog/HEAD/.vuepress/public/assets/img/bg.jpeg
--------------------------------------------------------------------------------
/.vuepress/public/assets/img/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liutaohz/record-blog/HEAD/.vuepress/public/assets/img/avatar.png
--------------------------------------------------------------------------------
/.vuepress/public/assets/img/md/baidu_PV.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liutaohz/record-blog/HEAD/.vuepress/public/assets/img/md/baidu_PV.png
--------------------------------------------------------------------------------
/.vuepress/public/assets/img/md/leancloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liutaohz/record-blog/HEAD/.vuepress/public/assets/img/md/leancloud.png
--------------------------------------------------------------------------------
/.vuepress/public/assets/img/javascript/scope_chain.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liutaohz/record-blog/HEAD/.vuepress/public/assets/img/javascript/scope_chain.jpg
--------------------------------------------------------------------------------
/blogs/webpack/todo.md.del:
--------------------------------------------------------------------------------
1 | ---
2 | title: webpack工作原理
3 | date: 2021-11-25
4 | tags:
5 | - webpack
6 | categories:
7 | - webpack
8 | ---
9 |
10 | webpack-todo
--------------------------------------------------------------------------------
/.vuepress/public/assets/img/javascript/JavaScript_Process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liutaohz/record-blog/HEAD/.vuepress/public/assets/img/javascript/JavaScript_Process.png
--------------------------------------------------------------------------------
/docs/design-mode/strategy-mode.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 策略模式
3 | sidebar: auto
4 | date: 2021-12-02
5 | tags:
6 | - 设计模式
7 | categories:
8 | - 设计模式
9 |
10 | ---
11 |
12 | ## 策略模式
13 |
14 |
15 | ## TODO
--------------------------------------------------------------------------------
/docs/design-mode/singleton-mode.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 单例模式
3 | sidebar: auto
4 | date: 2021-12-02
5 | tags:
6 | - 设计模式
7 | categories:
8 | - 设计模式
9 | ---
10 |
11 | ## 什么是单例模式?
12 | 单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
13 |
14 | ## TODO
--------------------------------------------------------------------------------
/.vuepress/enhanceApp.js:
--------------------------------------------------------------------------------
1 | export default ({ router }) => {
2 | /**
3 | * 路由切换事件处理
4 | */
5 | router.beforeEach((to, from, next) => {
6 | // console.log("切换路由", to.fullPath, from.fullPath);
7 | //触发百度的pv统计
8 | if (typeof _hmt != "undefined") {
9 | if (to.path) {
10 | _hmt.push(["_trackPageview", to.fullPath]);
11 | console.log("上报百度统计", to.fullPath);
12 | }
13 | }
14 |
15 | // continue
16 | next();
17 | });
18 | };
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "record-blog",
3 | "version": "1.0.0",
4 | "author": "刘涛",
5 | "scripts": {
6 | "dev": "vuepress dev . --open --host \"localhost\"",
7 | "build": "vuepress build .",
8 | "deploy": "gh-pages -d dist"
9 | },
10 | "devDependencies": {
11 | "gh-pages": "^3.2.3",
12 | "vuepress": "1.8.2",
13 | "vuepress-theme-reco": "1.6.6"
14 | },
15 | "homepage": "https://easysimple.github.io/record-blog/",
16 | "bugs": "https://github.com/EasySimple/record-blog/issues",
17 | "description": "个人博客"
18 | }
19 |
--------------------------------------------------------------------------------
/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | home: true
3 | heroText: null
4 | tagline: null
5 | # heroImage: /avatar.png
6 | # heroImageStyle: {
7 | # maxWidth: '600px',
8 | # width: '100%',
9 | # display: block,
10 | # margin: '9rem auto 2rem',
11 | # background: '#fff',
12 | # borderRadius: '1rem',
13 | # }
14 | bgImage: '/assets/img/bg.jpeg'
15 | bgImageStyle: {
16 | height: '450px'
17 | }
18 | isShowTitleInHome: false
19 | actionText: Guide
20 | actionLink: /views/other/guide
21 | features:
22 | - title: Yesterday
23 | details: 开发一款看着开心、写着顺手的 vuepress 博客主题
24 | - title: Today
25 | details: 希望帮助更多的人花更多的时间在内容创作上,而不是博客搭建上
26 | - title: Tomorrow
27 | details: 希望更多的爱好者能够参与进来,帮助这个主题更好的成长
28 | ---
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
9 | # record-blog简介
10 | 个人博客:记录 经验总结、学习笔记、日常生活...
11 |
12 | [博客地址](https://easysimple.github.io/record-blog/)
13 |
14 | **让搭建博客部署博客更加简单,你可以更专注于写博客内容。**
15 |
16 | ## 命令
17 | - npm i (加载依赖)
18 | - npm run dev (本地运行,启动博客)
19 | - npm run build (打包)
20 | - npm run deploy (部署到github page上)
21 |
22 | ## 博客搭建使用技术
23 | - vuepress
24 | - vuepress-theme-reco@1.6.6
25 | - gh-page
26 |
27 | ## 自定义修改添加功能点
28 |
29 | - 添加页面访问量显示,使用Valine、leancloud。在网站平台查看后台数据效果如下
30 | 
31 | - 添加页面PV埋点统计,使用百度埋点。在网站平台查看埋点数据效果如下
32 | 
33 |
34 | ## 注意
35 | 如果想直接使用这个项目模板,你需要把“/record-blog/.vuepress/config.js”中valineConfig换成自己的信息。
36 | 同样的百度埋点信息在“/record-blog/.vuepress/enhanceApp.js”中,也需要替换本人的百度统计代码
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 EasySimple
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.vuepress/config.js:
--------------------------------------------------------------------------------
1 | const githubUrl = 'https://github.com/EasySimple';
2 | module.exports = {
3 | "base": '/record-blog/',
4 | "title": "刘涛",
5 | "description": "个人博客",
6 | "dest": "dist",
7 | "head": [
8 | ['link', { rel: 'icon', href: "/assets/img/avatar.png" }],
9 | [
10 | "meta",
11 | {
12 | "name": "viewport",
13 | "content": "width=device-width,initial-scale=1,user-scalable=no"
14 | }
15 | ],
16 | // 添加百度统计
17 | [
18 | "script",
19 | {},
20 | `
21 | var _hmt = _hmt || [];
22 | (function() {
23 | var hm = document.createElement("script");
24 | hm.src = "https://hm.baidu.com/hm.js?324e3291a527715a870c6e1d7da28fb1";
25 | var s = document.getElementsByTagName("script")[0];
26 | s.parentNode.insertBefore(hm, s);
27 | })();
28 | `
29 | ]
30 | ],
31 | "theme": "reco",
32 | "themeConfig": {
33 | "footer": {
34 | "display":true,
35 | },
36 | "copyrightText":'转载请注明出处',
37 | "nav": [
38 | {
39 | "text": "Home",
40 | "link": "/",
41 | "icon": "reco-home"
42 | },
43 | {
44 | "text": "TimeLine",
45 | "link": "/timeline/",
46 | "icon": "reco-date"
47 | },
48 | {
49 | "text": "设计模式",
50 | "icon": "reco-message",
51 | "items": [
52 | {
53 | "text": "单例模式",
54 | "link": "/docs/design-mode/singleton-mode"
55 | },
56 | {
57 | "text": "策略模式",
58 | "link": "/docs/design-mode/strategy-mode"
59 | }
60 | ]
61 | },
62 | {
63 | "text": "GitHub",
64 | "link": githubUrl,
65 | "icon": "reco-github",
66 | }
67 | ],
68 | "sidebar": {
69 | "/docs/design-mode/": [
70 | // "",
71 | "singleton-mode",
72 | "strategy-mode",
73 | ]
74 | },
75 | "type": "blog",
76 | "blogConfig": {
77 | "category": {
78 | "location": 2,
79 | "text": "Category"
80 | },
81 | "tag": {
82 | "location": 3,
83 | "text": "Tag"
84 | },
85 | "socialLinks": [ // 信息栏展示社交信息
86 | { icon: 'reco-github', link: githubUrl },
87 | ],
88 | },
89 | // "friendLink": [
90 | // {
91 | // "title": "vuepress-theme-reco",
92 | // "desc": "A simple and beautiful vuepress Blog & Doc theme.",
93 | // "avatar": "https://vuepress-theme-reco.recoluan.com/icon_vuepress_reco.png",
94 | // "link": "https://vuepress-theme-reco.recoluan.com"
95 | // }
96 | // ],
97 | "logo": "/assets/img/avatar.png",
98 | "search": true,
99 | "searchMaxSuggestions": 10,
100 | "lastUpdated": "Last Updated",
101 | "author": "刘涛",
102 | "authorAvatar": "/assets/img/avatar.png",
103 | "record": "转载请注明出处",
104 | "startYear": "2021",
105 | "valineConfig": {
106 | appId: 'kPzUder8a8LVas2B3Cf4iXEE-gzGzoHsz',// your appId
107 | appKey: 'CRMrTeNnzfaOlkYcjNQzeIEf', // your appKey
108 | showComment: false, // 关闭评论
109 | placeholder: 'test placeholder',
110 | avatar: 'wavatar',
111 | requiredFields: ['nick','mail'],
112 | // serverUrl: ''
113 | }
114 | },
115 | "markdown": {
116 | "lineNumbers": true
117 | }
118 | }
--------------------------------------------------------------------------------
/blogs/JavaScript/Closure.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 闭包
3 | sidebar: auto
4 | date: 2021-11-25
5 | sticky: true
6 | tags:
7 | - 闭包
8 | - JavaScript
9 | categories:
10 | - JavaScript
11 | ---
12 |
13 | 闭包---我们经常听到这个词,那么究竟什么是闭包呢,我们来打破砂锅问到底的方式探索一下。
14 | # 定义
15 | 在不同的地方对它的定义相似但是略有差异
16 | > 在计算机科学中,闭包(Closure),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。 ---**维基百科**
17 |
18 | > 函数与对其状态即词法环境(lexical environment)的引用共同构成闭包(closure)。也就是说,闭包可以让你从内部函数访问外部函数作用域。在JavaScript,函数在每次创建时生成闭包。
19 | 简言之,闭包是由函数引用其周边状态(词法环境)绑在一起形成的(封装)组合结构。在 JavaScript 中,闭包在每个函数被创建时形成。 ---**MDN**
20 |
21 | > 函数对象可以通过作用域链相互关联起来,函数体内部的变量都可以保存在函数作用域内,这种特性在计算机科学文献中称为闭包。---**JavaScript权威指南**
22 |
23 | > 闭包是指有权访问另一个函数作用域中的变量的函数。 ---**JavaScript高级程序设计**
24 |
25 | # 前置知识
26 | 在上述概念中,有多个词高频出现,比如:词法环境、作用域链 等。看来我们想要弄懂闭包先要把这些概念弄明白。
27 | ## 作用域
28 | 作用域就是一套规则,用于确定在何处以及如何查找变量(标识符)的规则
29 |
30 | ``` js
31 | // eg1:
32 | function foo() {
33 | var a = 'test';
34 | console.log(a); // 输出"test"
35 | }
36 | foo();
37 |
38 | // eg2:
39 | var b = 'hello';
40 | function bar() {
41 | console.log(b); // 输出"hello"
42 | }
43 | bar();
44 | // 函数作用域、全局作用域
45 | ```
46 |
47 | ### 作用域链
48 | 我们在查找d变量的时候,先在函数作用域1中查找,没有找到,逐层向外层作用域查找,有一个往外层查找的过程。如下图红色箭头:我们好像是顺着一条链条从下往上查找变量,这条链条,我们就称之为作用域链。
49 |
50 |
51 |
52 | ### 作用域嵌套
53 | 在还没有接触到ES6的let、const之前,只有函数作用域和全局作用域,函数作用域肯定是在全局作用域里面的,而函数作用域中又可以继续嵌套函数作用域,如上图,矩形框框作用域层层嵌套。
54 |
55 | ## 词法环境
56 | 在上面的作用域介绍中,我们将作用域定义为一套规则,这套规则来管理浏览器引擎如何在当前作用域以及嵌套的作用域中根据变量(标识符)进行变量查找。
57 |
58 | “词法作用域是作用域的一种工作模型”,作用域有两种工作模型,在JavaScript中的词法作用域是比较主流的一种,另一种动态作用域
59 | (比较少的语言在用)。
60 |
61 | 所谓的词法作用域就是在你写代码时将变量和块作用域写在哪里来决定,也就是
62 | 词法作用域是静态的作用域,在你书写代码时就确定了
63 |
64 | ### 变量(标识符)的查找规则
65 | 首先声明一点,JavaScript是有编译过程的。
66 |
67 | eg:
68 | var name = 'test'
69 | 编译器在当前作用域中声明一个变量name
70 | 运行时引擎在作用域中查找该变量,找到了name变量并为其赋值
71 | ``` javascript
72 | console.log(name); // 输出undefined
73 | var name = 'test';
74 | ```
75 | 在var name = 'test'的上一行输出name变量,并没有报错,输出undefined,说明输出的时候该变量已经存在了,只是没有赋值而已。
76 | 其实编译器是这样工作的,在代码执行之前从上到下的进行编译,当遇到某个用var声明的变量的时候,先检查在当前作用域下是否存在了该变量。如果存在,则忽略这个声明;如果不存在,则在当前作用域中声明该变量。
77 | 上面的这段简单的代码包含两种查找类型:
78 | 输出变量的值的时候的查找类型是RHS,找到变量为其赋值的查找类型是LHS。
79 |
80 | 这里的左侧和右侧指的是在赋值操作的左侧和右侧。也就是说,变量出现在赋值操作的左侧时进行LHS查询,出现在右侧时进行RHS查询。用一句通俗的话来讲,RHS就是取到它的源值。
81 |
82 | 注意:“赋值操作的左侧和右侧”,并不意味着只是“=”,实际上赋值操作还有好几种形式。
83 |
84 | 在作用域中查找变量都是RHS,并且查找的规则是从当前作用域开始找,如果没找到再到父级作用域中找,一层层往外找,如果在全局作用域如果还没找到的话,就会报错了:ReferenceError: 某变量 is not defined
85 |
86 | 所有的赋值操作中查找变量都是LHS。其中a=4这类赋值操作,也是会从当前作用域中查找,如果没有找到再到外层作用域中找,如果到全局变量啊这个变量,在非严格模式下会创建一个全局变量a
87 | 。不过,非常不建议这么做,因为轻则污染全局变量,重则造成内存泄漏(比如:a = 一个非常大的数组,a在全局变量中,一直用有引用,程序不会自动将其销毁)。
88 |
89 | ## 可执行代码块及其执行上下文
90 | ### 可执行代码块:
91 | - **函数代码块(Function code)**:函数执行上下文 — 每当一个函数被调用时, 都会为该函数创建一个新的上下文。每个函数都有它自己的执行上下文,不过是在函数被调用时创建的。函数上下文可以有任意多个。每当一个新的执行上下文被创建
92 | - **全局代码块(Global code)**:全局执行上下文 — 这是基础上下文,任何不在函数内部的代码都在全局上下文中。它会执行两件事:创建一个全局的 window 对象(浏览器的情况下),并且设置 this 的值等于这个全局对象。一个程序中只会有一个全局执行上下文。
93 | - **eval代码块(Eval code)**:Eval 执行上下文 — 执行在 eval 内部的代码也会有它属于自己的执行上下文,除非你想搞黑魔法,不然不要轻易使用它
94 |
95 | ### 执行上下文分为两个阶段:
96 | - **创建阶段**
97 | - **执行阶段**
98 |
99 | 我们主要讨论创建阶段,执行阶段的主要工作就是分配变量.
100 |
101 | 执行上下文的创建阶段主要解决以下三点:
102 | - **1.决定 this 的指向**
103 | - **2.创建词法环境(LexicalEnvironment)**
104 | - **3.创建变量环境(VariableEnvironment)**
105 |
106 | #### 1.决定this指向
107 | 我们应该知道this的指向是在代码执行阶段确定的,所谓的『代码执行阶段』正是『执行上下文的创建阶段』。
108 |
109 | ::: tip
110 | this是怎么被绑定的呢?
111 | 在创建可执行上下文的时候,根据代码的执行条件,来判断分别进行默认绑定、隐式绑定、显示绑定等。
112 | :::
113 |
114 | #### 2.创建词法环境(LexicalEnvironment)
115 | - 全局环境:全局环境的外部环境引用是 null,它拥有内建的 Object/Array/等、在环境记录器内的原型函数(关联全局对象,比如 window 对象)还有任何用户定义的全局变量,并且 this的值指向全局对象。
116 | - 模块环境:包含模块顶级声明的绑定以及模块显式导入的绑定。 模块环境的外部环境是全局环境。
117 | - 函数环境:函数内部用户定义的变量存储在环境记录器中,外部引用既可以是其它函数的内部词法环境,也可以是全局词法环境
118 |
119 | 环境记录器包含了环境记录器(Environment Record)和外部环境的引用(outer Lexical Environment):
120 | - **环境记录器(Environment Record)**:是存储变量和函数声明的实际位置。包含了
121 | - **声明式环境记录器(DecarativeEnvironmentRecord)**:范围包含函数定义,变量声明,try...catch等,此类型对应其范围内包含的声明定义的标识符集
122 | - **对象式环境记录器(ObjectEnvironmentRecord)**:由程序级别的(Program)对象、声明、with语句等创建,与称为其绑定对象的对象相关联,此类型对应于其绑定对象的属性名称的字符串标识符名称集
123 | - **外部环境的引用(outer Lexical Environment)**:指它可以访问其父级词法环境(即作用域)
124 |
125 | ::: warning
126 | 作用域链是怎么形成的?
127 | 可执行上下文中的词法环境中含有外部词法环境的引用,我们可以通过这个引用获取外部词法环境的变量、声明等,这些引用串联起来一直指向全局的词法环境,因此形成了作用域链。
128 | :::
129 |
130 | #### 3.创建变量环境(VariableEnvironment)
131 | 变量环境的定义在es5标准和es6标准是略有不同的,我们采用es6的标准,变量环境也是一个词法环境,但不同的是词法环境被用来存储函数声明和变量(let 和 const)绑定,而变量环境只用来存储 var 变量绑定
132 |
133 |
134 | ```js
135 | // 当前词法环境(LexicalEnvironment)--window
136 | // 环境记录器(Environment Record) 存储变量和函数声明的实际位置
137 | // 外部环境的引用(outer Lexical Environment):null
138 | var d = 4;
139 | var fn3 = function () {
140 | debugger
141 | // 当前创建词法环境(LexicalEnvironment)--fn3
142 | // 环境记录器(Environment Record
143 | // 外部环境的引用(outer Lexical Environment):window ↑
144 | var c = 3;
145 | var fn2 = function () {
146 | // 当前词法环境(LexicalEnvironment)--fn2
147 | // 环境记录器(Environment Record
148 | // 外部环境的引用(outer Lexical Environment):fn3 ↑
149 | var b = 2;
150 | var fn1= function () {
151 | // 当前词法环境(LexicalEnvironment)--fn1
152 | // 环境记录器(Environment Record
153 | // 外部环境的引用(outer Lexical Environment):fn2 ↑
154 | var a = 1;
155 | console.log(d);
156 | // console.log(test);
157 | return d;
158 | }
159 | return fn1();
160 | }
161 | return fn2();
162 | }
163 | console.log('result:',fn3())
164 | ```
165 | ## javascript执行过程
166 | 这里大致说一下JavaScript执行过程。后面有时间整理一篇JavaScript运行过程的文章。
167 |
168 |
169 |
170 | ## 闭包的应用
171 | 闭包在前端开发中又哪些应用呢?
172 | ### 构造方法传参来访问私有变量
173 | 可以通过构造方法传参来访问私有变量
174 | ```js
175 | function Desk(){
176 | var str="";//局部变量str,默认值为""
177 | this.getStr=function(){
178 | return str;
179 | }
180 | this.setStr=function(value){
181 | str=value;
182 | };
183 | }
184 | var desk=new Desk();
185 | //为构造函数的局部变量写入值。
186 | desk.setStr("hello workd");
187 | //获取构造函数的局部变量
188 | console.log(desk.getStr());//hello workd
189 | ```
190 | ### 模拟块级作用域
191 | if(){}for(){}等没有作用域,所以在其块内声明的变量,在外部是可以使用的.
192 | ```js
193 | //javaScript没有块级作用域的概念
194 | function fn(num){
195 | for(var i=0;i