diff --git a/404.html b/404.html index 15eecf1cf..65ab9b2a7 100644 --- a/404.html +++ b/404.html @@ -20,7 +20,7 @@
Skip to content

404

PAGE NOT FOUND

But if you don't change your direction, and if you keep looking, you may end up where you are heading.

Released under the MIT License.

- diff --git a/assets/index.md.0d318df1.js b/assets/index.md.4abc46fe.js similarity index 95% rename from assets/index.md.0d318df1.js rename to assets/index.md.4abc46fe.js index fd2f31e0e..a6a5ea9cf 100644 --- a/assets/index.md.0d318df1.js +++ b/assets/index.md.4abc46fe.js @@ -1 +1 @@ -import{_ as t,o as e,c as a}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"Home","description":"","frontmatter":{"layout":"home","title":"Home","hero":{"name":"ran","text":"风起于青萍之末","tagline":"A ship in harbor is safe, but that is not what ships are built for.","image":{"src":"/home.svg","alt":"logo"},"actions":[{"theme":"brand","text":"更多详情","link":"https://github.com/chaxus/ran"},{"theme":"alt","text":"访问我的GitHub","link":"https://github.com/chaxus/ran"}]},"features":[{"icon":"⚡️","title":"记录","details":"每当遇到问题或者可以改进的事情的时候,会把想法先写下来,如果这是你遇到的问题,那么很可能有一群人也遇到同样的困难。"},{"icon":"🖖","title":"解决","details":"过一段时间后,再回来看看这些问题是否还有意义。然后再研究这个问题,确定是否存在解决方案。"},{"icon":"🛠️","title":"改进","details":"通常会发现一个工具是为了解决一个问题,我会去考虑如何改进或者简化这个工具。创造一个更好的轮子。"}]},"headers":[],"relativePath":"index.md","lastUpdated":1694276611000}'),i={name:"index.md"};function o(s,n,r,c,l,h){return e(),a("div")}const p=t(i,[["render",o]]);export{m as __pageData,p as default}; +import{_ as t,o as e,c as a}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"Home","description":"","frontmatter":{"layout":"home","title":"Home","hero":{"name":"ran","text":"风起于青萍之末","tagline":"A ship in harbor is safe, but that is not what ships are built for.","image":{"src":"/home.svg","alt":"logo"},"actions":[{"theme":"brand","text":"更多详情","link":"https://github.com/chaxus/ran"},{"theme":"alt","text":"访问我的GitHub","link":"https://github.com/chaxus/ran"}]},"features":[{"icon":"⚡️","title":"记录","details":"每当遇到问题或者可以改进的事情的时候,会把想法先写下来,如果这是你遇到的问题,那么很可能有一群人也遇到同样的困难。"},{"icon":"🖖","title":"解决","details":"过一段时间后,再回来看看这些问题是否还有意义。然后再研究这个问题,确定是否存在解决方案。"},{"icon":"🛠️","title":"改进","details":"通常会发现一个工具是为了解决一个问题,我会去考虑如何改进或者简化这个工具。创造一个更好的轮子。"}]},"headers":[],"relativePath":"index.md","lastUpdated":1694419899000}'),i={name:"index.md"};function o(s,n,r,c,l,h){return e(),a("div")}const p=t(i,[["render",o]]);export{m as __pageData,p as default}; diff --git a/assets/index.md.0d318df1.lean.js b/assets/index.md.4abc46fe.lean.js similarity index 95% rename from assets/index.md.0d318df1.lean.js rename to assets/index.md.4abc46fe.lean.js index fd2f31e0e..a6a5ea9cf 100644 --- a/assets/index.md.0d318df1.lean.js +++ b/assets/index.md.4abc46fe.lean.js @@ -1 +1 @@ -import{_ as t,o as e,c as a}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"Home","description":"","frontmatter":{"layout":"home","title":"Home","hero":{"name":"ran","text":"风起于青萍之末","tagline":"A ship in harbor is safe, but that is not what ships are built for.","image":{"src":"/home.svg","alt":"logo"},"actions":[{"theme":"brand","text":"更多详情","link":"https://github.com/chaxus/ran"},{"theme":"alt","text":"访问我的GitHub","link":"https://github.com/chaxus/ran"}]},"features":[{"icon":"⚡️","title":"记录","details":"每当遇到问题或者可以改进的事情的时候,会把想法先写下来,如果这是你遇到的问题,那么很可能有一群人也遇到同样的困难。"},{"icon":"🖖","title":"解决","details":"过一段时间后,再回来看看这些问题是否还有意义。然后再研究这个问题,确定是否存在解决方案。"},{"icon":"🛠️","title":"改进","details":"通常会发现一个工具是为了解决一个问题,我会去考虑如何改进或者简化这个工具。创造一个更好的轮子。"}]},"headers":[],"relativePath":"index.md","lastUpdated":1694276611000}'),i={name:"index.md"};function o(s,n,r,c,l,h){return e(),a("div")}const p=t(i,[["render",o]]);export{m as __pageData,p as default}; +import{_ as t,o as e,c as a}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"Home","description":"","frontmatter":{"layout":"home","title":"Home","hero":{"name":"ran","text":"风起于青萍之末","tagline":"A ship in harbor is safe, but that is not what ships are built for.","image":{"src":"/home.svg","alt":"logo"},"actions":[{"theme":"brand","text":"更多详情","link":"https://github.com/chaxus/ran"},{"theme":"alt","text":"访问我的GitHub","link":"https://github.com/chaxus/ran"}]},"features":[{"icon":"⚡️","title":"记录","details":"每当遇到问题或者可以改进的事情的时候,会把想法先写下来,如果这是你遇到的问题,那么很可能有一群人也遇到同样的困难。"},{"icon":"🖖","title":"解决","details":"过一段时间后,再回来看看这些问题是否还有意义。然后再研究这个问题,确定是否存在解决方案。"},{"icon":"🛠️","title":"改进","details":"通常会发现一个工具是为了解决一个问题,我会去考虑如何改进或者简化这个工具。创造一个更好的轮子。"}]},"headers":[],"relativePath":"index.md","lastUpdated":1694419899000}'),i={name:"index.md"};function o(s,n,r,c,l,h){return e(),a("div")}const p=t(i,[["render",o]]);export{m as __pageData,p as default}; diff --git a/assets/src_article_astParse_tokenizer.md.ccc361f6.js b/assets/src_article_astParse_tokenizer.md.99a1983d.js similarity index 99% rename from assets/src_article_astParse_tokenizer.md.ccc361f6.js rename to assets/src_article_astParse_tokenizer.md.99a1983d.js index bfcef6352..34c5771a5 100644 --- a/assets/src_article_astParse_tokenizer.md.ccc361f6.js +++ b/assets/src_article_astParse_tokenizer.md.99a1983d.js @@ -1,4 +1,4 @@ -import{_ as a,o as n,c as l,N as o}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/Literal.4f8173cf.jpeg",e="/ran/assets/Identifier.91b58315.jpeg",t="/ran/assets/Statement.98dca542.jpeg",c="/ran/assets/Declaration.1f7b4e23.jpeg",r="/ran/assets/Expression.d8010e56.jpeg",D="/ran/assets/ExpressionStatement.15a42b4e.jpeg",y="/ran/assets/Class.614486e5.jpeg",F="/ran/assets/import.32c7331a.jpeg",B="/ran/assets/export.84f41d4d.jpeg",i="/ran/assets/Program.e2066113.jpeg",d="/ran/assets/File.9a43a095.jpeg",E="/ran/assets/axtexplorer.2ebc951a.jpeg",A="/ran/assets/axtexplorerSave.21965993.jpeg",s="/ran/assets/Comment.4c895119.jpeg",C="/ran/assets/extra.ff9e7b7d.jpeg",v=JSON.parse('{"title":"Abstract Syntax Tree","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/astParse/tokenizer.md","lastUpdated":1694276611000}'),u={name:"src/article/astParse/tokenizer.md"},h=o('

Abstract Syntax Tree

一.(abstract syntax tree)抽象语法树的作用

源码是一串按照语法格式来组织的字符串,人能够认识,但是计算机并不认识,想让计算机认识就要转成一种数据结构,通过不同的对象来保存不同的数据,并且按照依赖关系组织起来,这种数据结构就是抽象语法树(abstract syntax tree)。

之所以叫“抽象”语法树是因为数据结构中省略掉了一些无具体意义的分隔符比如 ; { } 等。

有了 AST,计算机就能理解源码字符串的意思,而理解是能够转换的前提,所以编译的第一步需要把源码 parseAST

转成 AST 之后就可以通过修改 AST ,分析 AST 的方式来修改和分析代码,比如 babel 就通过这种方式进行代码的转换,比如 rollupTree Shaking ,就是通过分析 AST的 导入导出语法,从而分析出没有使用的代码,进行去除。

二.常见的 AST 节点

常见的 AST 节点 AST 是对源码的抽象,字面量、标识符、表达式、语句、模块语法、class 语法都有各自的 AST。

我们分别来了解一下:

Literal

Literal 是字面量的意思,比如 let name = 'value'中,'value'就是一个字符串字面量 StringLiteral,相应的还有数字字面量 NumericLiteral,布尔字面量 BooleanLiteral,字符串字面量 StringLiteral,正则表达式字面量 RegExpLiteral 等。

下面这些字面量都有对应的 Literal 节点:

代码中的字面量很多,babel 就是通过 xxLiteral 来抽象这部分内容的。

Identifier

Identifer 是标识符的意思,变量名、属性名、参数名等各种声明和引用的名字,都是Identifer

我们知道, JS 中的标识符只能包含字母或数字或下划线 (“_”) 或美元符号 (“$”) ,且不能以数字开头。这是 Identifier 的词法特点。

尝试分析一下,下面这一段代码里面有多少 Identifier 呢?

js
const name = 'value'
+import{_ as a,o as n,c as l,N as o}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/Literal.4f8173cf.jpeg",e="/ran/assets/Identifier.91b58315.jpeg",t="/ran/assets/Statement.98dca542.jpeg",c="/ran/assets/Declaration.1f7b4e23.jpeg",r="/ran/assets/Expression.d8010e56.jpeg",D="/ran/assets/ExpressionStatement.15a42b4e.jpeg",y="/ran/assets/Class.614486e5.jpeg",F="/ran/assets/import.32c7331a.jpeg",B="/ran/assets/export.84f41d4d.jpeg",i="/ran/assets/Program.e2066113.jpeg",d="/ran/assets/File.9a43a095.jpeg",E="/ran/assets/axtexplorer.2ebc951a.jpeg",A="/ran/assets/axtexplorerSave.21965993.jpeg",s="/ran/assets/Comment.4c895119.jpeg",C="/ran/assets/extra.ff9e7b7d.jpeg",v=JSON.parse('{"title":"Abstract Syntax Tree","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/astParse/tokenizer.md","lastUpdated":1694419899000}'),u={name:"src/article/astParse/tokenizer.md"},h=o('

Abstract Syntax Tree

一.(abstract syntax tree)抽象语法树的作用

源码是一串按照语法格式来组织的字符串,人能够认识,但是计算机并不认识,想让计算机认识就要转成一种数据结构,通过不同的对象来保存不同的数据,并且按照依赖关系组织起来,这种数据结构就是抽象语法树(abstract syntax tree)。

之所以叫“抽象”语法树是因为数据结构中省略掉了一些无具体意义的分隔符比如 ; { } 等。

有了 AST,计算机就能理解源码字符串的意思,而理解是能够转换的前提,所以编译的第一步需要把源码 parseAST

转成 AST 之后就可以通过修改 AST ,分析 AST 的方式来修改和分析代码,比如 babel 就通过这种方式进行代码的转换,比如 rollupTree Shaking ,就是通过分析 AST的 导入导出语法,从而分析出没有使用的代码,进行去除。

二.常见的 AST 节点

常见的 AST 节点 AST 是对源码的抽象,字面量、标识符、表达式、语句、模块语法、class 语法都有各自的 AST。

我们分别来了解一下:

Literal

Literal 是字面量的意思,比如 let name = 'value'中,'value'就是一个字符串字面量 StringLiteral,相应的还有数字字面量 NumericLiteral,布尔字面量 BooleanLiteral,字符串字面量 StringLiteral,正则表达式字面量 RegExpLiteral 等。

下面这些字面量都有对应的 Literal 节点:

代码中的字面量很多,babel 就是通过 xxLiteral 来抽象这部分内容的。

Identifier

Identifer 是标识符的意思,变量名、属性名、参数名等各种声明和引用的名字,都是Identifer

我们知道, JS 中的标识符只能包含字母或数字或下划线 (“_”) 或美元符号 (“$”) ,且不能以数字开头。这是 Identifier 的词法特点。

尝试分析一下,下面这一段代码里面有多少 Identifier 呢?

js
const name = 'value'
 
 function say(name) {
   console.log(name)
diff --git a/assets/src_article_astParse_tokenizer.md.ccc361f6.lean.js b/assets/src_article_astParse_tokenizer.md.99a1983d.lean.js
similarity index 93%
rename from assets/src_article_astParse_tokenizer.md.ccc361f6.lean.js
rename to assets/src_article_astParse_tokenizer.md.99a1983d.lean.js
index 3e0c08532..395d4b42e 100644
--- a/assets/src_article_astParse_tokenizer.md.ccc361f6.lean.js
+++ b/assets/src_article_astParse_tokenizer.md.99a1983d.lean.js
@@ -1 +1 @@
-import{_ as a,o as n,c as l,N as o}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/Literal.4f8173cf.jpeg",e="/ran/assets/Identifier.91b58315.jpeg",t="/ran/assets/Statement.98dca542.jpeg",c="/ran/assets/Declaration.1f7b4e23.jpeg",r="/ran/assets/Expression.d8010e56.jpeg",D="/ran/assets/ExpressionStatement.15a42b4e.jpeg",y="/ran/assets/Class.614486e5.jpeg",F="/ran/assets/import.32c7331a.jpeg",B="/ran/assets/export.84f41d4d.jpeg",i="/ran/assets/Program.e2066113.jpeg",d="/ran/assets/File.9a43a095.jpeg",E="/ran/assets/axtexplorer.2ebc951a.jpeg",A="/ran/assets/axtexplorerSave.21965993.jpeg",s="/ran/assets/Comment.4c895119.jpeg",C="/ran/assets/extra.ff9e7b7d.jpeg",v=JSON.parse('{"title":"Abstract Syntax Tree","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/astParse/tokenizer.md","lastUpdated":1694276611000}'),u={name:"src/article/astParse/tokenizer.md"},h=o("",150),f=[h];function m(g,b,T,k,x,_){return n(),l("div",null,f)}const j=a(u,[["render",m]]);export{v as __pageData,j as default};
+import{_ as a,o as n,c as l,N as o}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/Literal.4f8173cf.jpeg",e="/ran/assets/Identifier.91b58315.jpeg",t="/ran/assets/Statement.98dca542.jpeg",c="/ran/assets/Declaration.1f7b4e23.jpeg",r="/ran/assets/Expression.d8010e56.jpeg",D="/ran/assets/ExpressionStatement.15a42b4e.jpeg",y="/ran/assets/Class.614486e5.jpeg",F="/ran/assets/import.32c7331a.jpeg",B="/ran/assets/export.84f41d4d.jpeg",i="/ran/assets/Program.e2066113.jpeg",d="/ran/assets/File.9a43a095.jpeg",E="/ran/assets/axtexplorer.2ebc951a.jpeg",A="/ran/assets/axtexplorerSave.21965993.jpeg",s="/ran/assets/Comment.4c895119.jpeg",C="/ran/assets/extra.ff9e7b7d.jpeg",v=JSON.parse('{"title":"Abstract Syntax Tree","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/astParse/tokenizer.md","lastUpdated":1694419899000}'),u={name:"src/article/astParse/tokenizer.md"},h=o("",150),f=[h];function m(g,b,T,k,x,_){return n(),l("div",null,f)}const j=a(u,[["render",m]]);export{v as __pageData,j as default};
diff --git a/assets/src_article_babel.md.31e21b4d.js b/assets/src_article_babel.md.90287ca6.js
similarity index 95%
rename from assets/src_article_babel.md.31e21b4d.js
rename to assets/src_article_babel.md.90287ca6.js
index 6db16cd0b..c1a06612c 100644
--- a/assets/src_article_babel.md.31e21b4d.js
+++ b/assets/src_article_babel.md.90287ca6.js
@@ -1 +1 @@
-import{_ as e,o as a,c as t,N as l}from"./chunks/framework.6fe2e870.js";const u=JSON.parse('{"title":"Babel","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/babel.md","lastUpdated":1694276611000}'),r={name:"src/article/babel.md"},i=l('

Babel

babel 核心库主要是:

  • @babel/parser 对源码进行 parse,可以通过 plugins、sourceType 等来指定 parse 语法,功能是把源码转成 AST。
  • @babel/traverse 通过 visitor 函数对遍历到的 ast 进行处理,分为 enter 和 exit 两个阶段,具体操作 AST 使用 path 的 api,还可以通过 state 来在遍历过程中传递一些数据
  • @babel/types 用于创建、判断 AST 节点,提供了 xxx、isXxx、assertXxx 的 api
  • @babel/template 当需要批量创建 AST 的时候可以使用 @babel/template 来简化 AST 创建逻辑。
  • @babel/code-frame 可以创建友好的报错信息
  • @babel/generator 打印 AST 成目标代码字符串,支持 comments、minified、sourceMaps 等选项。
  • @babel/core 基于上面的包来完成 babel 的编译流程,并应用 plugin 和 preset。
',3),s=[i];function b(o,c,p,n,_,d){return a(),t("div",null,s)}const T=e(r,[["render",b]]);export{u as __pageData,T as default}; +import{_ as e,o as a,c as t,N as l}from"./chunks/framework.6fe2e870.js";const u=JSON.parse('{"title":"Babel","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/babel.md","lastUpdated":1694419899000}'),r={name:"src/article/babel.md"},i=l('

Babel

babel 核心库主要是:

  • @babel/parser 对源码进行 parse,可以通过 plugins、sourceType 等来指定 parse 语法,功能是把源码转成 AST。
  • @babel/traverse 通过 visitor 函数对遍历到的 ast 进行处理,分为 enter 和 exit 两个阶段,具体操作 AST 使用 path 的 api,还可以通过 state 来在遍历过程中传递一些数据
  • @babel/types 用于创建、判断 AST 节点,提供了 xxx、isXxx、assertXxx 的 api
  • @babel/template 当需要批量创建 AST 的时候可以使用 @babel/template 来简化 AST 创建逻辑。
  • @babel/code-frame 可以创建友好的报错信息
  • @babel/generator 打印 AST 成目标代码字符串,支持 comments、minified、sourceMaps 等选项。
  • @babel/core 基于上面的包来完成 babel 的编译流程,并应用 plugin 和 preset。
',3),s=[i];function b(o,c,p,n,_,d){return a(),t("div",null,s)}const T=e(r,[["render",b]]);export{u as __pageData,T as default}; diff --git a/assets/src_article_babel.md.31e21b4d.lean.js b/assets/src_article_babel.md.90287ca6.lean.js similarity index 83% rename from assets/src_article_babel.md.31e21b4d.lean.js rename to assets/src_article_babel.md.90287ca6.lean.js index e642ea63d..ff63c76cc 100644 --- a/assets/src_article_babel.md.31e21b4d.lean.js +++ b/assets/src_article_babel.md.90287ca6.lean.js @@ -1 +1 @@ -import{_ as e,o as a,c as t,N as l}from"./chunks/framework.6fe2e870.js";const u=JSON.parse('{"title":"Babel","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/babel.md","lastUpdated":1694276611000}'),r={name:"src/article/babel.md"},i=l("",3),s=[i];function b(o,c,p,n,_,d){return a(),t("div",null,s)}const T=e(r,[["render",b]]);export{u as __pageData,T as default}; +import{_ as e,o as a,c as t,N as l}from"./chunks/framework.6fe2e870.js";const u=JSON.parse('{"title":"Babel","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/babel.md","lastUpdated":1694419899000}'),r={name:"src/article/babel.md"},i=l("",3),s=[i];function b(o,c,p,n,_,d){return a(),t("div",null,s)}const T=e(r,[["render",b]]);export{u as __pageData,T as default}; diff --git a/assets/src_article_bundle.md.7a4db991.js b/assets/src_article_bundle.md.1794ffc6.js similarity index 93% rename from assets/src_article_bundle.md.7a4db991.js rename to assets/src_article_bundle.md.1794ffc6.js index f15d76302..360ed3a7e 100644 --- a/assets/src_article_bundle.md.7a4db991.js +++ b/assets/src_article_bundle.md.1794ffc6.js @@ -1 +1 @@ -import{_ as l,o as t,c as a,x as e,a as n}from"./chunks/framework.6fe2e870.js";const B=JSON.parse('{"title":"Bundle","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/bundle.md","lastUpdated":1694276611000}'),s={name:"src/article/bundle.md"},d=e("h1",{id:"bundle",tabindex:"-1"},[n("Bundle "),e("a",{class:"header-anchor",href:"#bundle","aria-label":'Permalink to "Bundle"'},"​")],-1),o=e("p",null,"Bundle 的本质就是输入,转换,输出。在机器上直接运行的代码,往往都难以维护和理解,我们需要将开发者方便理解和维护的代码,通过打包等工具转换成方便机器或者程序使用的代码。对于 web 前端来说,打包工具,至少需要以下功能:",-1),r=e("ul",null,[e("li",null,"编译能力"),e("li",null,"插件机制"),e("li",null,"HMR"),e("li",null,"cli 和命令行能力")],-1),c=[d,o,r];function i(u,_,p,h,m,b){return t(),a("div",null,c)}const x=l(s,[["render",i]]);export{B as __pageData,x as default}; +import{_ as l,o as t,c as a,x as e,a as n}from"./chunks/framework.6fe2e870.js";const B=JSON.parse('{"title":"Bundle","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/bundle.md","lastUpdated":1694419899000}'),s={name:"src/article/bundle.md"},d=e("h1",{id:"bundle",tabindex:"-1"},[n("Bundle "),e("a",{class:"header-anchor",href:"#bundle","aria-label":'Permalink to "Bundle"'},"​")],-1),o=e("p",null,"Bundle 的本质就是输入,转换,输出。在机器上直接运行的代码,往往都难以维护和理解,我们需要将开发者方便理解和维护的代码,通过打包等工具转换成方便机器或者程序使用的代码。对于 web 前端来说,打包工具,至少需要以下功能:",-1),r=e("ul",null,[e("li",null,"编译能力"),e("li",null,"插件机制"),e("li",null,"HMR"),e("li",null,"cli 和命令行能力")],-1),c=[d,o,r];function i(u,_,p,h,m,b){return t(),a("div",null,c)}const x=l(s,[["render",i]]);export{B as __pageData,x as default}; diff --git a/assets/src_article_bundle.md.7a4db991.lean.js b/assets/src_article_bundle.md.1794ffc6.lean.js similarity index 93% rename from assets/src_article_bundle.md.7a4db991.lean.js rename to assets/src_article_bundle.md.1794ffc6.lean.js index f15d76302..360ed3a7e 100644 --- a/assets/src_article_bundle.md.7a4db991.lean.js +++ b/assets/src_article_bundle.md.1794ffc6.lean.js @@ -1 +1 @@ -import{_ as l,o as t,c as a,x as e,a as n}from"./chunks/framework.6fe2e870.js";const B=JSON.parse('{"title":"Bundle","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/bundle.md","lastUpdated":1694276611000}'),s={name:"src/article/bundle.md"},d=e("h1",{id:"bundle",tabindex:"-1"},[n("Bundle "),e("a",{class:"header-anchor",href:"#bundle","aria-label":'Permalink to "Bundle"'},"​")],-1),o=e("p",null,"Bundle 的本质就是输入,转换,输出。在机器上直接运行的代码,往往都难以维护和理解,我们需要将开发者方便理解和维护的代码,通过打包等工具转换成方便机器或者程序使用的代码。对于 web 前端来说,打包工具,至少需要以下功能:",-1),r=e("ul",null,[e("li",null,"编译能力"),e("li",null,"插件机制"),e("li",null,"HMR"),e("li",null,"cli 和命令行能力")],-1),c=[d,o,r];function i(u,_,p,h,m,b){return t(),a("div",null,c)}const x=l(s,[["render",i]]);export{B as __pageData,x as default}; +import{_ as l,o as t,c as a,x as e,a as n}from"./chunks/framework.6fe2e870.js";const B=JSON.parse('{"title":"Bundle","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/bundle.md","lastUpdated":1694419899000}'),s={name:"src/article/bundle.md"},d=e("h1",{id:"bundle",tabindex:"-1"},[n("Bundle "),e("a",{class:"header-anchor",href:"#bundle","aria-label":'Permalink to "Bundle"'},"​")],-1),o=e("p",null,"Bundle 的本质就是输入,转换,输出。在机器上直接运行的代码,往往都难以维护和理解,我们需要将开发者方便理解和维护的代码,通过打包等工具转换成方便机器或者程序使用的代码。对于 web 前端来说,打包工具,至少需要以下功能:",-1),r=e("ul",null,[e("li",null,"编译能力"),e("li",null,"插件机制"),e("li",null,"HMR"),e("li",null,"cli 和命令行能力")],-1),c=[d,o,r];function i(u,_,p,h,m,b){return t(),a("div",null,c)}const x=l(s,[["render",i]]);export{B as __pageData,x as default}; diff --git a/assets/src_article_designMode.md.fdb686ab.js b/assets/src_article_designMode.md.c8355f94.js similarity index 99% rename from assets/src_article_designMode.md.fdb686ab.js rename to assets/src_article_designMode.md.c8355f94.js index 7de719ff6..8922ef965 100644 --- a/assets/src_article_designMode.md.fdb686ab.js +++ b/assets/src_article_designMode.md.c8355f94.js @@ -1,4 +1,4 @@ -import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/继承.d41dee10.png",o="data:image/png;base64,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",e="/ran/assets/组合.df5fa5b1.png",t="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfIAAAEiCAMAAAA1caDNAAAAjVBMVEX///8yMjKYmJj8/Pz09PRkZGSvr69CQkL6+vrS0tJDQ0NBQUFWVlbOzs7Nzc1vb287Ozs+Pj7Hx8c0NDTv7++JiYl/f3/AwMCmpqY2Njb+/v5mZmb39/eOjo5NTU3f39/W1tafn590dHRxcXFbW1v29vbo6Ojk5ORGRkarq6vn5+fZ2dm3t7ezs7N4eHiKJ4owAAAGMElEQVR42uzdy07bUBSF4bXrKyY3nMQkzYUQQkBF5f0fr0mZdeRItWSz/k86kz3x4JftozM5AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP6XJM+K6FCR5YnQI8k0OjeleZ/kMRqn6lA6HkUu9EcWY3VsEpnQH0Wk6lgahdAfEfrXIJ+BXuUgea+Q3A7J7ZDcDsntkNwOye2Q3A7J7ZDcDsntkNwOye2Q3A7J7ZDcDsntkNwOye2Q3A7J7ZDcDsntkNwOye20yBFfSP5NtMpxFyVv+bdBcjs3JC+X97PPVKpP6319mf1+f69X99UjyYflhuRNdl5sGunxUO72l9kubapl2uxJPiztky/iQ6ofJG0PP6K8izfVlzWJhOSD0j75If4qtatePq/J0+v8ukg+KO2Tn+OXrt7iSTXJh6t9cmXHc/JR6ynqxZTkw3VD8sVxtj7V0nK2X5F8uDhwtUNyOyS3Q3I7JLdDcjskt0NyOyS3Q3I7JLdDcjskt0NyOyS3Q3I7JLdDcjskt0NyOyS3Q3I7JLdDcjskt0NyO1xmbYcr6+3kMZqk6lA6GUUu9Ecyjc5Nfwo9kuRZER0qsjwRBu3En9nMa8Sr4GQTsRGMlHFRCj5eoqriKNhIIlarmLMH99FEtd1W0Qgu5vEsPcdcMLGM+1RKH2IneFjH8qv8WvBAcjt82P38Yd/ebiAEoQCICtuB9t/rduCfyQ1zTgWYCUZ5+HzL8ZOW83ssxdRYcM2xrdJj8zTHEYkeFxFyJM+RPEfyHMlzJM+RPEfyHMlzJM+RPEfyHMlzJM+RPEfyHMlzJM+RPEfyj917mrX2JPd1mmfx5sB3zrA5tafN8iOTX8PMGtGs0Rz6SH/u50AGAAAAYJC/9TXaDcoSWZppyRJZmmnJElmaackSWZppyRJZmmnJElmaackSWZppyRJZmmnJElmaackSWZppyRJZmmnJElmaackSWZppyRJZmmnJElmaackSWZppyRJZmmnJElmaackSWZppyRJZmmnJElmaackSWZppyRJZmmnJElmaackSWZppyRJZmmnJElmaackSWZppyRJZmmnJElmaackSxZ657DQOBFG0S207JNgQE8+YxwzhJSAI/v/3ME1gxQrFqlOluhINC6R7ro4MjWHROJ3EImLROJ3EImLROJ3EImLROJ3EImLROJ3EImLROJ3EImLROJ3EImLR/JTc1AuZMYu6yZaJWDSHSD6V2XOa7RKxaA6SRtquSjOm6lpp7BKxaA6SWro0c06ktkvEojlIFlKlmVPJwi4Ri8bM/VLELhGLxkxdKNfvQE9iEbFozNSFcv0O9CQWEYvGTF0o1+9AT2IRsWjM1IVy/Q70JBYRi8ZMXSjX70BPYhGxaMzUhXL9DvQkFhGLxkxdKNfvQE9iEbFozNSFcv0O9CQWEYvGTF0o1+9AT2IRsWjM1IVy/Q70JBYRi8ZMXSjX70BPYhGxaMzUhXL9DvQkFhGLxkxdKNfv+G2dHE/5PCDK5St/AcrXJVLO0Yvy74OiPJdUd9c3AOWf2WRXTzlOeclLezVwfrDLpSvlqynlIClfrv5kxO/yLP0U+fjIbpQTn/JxvYNc37JMx0k7HaF8TuW7/oxyYy/K71evrpTjbuzpdnWTSsaBoDz/b4d650k57ilvnrf7r9oRoHz5cDWk6uHVj/Lu23bHUJ6Pz9I+/RagfPv2cV0fHv0oLxHQ27dqM6aSf+d9Bigvn46OhlAus333+fPFuu/XF5vrEXJ9S2kpcu/m7/KSmqR8//7tEnFjT09fSH5excS/Vfax5wA9iUXEojFTF8r1O9CTWEQsGjN1oVy/Az2JRcSiMVMXyvU70JNYRCwaM3WhXL8DPYlFxKIxUxfK39u7YxsIYSCIorI4TIIgv/4LvRYusLWz0nsNzF+ZnPqN6JOyirJq2sx58vqN6JOyirJq2sx58vqN6JOyirJq2sx58vqN6JOyirJq2sx58vqN6JOyirJq2sx58vqN6JOyirJq2sx58vqN6JOyirJq/Mzaz6z9st4v6/8wx/1s/Y4/zz1m36KsmiWOd2z3fvsWZdWscczzGhtd5zw6F2XVAAAAAAAAAAAAAAAAACzxA5TVMRW7CUShAAAAAElFTkSuQmCC",c="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAY0AAACLCAMAAACqVzVKAAAAkFBMVEX///8yMjL8/Pw7Ozvz8/NkZGQ4ODhCQkKvr69OTk5VVVXl5eVEREQ0NDTu7u7Nzc1AQED5+fnp6enOzs5ISEj19fVvb29WVlaVlZX+/v7b29vU1NSenp6NjY2EhITw8PDr6+vg4ODJycm3t7ezs7OlpaV2dnZsbGxoaGhSUlLDw8O/v79xcXE9PT16enpaWlpyuPDWAAADTUlEQVR42u3d2VLiUBgE4D4nCyBJSGKi7OAuru//dpMAgjUXjGMVFv3bX1mVO9Jt1wHlJhARERERERERERERERERERERERERERERkd/Hd6OOO6JO1PU4RI32/IU7uotD4dXok667PA9xROH5peviADXai9w5jmzgIhyiRjsdF+LIQtfBAWq05xz+RnkPG42Ys9trxJzdXiPm7PYaMWe314g5u71GzNntNWLObq8Rc3Z7jZiz22vEnN1eI+bs9hoxZ7fXiDm7vUbM2e01Ys5urxFzdnuNmLPba8Sc3V4j5uz2GjFnt9eIObu9RszZ7TVizm6v0f+8buhPK/v377as+ddw/dPK/v27PUzxYewB9EM0Jh6Ea+R5XsG7IAgc4xq9Xi+teg00irzEvJy364yiNz9tSwWN017Dl+s1MjSC9sc7AJRruM/XmxdMev6qUwKo34doOH/yZ+N51a5xlYcG1jjbcGi8XyO6BYZRASCrSdZ4ma7PxsVwv0aSJJxrfLo+x7iLRoB/eMymSQW8MqzRj7P1GpOgvVZVDJ9+/Wz8qK+fjdEwW8WDpI9GcR8BKRAzrDG7336KR7Pt2ahz2jU+rvPH6TwOu5WrqipdLnZrvL4mJ73GIphs13gKss0aZUr/TnW2GBcx4OMRkNegORuzh91fuGfDzRrX95yf4ue9jdy5Jda//fGqvfp2jcUNwxqD8W6NSQaX5xVmt5xrbNTD5M5hs8Z8BhQBgCK9fGZYoxH6vltibQ7galXwrlEOk1mG7Rq3Sekx6LXHJr6meKdqvDn3OMKHfu8J3pcp4RrZ7UMyLGs/yddrjJPJOA06N2hcPQVu+794eNpr1MsMe493wHXq7vnWKIOXmwKL1AV3aIxRA/An8s3bN1+3QMszfmtYGPlG/ZTvYaMRc3Z7jZiz22vEnN1eI+bs9hoxZ7fXiDm7vUbM2e01Ys5urxFzdnuNmLPba8Sc3V4j5uz2GjFnt9eIObu9RszZ7TVizm6vEXN2e42Ys9trxJzdXiPm7PYaMWe314g5u71GzM9HsNeI+dkh9hp13eUgxBGFg388V0eNfviZU6MDAdTIyPPYfk0jEREREREREREREREREREREREREREREREREREROYo/dWMhiL/l5rAAAAAASUVORK5CYII=",r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZEAAACDCAMAAAB7ltZBAAAApVBMVEX///8yMjL8/PxBQUE7Ozuvr69kZGTl5eUzMzP09PTNzc3z8/Pu7u5WVlZSUlLY2Nhubm5HR0f+/v7s7OzOzs7KyspwcHBEREQ3Nzf29vbo6OihoaGOjo52dnZMTEw+Pj7Dw8NmZmb4+Pjw8PDg4OC8vLybm5uWlpaCgoJ/f396enpycnJpaWlfX1/c3Ny3t7eTk5OGhoZbW1uzs7Opqamnp6fS0tIlKBnqAAADP0lEQVR42u3dWVMaURQE4D73zsAMDLvIviPKEuMS8/9/WgBRgw9EqCLMOfZXVlm+cLvtYn8YEBERERERERERERERERERERERERERERERERHRV7kw4+WMfCZ0OISN9rmynN31oQJs9EkohasYZxRfFSTEIWy0JyNXOLOcZHAIG+3xEuPM8uJxCBvtEcFnKs+w00h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7/q16y1Aj7fk3Ss1iyU4j7fk3SkVp/qpaaXTMbedd+vJvxXci18k3XESy6cu/83MglfoJp+UfAdR68WycmkanLOK9r8BJEARy8fxvsj8kunVHnxYuAbT71e5I3SKuvV0kwVqw+XECID2LwD1E8iN77GlPgfeoVTC5GSbKFrkpbhaZ+nxaFwHqFRncHHfa8KkKzEfRqvc4yypb5LqzWQTl249FGo1GqhZBUha5ax1z2qrYaCxctelS9Mz4xdtuN2vbRX4H699RpdKEi464j3zA2ln/Kh7z36ohAlr3fva46nd0LdLt7Z7ZR93dfaQ1MLAINos89QfLzvB+rGqRSVDaLTIMktdF2pGBR61rL74AzEN0HnQ9anXL769+i7evi9R7Bp7ZgQhr4eK5X9O1SK70vkgpgXhfQfc5XYuc9uoXEXJAEvSn7YWqRdZil5Uatu4ATIvjVC1y4jtEF80L7j7jl66+1LbIQmRUxZtsfwjn2tHF8//1KUruhNNyzdmk5zutUab8om2RuJbgw6oD1KOod/H8W/H85E8ap+s1J4B76cbaFtk3xoa7fP7v/Wl8Ws/gN1apO4Pf6qbwDDuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtF8bwl4j7ddPsdcolEIujzPK5/51jSE2+v/X4aoeCMBGxq5V9y0aEREREREREREREREREREREREREan0Byk3I1baApDQAAAAAElFTkSuQmCC",y="data:image/png;base64,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",F="data:image/png;base64,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",D="/ran/assets/抽象工厂.786dc879.png",A="/ran/assets/单例.c53b9bde.jpg",B="/ran/assets/建造者.8aaf3334.jpeg",i="/ran/assets/原型.38aa29a0.jpg",E="/ran/assets/装饰.54bb2dbb.jpg",d="/ran/assets/外观.77eeb1fd.png",C="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAs8AAACQCAMAAADA63aOAAAAvVBMVEX///8yMjJERET9/f0+Pj5OTk47Ozvy8vJKSkr6+vpBQUHOzs7g4OBUVFRRUVH09PRkZGRXV1c3Nzfv7+9CQkL29vaCgoKvr6+5ubnKyspHR0erq6s0NDS+vr6np6eVlZX8/Pzc3NzY2Nhvb2+1tbWJiYnl5eWamprFxcVgYGBdXV2SkpJNTU2ysrKNjY1oaGjr6+vX19d+fn5ycnLS0tKioqJ5eXnp6ena2tqenp52dnbn5+dsbGwzMzN/f39aW3v0AAAJD0lEQVR42uzBgQAAAACAoP2pF6kCAAAAAAAAAAAAAAAAAACYXTvaTRQIowB8jqOgBQFdqlWQbletsba1S6WN3dT3f6xFG0ftLt4JE5jvwsQLE//zn5iJjKZpWrmJvuez7HyvL3Q458IpCzFmNYyFDifTuDSF7rNjuSg71+qwr8M5F05JeLRQBRY9Hc65cErCZ/l/gLZM+jqcc+GUBIlqIHU4FRi0PJPoPusWlGkS3WfdgjJNovusW5DHJC0oQfe5EoNeehLL6EAS85qAxDokK4pcfFP8oCRyNAuwZ0YznKVAOGq65CQxJaC3VeNH+jr9p892neEApxQYlEQ+bEruU5Ik60/OkhSyKBDOZa8DyCfxCq0s5m20UyPAAwPOFkMntQTw55FLXv3CqeJXRiIfLTvFRzslHB4giwLh5HMdYCzUWVna52CnRqSsxghwnZkAeNAEVkPGYsb6CMcUWFl+v8+HPt87tIMvjuJ9vuh1APkkXp2VxZSQujPqNp45BcDh/rzBZmvd5VQAUcjNO44VvjIS+bii9Bh7T/wSe8iiQDi5XAew6Kmzspgr00yMhWma18C01w4/NmEY95KTPn/QiEwAL6MmHwROVaTP+O203+4boRiwh9ZgWucErWjuIosC4eRyHcCkr87K3igtge7hzUmf7dd7hwJg4/r2DscKX1l+5435c7T+Wfexun1ZdD+9BedRk8MBsigQzn8/Vfg3I3ExYwYTw59sDdD67EA6PT/DIQA28E3hKyORD/dmU1u98AGp9+Cm1+2QXcNEtuLDqV6f26H4wZ0NcMclJIb7/zd2fR52q91nm0cWPr2Jx3nCBJkUCKdyfTbDNgK+BsErp8CaC0jBZH/emIwAm+1q9/kv++bakzgUhOF3ej9AqRRbClJucr+KsIqK/v+ftS0lG9lY42ax1HaeD6YlJod55wk5TA+W53n9DVGjHVxsZ/7ANq81S7J5v5Emn2/IHV43u0J+oxGEQVucQgoiNjTLt8+d9cJtkHGv0bRWHU2I3JJmwydtiBhSEE7ufHapJtEAEyLyMX6dIsbnARXu8u2zXCGaP1mwWiapm8KgTkR7oOUjjhSEkzufxQzLhw5GZqUtA/4WfzGY4cBCqSPfPmNb6yKiOLYEMFs+6fiMFISTO5+/TEzrLt+yNITzEakIh33+Fy4eDIeTinjYZ/aZfc4B7DP7nCXYZ/Y5S7DP7HOWYJ9z4nNuQACH8yHs8w+Efc6Fz8gHvN/IyX4D+YB9Zp+zBPvMPmcJ9pl9zhLsM/ucJdjnrPpcd7hlHE5mfO7Z5o5bxuFkxucy2S2ZW8bhZMNnWC7Rpsot43CS83mJd5TaZ17DU6hR55ZxOEn4LAoBVAgp4YA+L555jeGEXtsdbhmHk9DnMyGiQ8of6IxriPYrTYbcMg4naZ+Bk8uzrVFvkOJxyzic7/ZZkppSAEmSMgK6UnCvSAF697zvrHpL5DrcMg7ne32GPlg9QbeB5xICxEypAvJi9x1Hdss5ahkRh3MJnx8GxS18FQechbm8ctG7Kozki/t8h58LBXA4l/BZ+JuuZT4jZKg891qVyqo5cIDk9xtLvOdF+sE9iwrlcJLfP4copEkBFqzS7aprTsemAyTwfTB2bGiE2NfBHwDaEQpv/OnLvIfUExXK4VxiviG3bLpfI6C6Mmpds21gcKWfcw0x+9JIik6vTl962ZeLQLXQQ9+UkXaiQjmc5H2+u6lMhsU3e+p1gLH1y/CFBtmVbpzzPU+ZRo8M/qdltcJMAGjvAdnoI+1EhXI4SftcNZWHOgL0X8ZU1tvG/dpZVAAs5ttzrdGPeaQbPzYEqSFzVSVE7Cs9hMwXAJa3SDtRoRxO0j5jJ+OI/AIxGsqNQnl8uD3TGtZb7JGb+LEhIWA3FeghgqoIuaMuAO8aaScqlMPJ3Pm6mCORn48NBd2rKqkH2loIaQfWpAMokkDKiQrlcLLnc9yR9Q4RrT4eG6KqAcJGyOlHUMZaxuH8OJ9jflL0+diwWAbWTTXAkE9a9kglAF4BaScqlMPJns+x/x8/NsTTA+C6ABwFJy1Dow9gtkfaiQrlcHLr8/uxoVB9eSQ9ygL1yl8tW24AWV0g7USFcjg59fl0bDieiqtKCU7TVvqHF/UdOcfOKl145dTvEI+Fcjg59fl0bAgdPfndzPCGmi6OeJNHdY3UExXK4fxm54x61ASiKHxmxgoKCiiIUFEMcZ2m1k1aI9Xd/v+/1QESI3a7D2QfZrnzxeiDT3fup5mEk0PV5/cR+j/DfXNQczjG535g+pEo+xxFAMQcd8zxqTE+U/b5WdaXP1RcEkD+BsObuBt8CozPhH3O/gRB8OOQqvc9ZPiC1xMYKviNobwvU9A+62t8puuzm7pnicV5XkRQnI/5wLaZbdtLABYUJ2BatsoUdM/6Gp/p+nxcwt2IjYVNBoUn5A5gaChetxAMJ79dpqB71tf4TNdnJOCYNKyhWDg3nyMR83g0Q7xslynonvU1PhP2OcUYCg7FfjB7sRXMVmBrr/OynFdft8oUtM/6Gp+J++xPJiv1/wxgBiD0sEJF+Wviwj38U6agezbS+EzN5ybie/OZo341PudDgRWEA0UWIXt+KFPQP+trfKbm8x2pGLR9lt+AFeZpwmvYgCvuyhT0z/oanyn7vA0amcW49vnpS6I+rMRHzVe2zx/KFLTP+hqfCfuM3ab2+XIoEO1n8ioB7KeBhMI78uw6SfBQpqB51rfL4YfMAwUsFvbbZ9mUV3EIYH1++pmOQ87Hg2Gaj5zj+FwCWbqw2mUKmmd9uxy+zxxQwGF+v312ElTsoBgJAHnkWV40ykfT6XcXFdb10ipT0D3r2+XwYxY4FvqO5QQs7rfP/yfCDW0fbX/Y4YuC0aAQgJbXMYuF+v3GtKDToCL2Q9Z3Qj8WALS8jjnMNz7THrQrGl7H6puQWTPtQbui53WsEGbNtAftiobXseomZNZMfFDakFkzmUFpQ2bNZAalDZk1kxmUNmTWTGZQ2pBZM5lBaUNmzWQGpQ2ZNZMZlDYm4vu3XTsQAAAAYBjkb32PvTiiRPGlRPGlRPElRfEFAAAAAAAAAAAAAAAAAAAAAIADA572v7F9OdVZAAAAAElFTkSuQmCC",u="/ran/assets/享元.6ee46b37.png",h="/ran/assets/桥接.de284493.png",f="/ran/assets/适配器.1e901e8e.png",g="data:image/png;base64,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",m="data:image/png;base64,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",k="/ran/assets/解释器.07d142dd.jpg",b="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfoAAACYCAMAAAA7gNueAAAAvVBMVEX///8yMjL8/PzS0tJBQUH6+vr19fVRUVFYWFhHR0fOzs5OTk5VVVVlZWXu7u6vr68+Pj48PDzZ2dk3NzdeXl59fX1ERETy8vL+/v7p6elubm709PTJyclxcXFhYWHk5OSnp6eDg4NKSkq6urrW1tZqamrFxcWysrI2Njbg4OCJiYl2dnbw8PC3t7erq6uXl5eNjY339/dSUlLm5ubBwcHd3d1ZWVnr6+uioqKcnJyRkZGUlJQ5OTnQ0NC8vLxkx+d3AAAISElEQVR42uydiXKiQBRF72tpEUEFFdz3fYlLxqyz/P9nDRBl9pCZiTPd8Z0qJYU23PSp1qYfVYJhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhmMtElAoGnRGjUBJgFEQ06ex02L2KlMjJt3BGWnmHSmDUo0B5nJk8FcCoh0EtnJkaGWDUgwjfo+U5GCW1sHolYfUXC6u/WFj9xZKmRQpEfERM3e+hNhG9LKvXnzQtDx2JzQMqAhFtSyJL8sHpAWKey1UQ5HK5D6xex7XyNC315iMmhkWWZU2B5j0gqIb7awExBCxYAIap53iz3afzWnmqlqzodSHmiCjTGoDXw7qd/61R/2a7T+e18hdoebyHrCCiQHf9R79iecPuAKIA+CV/2lmsUs/xZrtP57XyFC0bg7Bfo2bE/Z+j9XZzqG4EQsyID6bpuWYh7Rxvtvt0XitP1UKwLCuohE/V7piyAJZbPFHcmPnupoU0iN5s96lygUN0FvUhW7sM4A6x+tkEIePVdbBsYN/v5ia+TDnHm+0+nbO/SH3p+pAbrIEn9Y1K9LwffQhneJjkcuY8A1avX/bUiztCuTApQj5Y46N6dPvhowjrdHFngdVrmD2lTbFp7spTRNyIk/pp0Gh8EKxe8+wpba4G4uHaMILAMLyhPKrHcthpAvNcbg4rFz6zeh2zp7QRAhF1EQKgKREzGyyAHtCLntBj9TpmVzWXnjG1yq5qLj1japVd1Vx6xtQqu6q59IypVXZVc+kZU6vsqubSM6ZW2VXNpWdMrbLTP4DVf48S56Cfwep1OC5/4KsUU6vsqubSM6ZW2VXNpWdMrbKrmkvPmFplVzWXnjG1yq5qLj1jqp69vVcz17fU8op2nzLH/f1zlCvXZRVzfUt9RVuhfkzN1JtU6dfVy/Ut4j1R952C3Xe248p/cI7sgKhTVL5P2xa5o988xF5D9cJfIGTTRERjKb972X3V7FceWW3V1aPYJBpkX3SIRg8ubu6yFYmIA75CXtXRr6mrHvdWD8DeXsRpq82pF0NH9dG27IvXyt6rEm2F4upR71fouvySQ2wKcOvdfNtBjAvTNiMMAP4KuL9SWD1204cgCIwgBLgrrBFDAOwQsu3JsPR62WX0VdpTXH0yL0n/0Jy8czMD7AaJ+iIiDIjlPLpdPBdRVFR9BGUT4Ue+jPqMeXi1Lk6+SlVXn8xLUg5hmiaZ5tSwhoZXMg0yzGsnwsg2C5VqtRo9qn01R/3ANb5V70YAhLYdQfbcDTevlj35KlVcPTCK5iWph1gUKtvsPTXwsEtG/QDwxWPWAmApPM2LdQuyIrIgwED8IMS0C7vWWWrv1/9E/V/z/vmY8rG7cD9Vd4UpVrNEvYEY1Ud9LHlPAsBcfqc+O7slwzRNh9X/gvpILEeoob8UQQ9yXKl+eJof2XlAi1H/LvIt5/hGfcYPSJ7ewR/4P8e0yTTNYsPoVyHtlbewRDLq57kTDVXVFweHbmQkFg5yXTfaYDpZEGJImWlewxb4FZ+q7+zyv57mrYcLjB0Bnw4IcesGHIccpwPgI4ChyqM+S/bG3wK4sWPJ1a90Uy6GoMHFXdEoY+aIf3xx11tVS2YeokOjWP27HIwojImO4zg2keeEKKq+PRyXvUarJTaFHy7uKPlb/SWd901ADK/+8ZIO5NIL+tLvHrxNpP7KP6kHxOh2NtwO3ik76lGTZh9XRMYhkdwSN17c1oyhV13Izf+0TYayyV/T60qzGG5nxhJyaXirGiY+gMkyepd8P5wPH8RTiwxJ9IPKErBnAHadf7uQW/OHy+LNfaGZxdQt3b0LmiWQ4zjXphhvc7s1hhhPmiV1l3QyAIREiIsYe+49IGSKmOlrlW/8+PszVf2q2Lj1w63fqsHvNoqh95ErcUc30bt8pyw/DreJ+h61sxkU6QbAVfAa5Zvg5eWbwx4h+TqAhrx1t4/r46jP+qUWgC6A8q6srPr/X7StUMTtUf0CGHnhtgwUo6epB+ke0O9Guov0EcAsSNQ3aAZgTOvIAcm/Lto+/k3Rtq6SIoXUJ7dqpIz6bORQZKgVGY2RGPiozqLXxlRD/PpJPa4sJ4/Tbsm3aqiYvb3Hi9Q3gJL1tKdB7457vbK7j/bdUQbAbIgyFYFp5FruAjRoAWBk8A1a6md/Rr3fWtjvj3sKnYYotwE4heXTu1a5ssgM+9h799hPSL7Ly75bh3UF4HHCt2Wqn/2XbTK0CbyBPKovrrzKbaT+nspP6vfLYG5uABxsu3tPsmfOzcPT5L5uz1i9+tmfUZ/FH3Dn3mBkSlavfvbXVo9RtWGP+T58DbI/p16h/13V7tM5u6q59IypVXZVc+kZU6vsqubSM6ZW2VPaPF+WZ/U6Z//tNgtTfinLs3qNs/92mwzJL2V5Vq9x9mcWctu3FWeMU6l+Y6yR93qgkKQsz+o1zv5cvf5u3bzFqVRf7+7Ebf9p1CdleVavcfbn6/VTEqdSPW68x0L9qD4py7N6fbM/W6+PPCeleviUR6K+xuqhefZU9UmpvmesJkf1SVmeP/A1zp6q/lSqF91tKygBC2qvcSrLs3qNs/+qTaL+VKp/sCVmXgMYVIKkLM/qNc5OhL8oy7N6jbMT4c/L8ryQq3N2VXPpGVOrX+HWpE9V7T6df3tfE/Wqdt9LKJGTr+GM1PIOld6selW77yWIJp2dTv3Nqle1+16EKBUMOiNGoSQUmtt8DdGb7T6d0UU9o6UWVq8krP5iYfUXC6u/WFj9xcLqLxadF8eZi10cZy52cZy53MVxhhfHmc/twSEBAAAAgKD/rz1hBAAAAAAAAAAAAAAAAAAAAGAUHN+OiDiImkUAAAAASUVORK5CYII=",v="data:image/png;base64,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",R="/ran/assets/备忘录.f4491fa8.jpg",q="data:image/png;base64,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",P="/ran/assets/状态.10166acb.png",x="/ran/assets/策略.3d82c7be.png",V="data:image/png;base64,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",S="/ran/assets/访问者.4ef81e5c.png",L=JSON.parse('{"title":"23 种经典设计模式","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/designMode.md","lastUpdated":1694276611000}'),J={name:"src/article/designMode.md"},M=l(`

23 种经典设计模式

设计模式 Design Pattern 是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解并且保证代码可靠性。。

在《设计模式:可复用面向对象软件的基础》一书中所介绍的 23 种经典设计模式,不过设计模式并不仅仅只有这 23 种,随着软件开发行业的发展,越来越多的新模式不断诞生并得以应用。有经验的开发者在学习设计模式可以和过往的经验互相印证,更容易理解这些设计模式。

设计模式一般包含模式名称、问题、目的、解决方案、效果等组成要素。问题描述了应该在何时使用模式,它包含了设计中存在的问题以及问题存在的原因。解决方案描述了一个设计模式的组成成分,以及这些组成成分之间的相互关系,各自的职责和协作方式,通常解决方案通过 UML 类图和核心代码来进行描述。效果描述了模式的优缺点以及在使用模式时应权衡的问题。

为什么要学习设计模式:

  • 设计模式来源众多专家的经验和智慧,它们是从许多优秀的软件系统中总结出的成功的、能够实现可维护性复用的设计方案,使用这些方案将可以让我们避免做一些重复性的工作

  • 设计模式提供了一套通用的设计词汇和一种通用的形式来方便开发人员之间沟通和交流,使得设计方案更加通俗易懂

  • 大部分设计模式都兼顾了系统的可重用性和可扩展性,这使得我们可以更好地重用一些已有的设计方案、功能模块甚至一个完整的软件系统,避免我们经常做一些重复的设计、编写一些重复的代码

  • 合理使用设计模式并对设计模式的使用情况进行文档化,将有助于别人更快地理解系统

  • 学习设计模式将有助于初学者更加深入地理解面向对象思想

储备知识

  • 抽象类:一般抽象类都是作为基类,比如说「电脑」就可以作为一个抽象类,根据抽象类派生出「台式电脑」和「笔记本电脑」2 种具体类。一般不对抽象类进行实例化。

  • 组合优于继承:不能滥用继承来拓展功能,配合组合会更灵活。同样拿「电脑」抽象类来举例,如果使用继承,区分不同类型的「电脑」我们可以派生出「台式电脑」和「笔记本电脑」,如果再增加一个维度,根据品牌又能继续细分出「联想台式电脑」、「联想笔记本电脑」、「苹果台式电脑」和「苹果笔记本电脑」等等,如果再增加一个维度继续细分下去,显然继承是无法胜任的。这个时候可以使用继承加组合方式,组合的对象也可以进行抽象化设计:

    ts
    // 品牌
    +import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/继承.d41dee10.png",o="data:image/png;base64,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",e="/ran/assets/组合.df5fa5b1.png",t="data:image/png;base64,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",c="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAY0AAACLCAMAAACqVzVKAAAAkFBMVEX///8yMjL8/Pw7Ozvz8/NkZGQ4ODhCQkKvr69OTk5VVVXl5eVEREQ0NDTu7u7Nzc1AQED5+fnp6enOzs5ISEj19fVvb29WVlaVlZX+/v7b29vU1NSenp6NjY2EhITw8PDr6+vg4ODJycm3t7ezs7OlpaV2dnZsbGxoaGhSUlLDw8O/v79xcXE9PT16enpaWlpyuPDWAAADTUlEQVR42u3d2VLiUBgE4D4nCyBJSGKi7OAuru//dpMAgjUXjGMVFv3bX1mVO9Jt1wHlJhARERERERERERERERERERERERERERERkd/Hd6OOO6JO1PU4RI32/IU7uotD4dXok667PA9xROH5peviADXai9w5jmzgIhyiRjsdF+LIQtfBAWq05xz+RnkPG42Ys9trxJzdXiPm7PYaMWe314g5u71GzNntNWLObq8Rc3Z7jZiz22vEnN1eI+bs9hoxZ7fXiDm7vUbM2e01Ys5urxFzdnuNmLPba8Sc3V4j5uz2GjFnt9eIObu9RszZ7TVizm6v0f+8buhPK/v377as+ddw/dPK/v27PUzxYewB9EM0Jh6Ea+R5XsG7IAgc4xq9Xi+teg00irzEvJy364yiNz9tSwWN017Dl+s1MjSC9sc7AJRruM/XmxdMev6qUwKo34doOH/yZ+N51a5xlYcG1jjbcGi8XyO6BYZRASCrSdZ4ma7PxsVwv0aSJJxrfLo+x7iLRoB/eMymSQW8MqzRj7P1GpOgvVZVDJ9+/Wz8qK+fjdEwW8WDpI9GcR8BKRAzrDG7336KR7Pt2ahz2jU+rvPH6TwOu5WrqipdLnZrvL4mJ73GIphs13gKss0aZUr/TnW2GBcx4OMRkNegORuzh91fuGfDzRrX95yf4ue9jdy5Jda//fGqvfp2jcUNwxqD8W6NSQaX5xVmt5xrbNTD5M5hs8Z8BhQBgCK9fGZYoxH6vltibQ7galXwrlEOk1mG7Rq3Sekx6LXHJr6meKdqvDn3OMKHfu8J3pcp4RrZ7UMyLGs/yddrjJPJOA06N2hcPQVu+794eNpr1MsMe493wHXq7vnWKIOXmwKL1AV3aIxRA/An8s3bN1+3QMszfmtYGPlG/ZTvYaMRc3Z7jZiz22vEnN1eI+bs9hoxZ7fXiDm7vUbM2e01Ys5urxFzdnuNmLPba8Sc3V4j5uz2GjFnt9eIObu9RszZ7TVizm6vEXN2e42Ys9trxJzdXiPm7PYaMWe314g5u71GzM9HsNeI+dkh9hp13eUgxBGFg388V0eNfviZU6MDAdTIyPPYfk0jEREREREREREREREREREREREREREREREREREROYo/dWMhiL/l5rAAAAAASUVORK5CYII=",r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZEAAACDCAMAAAB7ltZBAAAApVBMVEX///8yMjL8/PxBQUE7Ozuvr69kZGTl5eUzMzP09PTNzc3z8/Pu7u5WVlZSUlLY2Nhubm5HR0f+/v7s7OzOzs7KyspwcHBEREQ3Nzf29vbo6OihoaGOjo52dnZMTEw+Pj7Dw8NmZmb4+Pjw8PDg4OC8vLybm5uWlpaCgoJ/f396enpycnJpaWlfX1/c3Ny3t7eTk5OGhoZbW1uzs7Opqamnp6fS0tIlKBnqAAADP0lEQVR42u3dWVMaURQE4D73zsAMDLvIviPKEuMS8/9/WgBRgw9EqCLMOfZXVlm+cLvtYn8YEBERERERERERERERERERERERERERERERERHRV7kw4+WMfCZ0OISN9rmynN31oQJs9EkohasYZxRfFSTEIWy0JyNXOLOcZHAIG+3xEuPM8uJxCBvtEcFnKs+w00h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7/q16y1Aj7fk3Ss1iyU4j7fk3SkVp/qpaaXTMbedd+vJvxXci18k3XESy6cu/83MglfoJp+UfAdR68WycmkanLOK9r8BJEARy8fxvsj8kunVHnxYuAbT71e5I3SKuvV0kwVqw+XECID2LwD1E8iN77GlPgfeoVTC5GSbKFrkpbhaZ+nxaFwHqFRncHHfa8KkKzEfRqvc4yypb5LqzWQTl249FGo1GqhZBUha5ax1z2qrYaCxctelS9Mz4xdtuN2vbRX4H699RpdKEi464j3zA2ln/Kh7z36ohAlr3fva46nd0LdLt7Z7ZR93dfaQ1MLAINos89QfLzvB+rGqRSVDaLTIMktdF2pGBR61rL74AzEN0HnQ9anXL769+i7evi9R7Bp7ZgQhr4eK5X9O1SK70vkgpgXhfQfc5XYuc9uoXEXJAEvSn7YWqRdZil5Uatu4ATIvjVC1y4jtEF80L7j7jl66+1LbIQmRUxZtsfwjn2tHF8//1KUruhNNyzdmk5zutUab8om2RuJbgw6oD1KOod/H8W/H85E8ap+s1J4B76cbaFtk3xoa7fP7v/Wl8Ws/gN1apO4Pf6qbwDDuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtF8bwl4j7ddPsdcolEIujzPK5/51jSE2+v/X4aoeCMBGxq5V9y0aEREREREREREREREREREREREREan0Byk3I1baApDQAAAAAElFTkSuQmCC",y="data:image/png;base64,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",F="data:image/png;base64,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",D="/ran/assets/抽象工厂.786dc879.png",A="/ran/assets/单例.c53b9bde.jpg",B="/ran/assets/建造者.8aaf3334.jpeg",i="/ran/assets/原型.38aa29a0.jpg",E="/ran/assets/装饰.54bb2dbb.jpg",d="/ran/assets/外观.77eeb1fd.png",C="data:image/png;base64,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",u="/ran/assets/享元.6ee46b37.png",h="/ran/assets/桥接.de284493.png",f="/ran/assets/适配器.1e901e8e.png",g="data:image/png;base64,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",m="data:image/png;base64,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",k="/ran/assets/解释器.07d142dd.jpg",b="data:image/png;base64,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",v="data:image/png;base64,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",R="/ran/assets/备忘录.f4491fa8.jpg",q="data:image/png;base64,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",P="/ran/assets/状态.10166acb.png",x="/ran/assets/策略.3d82c7be.png",V="data:image/png;base64,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",S="/ran/assets/访问者.4ef81e5c.png",L=JSON.parse('{"title":"23 种经典设计模式","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/designMode.md","lastUpdated":1694419899000}'),J={name:"src/article/designMode.md"},M=l(`

    23 种经典设计模式

    设计模式 Design Pattern 是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解并且保证代码可靠性。。

    在《设计模式:可复用面向对象软件的基础》一书中所介绍的 23 种经典设计模式,不过设计模式并不仅仅只有这 23 种,随着软件开发行业的发展,越来越多的新模式不断诞生并得以应用。有经验的开发者在学习设计模式可以和过往的经验互相印证,更容易理解这些设计模式。

    设计模式一般包含模式名称、问题、目的、解决方案、效果等组成要素。问题描述了应该在何时使用模式,它包含了设计中存在的问题以及问题存在的原因。解决方案描述了一个设计模式的组成成分,以及这些组成成分之间的相互关系,各自的职责和协作方式,通常解决方案通过 UML 类图和核心代码来进行描述。效果描述了模式的优缺点以及在使用模式时应权衡的问题。

    为什么要学习设计模式:

    • 设计模式来源众多专家的经验和智慧,它们是从许多优秀的软件系统中总结出的成功的、能够实现可维护性复用的设计方案,使用这些方案将可以让我们避免做一些重复性的工作

    • 设计模式提供了一套通用的设计词汇和一种通用的形式来方便开发人员之间沟通和交流,使得设计方案更加通俗易懂

    • 大部分设计模式都兼顾了系统的可重用性和可扩展性,这使得我们可以更好地重用一些已有的设计方案、功能模块甚至一个完整的软件系统,避免我们经常做一些重复的设计、编写一些重复的代码

    • 合理使用设计模式并对设计模式的使用情况进行文档化,将有助于别人更快地理解系统

    • 学习设计模式将有助于初学者更加深入地理解面向对象思想

    储备知识

    • 抽象类:一般抽象类都是作为基类,比如说「电脑」就可以作为一个抽象类,根据抽象类派生出「台式电脑」和「笔记本电脑」2 种具体类。一般不对抽象类进行实例化。

    • 组合优于继承:不能滥用继承来拓展功能,配合组合会更灵活。同样拿「电脑」抽象类来举例,如果使用继承,区分不同类型的「电脑」我们可以派生出「台式电脑」和「笔记本电脑」,如果再增加一个维度,根据品牌又能继续细分出「联想台式电脑」、「联想笔记本电脑」、「苹果台式电脑」和「苹果笔记本电脑」等等,如果再增加一个维度继续细分下去,显然继承是无法胜任的。这个时候可以使用继承加组合方式,组合的对象也可以进行抽象化设计:

      ts
      // 品牌
       interface Brand {
         // ...
       }
      diff --git a/assets/src_article_designMode.md.fdb686ab.lean.js b/assets/src_article_designMode.md.c8355f94.lean.js
      similarity index 99%
      rename from assets/src_article_designMode.md.fdb686ab.lean.js
      rename to assets/src_article_designMode.md.c8355f94.lean.js
      index 158609ba6..3089cf77d 100644
      --- a/assets/src_article_designMode.md.fdb686ab.lean.js
      +++ b/assets/src_article_designMode.md.c8355f94.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/继承.d41dee10.png",o="data:image/png;base64,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",e="/ran/assets/组合.df5fa5b1.png",t="data:image/png;base64,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",c="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAY0AAACLCAMAAACqVzVKAAAAkFBMVEX///8yMjL8/Pw7Ozvz8/NkZGQ4ODhCQkKvr69OTk5VVVXl5eVEREQ0NDTu7u7Nzc1AQED5+fnp6enOzs5ISEj19fVvb29WVlaVlZX+/v7b29vU1NSenp6NjY2EhITw8PDr6+vg4ODJycm3t7ezs7OlpaV2dnZsbGxoaGhSUlLDw8O/v79xcXE9PT16enpaWlpyuPDWAAADTUlEQVR42u3d2VLiUBgE4D4nCyBJSGKi7OAuru//dpMAgjUXjGMVFv3bX1mVO9Jt1wHlJhARERERERERERERERERERERERERERERkd/Hd6OOO6JO1PU4RI32/IU7uotD4dXok667PA9xROH5peviADXai9w5jmzgIhyiRjsdF+LIQtfBAWq05xz+RnkPG42Ys9trxJzdXiPm7PYaMWe314g5u71GzNntNWLObq8Rc3Z7jZiz22vEnN1eI+bs9hoxZ7fXiDm7vUbM2e01Ys5urxFzdnuNmLPba8Sc3V4j5uz2GjFnt9eIObu9RszZ7TVizm6v0f+8buhPK/v377as+ddw/dPK/v27PUzxYewB9EM0Jh6Ea+R5XsG7IAgc4xq9Xi+teg00irzEvJy364yiNz9tSwWN017Dl+s1MjSC9sc7AJRruM/XmxdMev6qUwKo34doOH/yZ+N51a5xlYcG1jjbcGi8XyO6BYZRASCrSdZ4ma7PxsVwv0aSJJxrfLo+x7iLRoB/eMymSQW8MqzRj7P1GpOgvVZVDJ9+/Wz8qK+fjdEwW8WDpI9GcR8BKRAzrDG7336KR7Pt2ahz2jU+rvPH6TwOu5WrqipdLnZrvL4mJ73GIphs13gKss0aZUr/TnW2GBcx4OMRkNegORuzh91fuGfDzRrX95yf4ue9jdy5Jda//fGqvfp2jcUNwxqD8W6NSQaX5xVmt5xrbNTD5M5hs8Z8BhQBgCK9fGZYoxH6vltibQ7galXwrlEOk1mG7Rq3Sekx6LXHJr6meKdqvDn3OMKHfu8J3pcp4RrZ7UMyLGs/yddrjJPJOA06N2hcPQVu+794eNpr1MsMe493wHXq7vnWKIOXmwKL1AV3aIxRA/An8s3bN1+3QMszfmtYGPlG/ZTvYaMRc3Z7jZiz22vEnN1eI+bs9hoxZ7fXiDm7vUbM2e01Ys5urxFzdnuNmLPba8Sc3V4j5uz2GjFnt9eIObu9RszZ7TVizm6vEXN2e42Ys9trxJzdXiPm7PYaMWe314g5u71GzM9HsNeI+dkh9hp13eUgxBGFg388V0eNfviZU6MDAdTIyPPYfk0jEREREREREREREREREREREREREREREREREREROYo/dWMhiL/l5rAAAAAASUVORK5CYII=",r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZEAAACDCAMAAAB7ltZBAAAApVBMVEX///8yMjL8/PxBQUE7Ozuvr69kZGTl5eUzMzP09PTNzc3z8/Pu7u5WVlZSUlLY2Nhubm5HR0f+/v7s7OzOzs7KyspwcHBEREQ3Nzf29vbo6OihoaGOjo52dnZMTEw+Pj7Dw8NmZmb4+Pjw8PDg4OC8vLybm5uWlpaCgoJ/f396enpycnJpaWlfX1/c3Ny3t7eTk5OGhoZbW1uzs7Opqamnp6fS0tIlKBnqAAADP0lEQVR42u3dWVMaURQE4D73zsAMDLvIviPKEuMS8/9/WgBRgw9EqCLMOfZXVlm+cLvtYn8YEBERERERERERERERERERERERERERERERERHRV7kw4+WMfCZ0OISN9rmynN31oQJs9EkohasYZxRfFSTEIWy0JyNXOLOcZHAIG+3xEuPM8uJxCBvtEcFnKs+w00h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7/q16y1Aj7fk3Ss1iyU4j7fk3SkVp/qpaaXTMbedd+vJvxXci18k3XESy6cu/83MglfoJp+UfAdR68WycmkanLOK9r8BJEARy8fxvsj8kunVHnxYuAbT71e5I3SKuvV0kwVqw+XECID2LwD1E8iN77GlPgfeoVTC5GSbKFrkpbhaZ+nxaFwHqFRncHHfa8KkKzEfRqvc4yypb5LqzWQTl249FGo1GqhZBUha5ax1z2qrYaCxctelS9Mz4xdtuN2vbRX4H699RpdKEi464j3zA2ln/Kh7z36ohAlr3fva46nd0LdLt7Z7ZR93dfaQ1MLAINos89QfLzvB+rGqRSVDaLTIMktdF2pGBR61rL74AzEN0HnQ9anXL769+i7evi9R7Bp7ZgQhr4eK5X9O1SK70vkgpgXhfQfc5XYuc9uoXEXJAEvSn7YWqRdZil5Uatu4ATIvjVC1y4jtEF80L7j7jl66+1LbIQmRUxZtsfwjn2tHF8//1KUruhNNyzdmk5zutUab8om2RuJbgw6oD1KOod/H8W/H85E8ap+s1J4B76cbaFtk3xoa7fP7v/Wl8Ws/gN1apO4Pf6qbwDDuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtF8bwl4j7ddPsdcolEIujzPK5/51jSE2+v/X4aoeCMBGxq5V9y0aEREREREREREREREREREREREREan0Byk3I1baApDQAAAAAElFTkSuQmCC",y="data:image/png;base64,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",F="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfMAAAERCAMAAABYXb7wAAAAw1BMVEX///8yMjI4ODj7+/v9/f1BQUHy8vJEREQ7OztVVVX19fVISEhCQkJwcHCvr69YWFjNzc1cXFxhYWFOTk75+fn09PTj4+OFhYU+Pj5RUVHf39/s7OzY2Ni5ubllZWXr6+v39/fo6OjJycnu7u7l5eW9vb20tLRLS0t5eXlkZGSrq6uTk5OCgoLPz8+Li4udnZ2goKBpaWnExMSHh4epqalZWVl/f3/29vbw8PDa2tqkpKSGhoaWlpbV1dV1dXVtbW3AwMC629LZAAAKu0lEQVR42uzBgQAAAACAoP2pF6kCAAAAAAAAAAAAAAAAAACYXXNRThMIo/A5sIhctCpoFDVeWsV4wUtT05gmzfs/VcHaYDtNIyUqMH4jOI7D7Jz9hp2f/Tknonhj8miYN0WBV7mEOQuiwCNTEHiFS5jT0BP4jSK1UhVHo1rSWMTxyHCY9+NKfejLCLlhCUelxGsclayGeUfnJJX1ysYOk1UclRxNHJtMhnlP56pGsj4adBFA4ni8MUIKhyKRPq44hjP/QjL/1K5mbJoyFebflBmFMXxqi+1FhWGmpun0YUQP54EX52dxLvcf1CucB/I/13Y9Y8vhKcPYq7VCMh3OzUsNF3uE7mBUJ6mpKXFOKtOVncmy5zRhqu2nPMkvcwfjdDgP9mSyWuqeIsywQJ/yogafMQ/iGj7ni9oTyO7jTVKdEz7JiXpxHnkEPerafnEeksKh/qjhzFQ4j7W2FxDwhJ+0K1384rkHSACGtYQ7l786s8FYxA9jr6YKmQrnb9dwfOHD/q8gnYQABVtWkvrBp4+AZ+sREvS15iTK+UTaAy1DydcNrVKYdhAvTLgnkwrnYV/tlWtlnxqDswDAe32HLWRJfpkmsdnOSKuiY8tsDAkrz07o2p4jgPZ3AXy2EfBOYUQvFc4P6at9InYwXN8aLl3VsixalpKr0NI0zVVdzQJQafiwETBKrvPFZwDU44VJSJlBxuirHe4ckKACUIJP3wVQUwXgIkBsRpI3sBNXwymGYSg751eLrfMoYVLqvBy9xxI6F685h6tpmlr3TxJ8VmVPlu49y7tPmHMGx875sr11HiFMWp0zjnObHfxC3PM6nKY2ZhWlBnzd+IfVWAFz4O7WuhGJdf5B8qEUcHdomLQ6j9xXC533aGPHXb1BR9U0jZqm2AOvsex/d525OwfwKICPJnzEY3Lvc6AFUJdbh4dJ7X0eua8WOu8beKG5txyK9ca5tRZrpdGDj+FTZz34qiTMuaqqL86/fbFBveYODw6T0rqdjNxXC517I4TsT9NgbU5bD2Xt2cOO5UhrJm8fjnt1+9zqANRRM24PDJPW53Myal8tdN7Jr/7uHJOxMzcmuorCLQK606XYuAORNOcBNjCTgInVs+UOu4BjDmOHsVfr5O7DkZH2XrlHabpESLOZR/BIa1qW0i0WzCtHLlaQK4/Q7U+MaRcolS1vmEuc8xHz/AzMmhiSBfi0mrHChO9MpMJ5tH9zHYRYeQ8qtiiy1+46hlp5BOQa9OXEwZbWt4dk1e0B1U6vipC4YarJ76uRiWhF/YUUDvVG//z64vwHO3eQgjAQRUEwgrjMEQLe/5IqiLgShCQk09U3+NRuGF7O/MJ8RPNffyaYj2r+/WeCecb882eCecn8/SbDvGX+7HpnXjOfJubMmTM/oPlQcxx7HDOA+VCzO3scM4D5a17rNm3WbfV5rSMfcxLzoWb09jhmAPPpOi9bzmUu88rkRz7mLOb6K+ZiHo95L+a9mPdi3ot5L+a9mPdi3ot5L+a9mPdi3ot5L+a9mPdi3ot5L+a9mPdi3ot5L+a9mPdi3ot5L+a9mPdi3ot5L+a9mPdi3ot5L+a9mPdi3ot5L+a9mPdi3ot5L+a9mPdi3uvB3rk2pQ0FYfjdJFyaiBcMiAqkgFIp0EqxVTt2/P//qoRmQggNbbhusvvMBMHzYXn3GTK5zTnqXB7qXB7qXB7qXB5ZcW6dDva5hMlg1+uxcA6TEeeWrrskbt0lf0myGvZGbefrq3EOkxHnA11HUdw6iie6Xqq49VJJ10UWty4yqXN1DmROBJsw6lydq/MVMlhKnTMRwSaMOlfn6nwvdD8yCqPOD1GhaVy/8gmjzg/i/JqMJ4tLGHV+kAr2iKjSYxImF85PkYD5cjO+/2wd3znQapDTTSi1eTIhzltlHzLKPhdnPjR/vR8aEdB0CuWG86FaGXkAhZwh+unqYM5RrxK9mQmlNk0mxPkf2vdY0MAyRQLQereAqYs55ow6+a8WAHq1A9zDOYc5JKreJZVKn0zcvv2kgz8Y1WqVZpsT78zjFADZCLkjBFD9OOfn3RI1Wgml0ieT5NykQgDFO1NwHKcQdObqkZ1z9CpEo+d4qfTJcuN8HcvOo28qABrBX5C/BZ2ZtJKcW39zHq+1v0/Xyc5TJdu4mWyctzdy/uvCh2ZbI96ZM2MGGT7Py85d8vg7T5EstfM2E+frWXZeCqDIkU4p3hmgCZBtNld+5x1yj7Vvf1+3b0+fLAkiJlcodud88eZsDs23U8DvWdiZt+8uyK5/6seddx3wPIZLnUyk83G4B5z/kyJHt18vPYBs1J2nmPMvDwhhda6WPplE54s94HcEuMDYAIaXHdf06CNwc9Jfcu6Vvx3Def0i4ZrMVsnEOI+e0aBo33xChAcq0xQY36JPVMGM5i1FOB9NjnXt9Tyh1BbJxDhfenPfKPxEhJrXqWEdRe/wzu0fyfdYNk8m5xgOZviGybfb7l5qqmRSnfuw+nYZe2ZCnct7Nkqdy3sGUp2rc3W+QgZLqXMmFbiHUecLMlhKnTOpwD2MOl+QwVK5cH6ic4ukC5MD5wOdQyhdmBw496fXKmJvFDeYKyx3Ybg5t3ROwHRhcuAc1ml7n9NlttPP/Zm7MOycK3Ey4Ued80ady0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody0Ody4Odc+t0sM+plgbpp1rKXRhuzplOqZarMNyc+1Mn1rA3ahtMnZi7MNycM50iNVdhuDlnOhVyrsJwc850ynOupXIxfzvTNnEtpc6ZVOAeRp0vyGApdc6kAvcw6nxBBkupcyYVuIdR53N0XWR1ruufq/P/dn5NxpPFPIw63y32iKjS4x0mJ87Nl5vx/Wfr+M6BVoOc7tal4smEOB8aEVAOeYmNNJ1CueF8qFZGHkAhZ4h+ujqYc9SrRG9mQqlNkwlxHlIkAHSLOSb1YiOtdwuYusHwjDr5rxYAerUD3MM5hzkkqt4llUqfTOK+/R+deZwCIBshd4QAqh/n/LxbokYroVT6ZKKcFxzHKax2JjZy9cjOOXoVotFzvFT6ZBlyvg1YQP622pnYyKSV5Nz6m/N4rf19uk5obtpku281dk77sM7PjBlk+DwvO3fJy7TzaLJdOm+DFamd+zQBss3myu+8Q+6x9u3va/bt6ZNxuHkQYa/OS6VSQmciI3j77oLs+qd+3HnXAdNjuLTJBDlPPLqNjny99ACyUXeeYs6/PCCE17la6mRinPu4wNgAQOUA6i2PDC87runRR+DmpL/k3Ct/O0ab6hcJ12S2SibJ+QOVaQpg8oI51qS2PDK+RZ+oghnNW4pwPpoc69rreUKpLZJJcl7zOjVEiY8kU/SOcI/lR/I9llTJONwwWguP6zkMKmTiXio3Mt6mTDwzwY2stykLz0ZxI1dtylWYkAyGUOfcyFWbchUmJIMh1Dk3ctWmXIX53c4d2wAMAkEQdGARugT6L9MZAQESwUtwmung/vMdLhzh56eJOlPUmFl8jsOYWX52x5gaI6/VnjJtmdcyZk92Rs+YSu/XK3OZfZXLNAYAAAAAAAAAAAAArvMD6brkIaU8kEwAAAAASUVORK5CYII=",D="/ran/assets/抽象工厂.786dc879.png",A="/ran/assets/单例.c53b9bde.jpg",B="/ran/assets/建造者.8aaf3334.jpeg",i="/ran/assets/原型.38aa29a0.jpg",E="/ran/assets/装饰.54bb2dbb.jpg",d="/ran/assets/外观.77eeb1fd.png",C="data:image/png;base64,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",u="/ran/assets/享元.6ee46b37.png",h="/ran/assets/桥接.de284493.png",f="/ran/assets/适配器.1e901e8e.png",g="data:image/png;base64,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",m="data:image/png;base64,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",k="/ran/assets/解释器.07d142dd.jpg",b="data:image/png;base64,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",v="data:image/png;base64,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",R="/ran/assets/备忘录.f4491fa8.jpg",q="data:image/png;base64,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",P="/ran/assets/状态.10166acb.png",x="/ran/assets/策略.3d82c7be.png",V="data:image/png;base64,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",S="/ran/assets/访问者.4ef81e5c.png",L=JSON.parse('{"title":"23 种经典设计模式","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/designMode.md","lastUpdated":1694276611000}'),J={name:"src/article/designMode.md"},M=l("",384),j=[M];function N(Q,O,I,Z,U,w){return n(),a("div",null,j)}const K=s(J,[["render",N]]);export{L as __pageData,K as default};
      +import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/继承.d41dee10.png",o="data:image/png;base64,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",e="/ran/assets/组合.df5fa5b1.png",t="data:image/png;base64,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",c="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAY0AAACLCAMAAACqVzVKAAAAkFBMVEX///8yMjL8/Pw7Ozvz8/NkZGQ4ODhCQkKvr69OTk5VVVXl5eVEREQ0NDTu7u7Nzc1AQED5+fnp6enOzs5ISEj19fVvb29WVlaVlZX+/v7b29vU1NSenp6NjY2EhITw8PDr6+vg4ODJycm3t7ezs7OlpaV2dnZsbGxoaGhSUlLDw8O/v79xcXE9PT16enpaWlpyuPDWAAADTUlEQVR42u3d2VLiUBgE4D4nCyBJSGKi7OAuru//dpMAgjUXjGMVFv3bX1mVO9Jt1wHlJhARERERERERERERERERERERERERERERkd/Hd6OOO6JO1PU4RI32/IU7uotD4dXok667PA9xROH5peviADXai9w5jmzgIhyiRjsdF+LIQtfBAWq05xz+RnkPG42Ys9trxJzdXiPm7PYaMWe314g5u71GzNntNWLObq8Rc3Z7jZiz22vEnN1eI+bs9hoxZ7fXiDm7vUbM2e01Ys5urxFzdnuNmLPba8Sc3V4j5uz2GjFnt9eIObu9RszZ7TVizm6v0f+8buhPK/v377as+ddw/dPK/v27PUzxYewB9EM0Jh6Ea+R5XsG7IAgc4xq9Xi+teg00irzEvJy364yiNz9tSwWN017Dl+s1MjSC9sc7AJRruM/XmxdMev6qUwKo34doOH/yZ+N51a5xlYcG1jjbcGi8XyO6BYZRASCrSdZ4ma7PxsVwv0aSJJxrfLo+x7iLRoB/eMymSQW8MqzRj7P1GpOgvVZVDJ9+/Wz8qK+fjdEwW8WDpI9GcR8BKRAzrDG7336KR7Pt2ahz2jU+rvPH6TwOu5WrqipdLnZrvL4mJ73GIphs13gKss0aZUr/TnW2GBcx4OMRkNegORuzh91fuGfDzRrX95yf4ue9jdy5Jda//fGqvfp2jcUNwxqD8W6NSQaX5xVmt5xrbNTD5M5hs8Z8BhQBgCK9fGZYoxH6vltibQ7galXwrlEOk1mG7Rq3Sekx6LXHJr6meKdqvDn3OMKHfu8J3pcp4RrZ7UMyLGs/yddrjJPJOA06N2hcPQVu+794eNpr1MsMe493wHXq7vnWKIOXmwKL1AV3aIxRA/An8s3bN1+3QMszfmtYGPlG/ZTvYaMRc3Z7jZiz22vEnN1eI+bs9hoxZ7fXiDm7vUbM2e01Ys5urxFzdnuNmLPba8Sc3V4j5uz2GjFnt9eIObu9RszZ7TVizm6vEXN2e42Ys9trxJzdXiPm7PYaMWe314g5u71GzM9HsNeI+dkh9hp13eUgxBGFg388V0eNfviZU6MDAdTIyPPYfk0jEREREREREREREREREREREREREREREREREREROYo/dWMhiL/l5rAAAAAASUVORK5CYII=",r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZEAAACDCAMAAAB7ltZBAAAApVBMVEX///8yMjL8/PxBQUE7Ozuvr69kZGTl5eUzMzP09PTNzc3z8/Pu7u5WVlZSUlLY2Nhubm5HR0f+/v7s7OzOzs7KyspwcHBEREQ3Nzf29vbo6OihoaGOjo52dnZMTEw+Pj7Dw8NmZmb4+Pjw8PDg4OC8vLybm5uWlpaCgoJ/f396enpycnJpaWlfX1/c3Ny3t7eTk5OGhoZbW1uzs7Opqamnp6fS0tIlKBnqAAADP0lEQVR42u3dWVMaURQE4D73zsAMDLvIviPKEuMS8/9/WgBRgw9EqCLMOfZXVlm+cLvtYn8YEBERERERERERERERERERERERERERERERERHRV7kw4+WMfCZ0OISN9rmynN31oQJs9EkohasYZxRfFSTEIWy0JyNXOLOcZHAIG+3xEuPM8uJxCBvtEcFnKs+w00h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7/q16y1Aj7fk3Ss1iyU4j7fk3SkVp/qpaaXTMbedd+vJvxXci18k3XESy6cu/83MglfoJp+UfAdR68WycmkanLOK9r8BJEARy8fxvsj8kunVHnxYuAbT71e5I3SKuvV0kwVqw+XECID2LwD1E8iN77GlPgfeoVTC5GSbKFrkpbhaZ+nxaFwHqFRncHHfa8KkKzEfRqvc4yypb5LqzWQTl249FGo1GqhZBUha5ax1z2qrYaCxctelS9Mz4xdtuN2vbRX4H699RpdKEi464j3zA2ln/Kh7z36ohAlr3fva46nd0LdLt7Z7ZR93dfaQ1MLAINos89QfLzvB+rGqRSVDaLTIMktdF2pGBR61rL74AzEN0HnQ9anXL769+i7evi9R7Bp7ZgQhr4eK5X9O1SK70vkgpgXhfQfc5XYuc9uoXEXJAEvSn7YWqRdZil5Uatu4ATIvjVC1y4jtEF80L7j7jl66+1LbIQmRUxZtsfwjn2tHF8//1KUruhNNyzdmk5zutUab8om2RuJbgw6oD1KOod/H8W/H85E8ap+s1J4B76cbaFtk3xoa7fP7v/Wl8Ws/gN1apO4Pf6qbwDDuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtOe310h7fnuNtF8bwl4j7ddPsdcolEIujzPK5/51jSE2+v/X4aoeCMBGxq5V9y0aEREREREREREREREREREREREREan0Byk3I1baApDQAAAAAElFTkSuQmCC",y="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAcoAAAGBCAMAAADR3QFBAAAAt1BMVEX///8yMjKrq6uFhYX8/Pw4ODiYmJj19fVZWVlISEhEREQ7Ozv5+flRUVFOTk5BQUFCQkLz8/NlZWWvr6/y8vI+Pj7r6+vNzc3Y2Nhvb2/l5eXh4eFhYWGKioo0NDTOzs5VVVVeXl7+/v7Jycm7u7uenp5KSkro6Ojd3d2BgYGTk5Pv7+/FxcV4eHi0tLRWVlbT09OoqKhqamp9fX2/v79ycnLt7e24uLiioqKOjo7Q0NCHh4fa2toZwSUUAAAMWUlEQVR42uzd627aMACG4c/gNE0akgCDciYUCAdx6KBr2br7v645h3Vs1YQiLay2vkeAhBKElFcxTvhhEBERERERERERERERERERERERERERERERERERERERERERERERkZlksxGKEoWNpgRdgeyK0nXZ8hqaYj+uo0T18V40QeVriDFKdi8aoPKFoo6S1UUIKp8Q+JOW30FMaQ6mNAZTGoMpjcGUxmBKYzClMf5Lyh4ooXvK/nzCszSjdcrlzV4IDrg5bVM+dNY1lbF1ZMqcninl41dfdQxWG4/ToJyWKe+HjuoYVqcyfX+B1QF91JTjQilFFfRRUxYaYKuiAvq4Kc+nPUyZ0zZldjFyKwRT5rROmd0iYMqM7imVHlOmDEgJpkwxJTGl2ZjSGExpDCFwkfzUH88qEkAXiS/IzAYefnpaABaAXY8pCyg35do6g44T3LWcaPBl1UYaSwmQ2ljurTLNUvqPaqt9jJZMeW2XD/OnZNNLVwKvHhJSWvIt5cMp6gPoTGykxhWVcjP0OMAWcNWU89dkpyxXLRax6/v+yPeD+kD4URTFbhz5AAY1RdQSW6YsoOSUgeM4QZ6yOs9SZiy4yfbkMY0B9FwJxEjI09YazjxOewooP6VInnnKw8tfUiKOoshtqZcRlM1kKK3l0B9+Z8oCrplybynCStjy+6jxK+UM3wZBX+32WT392gaYA3bFb0imvL7LKZUOIGypXu1WbdR3k9MwigLv6WvtMD3E/XmsCuJRAs8hFPnIs/JqLqd0Xfct5c2tp1L24h3QPhtg5fG0/OzPV0FtAcVRWqLlKBOmLKDklKPzGazfTn8r+85n4Czlw+wYrjrVSfT0FbnDMXrm3Z5ru3yYPeCbBaz9hSfbQr1bhrvzlFhXlnNnbbvoVrIPrA7yFM8emLKAq6Tcju7Eq8r5jJ0YdaF02s/Pd0iuK0PfD+xmN6wuZXOA+mQLb7p2VjYwnvjDXZ0pCyg/Zb29eJfEvxvCRSqQw5nXd9xJB5B92If1EqnOTZUz2II0/mdELpgypXlKOa26VaZM6ZzS26wCIQRTZrRNac+2LdUxcpkyp2fK+suXO9Xxdr5EhSlzOqbcdYUyOfWgVMTvGkypX8p5/31KhSk1SgnYL9t0gL15N8AypWYpFfvpmE57QqbMaZvy7WKEKXM6p8xvETBlRvOUilwwZUr/lABTZpiSmNJoTGkMpjQGUxqDKY3BlMZgSmMwpTGY0hhMaYz/v+ghU8KUpUiZ8h9piv19uQsE3+9Fkykv0mTZ7gemvMyAxfSZ0hhMaQymNAZTGoMpjcGUxmBKYzClMZjSGExpDKY0BlMagymNwZTGYEpjMKUxmNIYTGkMpjQGUxrjB3t3upM6FIVh+Fu4aSm0ZS5DQZRZJhXn4f6v6xRFc5QoakTo4nuTGsj+geGxA5vGTUo1kVJNpFQTKdVESjWRUk2kVBMp1URKNZFSTaRUEynVREo1kVJNpFQTKdVESjWRUk2kVBMp1URKNZFSTaRUEynVREo1kVJNpFQTKdVESjWRUk2kVBMp1URK/ht8toXFKQwp/6CinLY2u2RMi0vGfBwXcmJcXk1zXPRQTaRUEynVREo1kVJNpFQTKdVESjWRUk2kVBMp1URKNZFSTaRUEynVREo1kVJNpFQTKdVESjWRMs51bFLqqJr0HkmpoqonyfM2KTVkn4hcjUmpopuyOJ1fpDSlsNVNGFJuofqxiGU+fZtHyf9C5rXxu5Gqk82UnaPG1UlAym1kRiKN+pf2ypIAkKWTkfG7kZuaAR5cHmC3Vyct5e4vUPYeAIhNyi02romc2CL4qKzjONlVyncjBz1SbrTOoYggSl5afdYWEU8EH/VEuEr5bmR+s57y00j5eZb8FeVpMkqSi+yfURZI+TmlhTVdrxxgf0QJVAGxTfXn87yk/B7l9y97JJ1Of0D53wislAux6/0ZKZdtmvL7H0YOP7iCfTvS8wNAbITOOSmj/ppy/RTBMhe4TwKQzDIZvx0Z+QPXBOICw9yMlMDGKVcn7ipfepunhxl5ADAv4Skzz78dub/GTA5riKoGpNxAFavyK9Pp+WCQ/+IIL3u+ntIvuUip5qtnUqq5IYSUa8+VcblNi5Rrr2BJqSNSqomUaiKlmkipJlKqiZRqIqWaSKkmzvbsX6RUEynVRMpdj+fK/YuUccgmZVxXD+ze46lBHWUMAzvpkjKeqwcm/Efcni0eFFBuNyqdI7xk7rLlUZuU8Vg90H6Yj2E66VvAzOvlsxM0T/BSzxsMc0VSxmP1wJrk0n3vuOA14XneoedNck4/m3n268+AUYGU8Vg9cGzjogfAHgJhIWnZtxLAusOiQELgsryLv/ZOUm73z9v3/cOc72eizRs1wvLlcbMwwbSIRVUpAS0xO3gwIeVqbathu7PWURXtrml2UcJ50+TqWHQmeeBezAen+MpmT/GVUymS8uuvERamwbnfzFf9u8DzxfO88SB3frwclDpwmdvehXeblF9+jdBJTJ1m/X4+yzezYT9E9cjgQi6XXOUuYNV29OMwKd/m4qyeSDUm1z3XrU+Pi14L5kq6eK6ZCobpCWLSnlPiJtW/qwaW03MBt5lJn5uLxmUmsYS+yDgJxKV9pwzCQaLmWNdA/qLfvB7eFmo2JuUi4te+U9453sHExaJLG1GVNoCBi/i175SBDS3tOyVW77iLa6QkJSl3LVKSkpS7FilJScpdi5Qr98HGNVKqiZRqIqWaSMlzpU5KXsGScgciJSn/4sZGgyhDyvhTTu8AdI7xVOfKBjArkjKGlBPxUqlRI52KfgLuVcOg5IeIktdSb54dkHIrrb9HddiyUJwOLwwAz0knHScbbQBMVChmEQB5tJe5pPxWf0U5nfVKhZI1aE/vAWQQJcsHi+qCZRLyALvblMZczTupp3wg40fJYiNl7CjRtWd4LvPZXtmWOtYkr32+DB5nezZEWQaS0S6ZXEPpSvBblPGert1tSgfR9kzpRMlie085EHf9a+zUjMW/9u6GJ20oCsDwuVtraUXRyUdRhkNQRKebZqib+/+/a7RULHihNWFy7+V9EjKWsGw571oLKCezXSn9Xq83PSpbL0dlazFlPxRSmp9ydlRGKRUlnuZT/r4hpQUpu5WJJOWUkkwuZXP3OyktSJlUCqrDaD6lymmN7oWUFqRM3EUXL//EsbxVb5LS+JRlkZKUpCSlmUjpDFI6g5TOIKUzSOlMdVKSkpSmISUpSWkaUpKSlKYhJSlJaRpSOoOUb9j6saKkfLtezcbP9SVlwXq106+eyTv+SFl6vVoUqarBO/5IWX69WvxTVY3d8UfKsuvVUpOUxu74I2Xp9WpZSmN3/JmXckMDKV6vlqU09T+hgSk3cZoqXq9GygLGbQ9ctl6NlMau7T5753o1Ulq4TH/lejWVIqUdlq1XM/7am5Rl16uR0jrNwNJnxKQUV17cICUpQUrbGPZtQKQkJUjpDlI6g5TOIKUzSOkMUjqDlM4g5ZboB6R0Q+zv/SWlE+I95d+dkdIFwUip8TUprVA0u8eGCvvvH/ORLOHVT04HnzxSrl3x7I57Su14Kx/6uJvo+ukvvUqiW0n8uvJzJA5ru43wW2c8apJy/Ypn510p1TkufuiXgbxqyLy6SpK3PZHnKifYdSs/u36kGoPChx4MZcrvdDrdyS1cTHn+nPyFASkzG0gp122lRsHyh3qqllGLKWthGNaylJ/PSfkfqcTszqrf7a1Kmb8zzk6w7fSPJrcs5f1jiZSfVWmknNNbd8p4dtnTWEz5w59QfiJYR0o/FrzTQ+EJNsqo3GVPNJ8yEYuowIu3/ROHNie77Cl3VFZS3fR2JJJEnqXcqVRFBccXt6TciOzJSNmUp68pZaKbv4Ldb6ZfK0/CO1JuQPYSQcmU+RNsRTJVkT++yNX+sOo1VVXk8uCWlB8re+GuJamyT0akHlxeSM5Nd1c9T3I+yK3qtmUibpLyQ+lfTi8+KgeN2pPkHDaHhwa9vb2VSr/J5c3uWPBzKVvJ7Lee4cw3hMDoMZNSx8oxk1LHyjGTUsfKMZNSx8oxk1LHyjGTUsfKMZNSx8oxk1LHyjGTUsfKMZNSx8oxk1LHyjGTUsfKMZNSx8oxk1LHyjGTUsfKMZNSx8oxk1LHyjGTUsfKMZNSx8oxk1LHyjGTcjU3dvxBHNnxBxE3dvxhyoUdf0g5seMPAAAAAAAAAAAAAAAAAAAAa/YPuWzT64OsNxgAAAAASUVORK5CYII=",F="data:image/png;base64,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",D="/ran/assets/抽象工厂.786dc879.png",A="/ran/assets/单例.c53b9bde.jpg",B="/ran/assets/建造者.8aaf3334.jpeg",i="/ran/assets/原型.38aa29a0.jpg",E="/ran/assets/装饰.54bb2dbb.jpg",d="/ran/assets/外观.77eeb1fd.png",C="data:image/png;base64,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",u="/ran/assets/享元.6ee46b37.png",h="/ran/assets/桥接.de284493.png",f="/ran/assets/适配器.1e901e8e.png",g="data:image/png;base64,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",m="data:image/png;base64,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",k="/ran/assets/解释器.07d142dd.jpg",b="data:image/png;base64,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",v="data:image/png;base64,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",R="/ran/assets/备忘录.f4491fa8.jpg",q="data:image/png;base64,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",P="/ran/assets/状态.10166acb.png",x="/ran/assets/策略.3d82c7be.png",V="data:image/png;base64,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",S="/ran/assets/访问者.4ef81e5c.png",L=JSON.parse('{"title":"23 种经典设计模式","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/designMode.md","lastUpdated":1694419899000}'),J={name:"src/article/designMode.md"},M=l("",384),j=[M];function N(Q,O,I,Z,U,w){return n(),a("div",null,j)}const K=s(J,[["render",N]]);export{L as __pageData,K as default};
      diff --git a/assets/src_article_functionalProgramming.md.e9f945b3.js b/assets/src_article_functionalProgramming.md.0ef4df92.js
      similarity index 99%
      rename from assets/src_article_functionalProgramming.md.e9f945b3.js
      rename to assets/src_article_functionalProgramming.md.0ef4df92.js
      index d6b57947b..7bd8fb596 100644
      --- a/assets/src_article_functionalProgramming.md.e9f945b3.js
      +++ b/assets/src_article_functionalProgramming.md.0ef4df92.js
      @@ -1,4 +1,4 @@
      -import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"函数式编程","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/functionalProgramming.md","lastUpdated":1694276611000}'),p={name:"src/article/functionalProgramming.md"},o=l(`

      函数式编程

      • 概述: 函数式编程(Functional Programming)FP就是编程规范之一,我们常听说的编程规范还有面向对象编程,面向过程编程。
      • 面向对象的编程思维方式:把现实世界中的事物抽象成程序世界的类和对象,通过封装,继承和多态演示事物事件的联系
      • 函数编程的思维方式:把现实世界的事物和事物之间的联系抽象到程序世界(对运算过程进行抽象)
        • 程序的本质:根据输入,通过某种运算,获得相应的输出
        • 函数式编程中的函数不是指程序中的(函数)方法,而是数学中的函数,即映射关系
        • 相同的输入始终要得到相同的输出(纯函数)
        • 函数式编程用来描述数据(函数)之间的映射关系
      js
      //非函数式编程,面向过程的编程方式
      +import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"函数式编程","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/functionalProgramming.md","lastUpdated":1694419899000}'),p={name:"src/article/functionalProgramming.md"},o=l(`

      函数式编程

      • 概述: 函数式编程(Functional Programming)FP就是编程规范之一,我们常听说的编程规范还有面向对象编程,面向过程编程。
      • 面向对象的编程思维方式:把现实世界中的事物抽象成程序世界的类和对象,通过封装,继承和多态演示事物事件的联系
      • 函数编程的思维方式:把现实世界的事物和事物之间的联系抽象到程序世界(对运算过程进行抽象)
        • 程序的本质:根据输入,通过某种运算,获得相应的输出
        • 函数式编程中的函数不是指程序中的(函数)方法,而是数学中的函数,即映射关系
        • 相同的输入始终要得到相同的输出(纯函数)
        • 函数式编程用来描述数据(函数)之间的映射关系
      js
      //非函数式编程,面向过程的编程方式
       let num1 = 1
       let num2 = 2
       let sum = num1 + num2
      diff --git a/assets/src_article_functionalProgramming.md.e9f945b3.lean.js b/assets/src_article_functionalProgramming.md.0ef4df92.lean.js
      similarity index 85%
      rename from assets/src_article_functionalProgramming.md.e9f945b3.lean.js
      rename to assets/src_article_functionalProgramming.md.0ef4df92.lean.js
      index 0690f21c7..2b4964e36 100644
      --- a/assets/src_article_functionalProgramming.md.e9f945b3.lean.js
      +++ b/assets/src_article_functionalProgramming.md.0ef4df92.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"函数式编程","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/functionalProgramming.md","lastUpdated":1694276611000}'),p={name:"src/article/functionalProgramming.md"},o=l("",66),e=[o];function t(c,r,y,F,D,B){return n(),a("div",null,e)}const E=s(p,[["render",t]]);export{A as __pageData,E as default};
      +import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"函数式编程","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/functionalProgramming.md","lastUpdated":1694419899000}'),p={name:"src/article/functionalProgramming.md"},o=l("",66),e=[o];function t(c,r,y,F,D,B){return n(),a("div",null,e)}const E=s(p,[["render",t]]);export{A as __pageData,E as default};
      diff --git a/assets/src_article_imagemin.md.05c1ce1a.js b/assets/src_article_imagemin.md.32ccabea.js
      similarity index 90%
      rename from assets/src_article_imagemin.md.05c1ce1a.js
      rename to assets/src_article_imagemin.md.32ccabea.js
      index 6c78ad6ac..cf300c7eb 100644
      --- a/assets/src_article_imagemin.md.05c1ce1a.js
      +++ b/assets/src_article_imagemin.md.32ccabea.js
      @@ -1 +1 @@
      -import{_ as a,o as t,c as i,x as e,a as n}from"./chunks/framework.6fe2e870.js";const f=JSON.parse('{"title":"imagemin 图片压缩源码分析","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/imagemin.md","lastUpdated":1694276611000}'),r={name:"src/article/imagemin.md"},s=e("h1",{id:"imagemin-图片压缩源码分析",tabindex:"-1"},[n("imagemin 图片压缩源码分析 "),e("a",{class:"header-anchor",href:"#imagemin-图片压缩源码分析","aria-label":'Permalink to "imagemin 图片压缩源码分析"'},"​")],-1),c=[s];function m(o,d,l,_,p,g){return t(),i("div",null,c)}const x=a(r,[["render",m]]);export{f as __pageData,x as default};
      +import{_ as a,o as t,c as i,x as e,a as n}from"./chunks/framework.6fe2e870.js";const f=JSON.parse('{"title":"imagemin 图片压缩源码分析","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/imagemin.md","lastUpdated":1694419899000}'),r={name:"src/article/imagemin.md"},s=e("h1",{id:"imagemin-图片压缩源码分析",tabindex:"-1"},[n("imagemin 图片压缩源码分析 "),e("a",{class:"header-anchor",href:"#imagemin-图片压缩源码分析","aria-label":'Permalink to "imagemin 图片压缩源码分析"'},"​")],-1),c=[s];function m(o,d,l,_,p,g){return t(),i("div",null,c)}const x=a(r,[["render",m]]);export{f as __pageData,x as default};
      diff --git a/assets/src_article_imagemin.md.05c1ce1a.lean.js b/assets/src_article_imagemin.md.32ccabea.lean.js
      similarity index 90%
      rename from assets/src_article_imagemin.md.05c1ce1a.lean.js
      rename to assets/src_article_imagemin.md.32ccabea.lean.js
      index 6c78ad6ac..cf300c7eb 100644
      --- a/assets/src_article_imagemin.md.05c1ce1a.lean.js
      +++ b/assets/src_article_imagemin.md.32ccabea.lean.js
      @@ -1 +1 @@
      -import{_ as a,o as t,c as i,x as e,a as n}from"./chunks/framework.6fe2e870.js";const f=JSON.parse('{"title":"imagemin 图片压缩源码分析","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/imagemin.md","lastUpdated":1694276611000}'),r={name:"src/article/imagemin.md"},s=e("h1",{id:"imagemin-图片压缩源码分析",tabindex:"-1"},[n("imagemin 图片压缩源码分析 "),e("a",{class:"header-anchor",href:"#imagemin-图片压缩源码分析","aria-label":'Permalink to "imagemin 图片压缩源码分析"'},"​")],-1),c=[s];function m(o,d,l,_,p,g){return t(),i("div",null,c)}const x=a(r,[["render",m]]);export{f as __pageData,x as default};
      +import{_ as a,o as t,c as i,x as e,a as n}from"./chunks/framework.6fe2e870.js";const f=JSON.parse('{"title":"imagemin 图片压缩源码分析","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/imagemin.md","lastUpdated":1694419899000}'),r={name:"src/article/imagemin.md"},s=e("h1",{id:"imagemin-图片压缩源码分析",tabindex:"-1"},[n("imagemin 图片压缩源码分析 "),e("a",{class:"header-anchor",href:"#imagemin-图片压缩源码分析","aria-label":'Permalink to "imagemin 图片压缩源码分析"'},"​")],-1),c=[s];function m(o,d,l,_,p,g){return t(),i("div",null,c)}const x=a(r,[["render",m]]);export{f as __pageData,x as default};
      diff --git a/assets/src_article_javascript_domLoad.md.c8afd20d.js b/assets/src_article_javascript_domLoad.md.f4dd6368.js
      similarity index 97%
      rename from assets/src_article_javascript_domLoad.md.c8afd20d.js
      rename to assets/src_article_javascript_domLoad.md.f4dd6368.js
      index db3108062..aa0dfd601 100644
      --- a/assets/src_article_javascript_domLoad.md.c8afd20d.js
      +++ b/assets/src_article_javascript_domLoad.md.f4dd6368.js
      @@ -1 +1 @@
      -import{_ as a,o as e,c as o,N as t}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"页面加载完成后事件","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/javascript/domLoad.md","lastUpdated":1694276611000}'),n={name:"src/article/javascript/domLoad.md"},s=t('

      页面加载完成后事件

      window.onload

      DOMContentLoaded

      js
      document.addEventListener('DOMContentLoaded', fun)

      <body onload="fun()">

      readyState

      js
      document.readyState\n\ndocument.onreadystatechange

      一个文档的 readyState 可以是以下之一:

      • loading / 加载 。document 仍在加载。
      • interactive / 互动。文档已经完成加载,文档已被解析,但是诸如图像,样式表和框架之类的子资源仍在加载。
      • complete / 完成。T 文档和所有子资源已完成加载。状态表示 load 事件即将被触发。
      ',9),l=[s];function d(r,c,p,i,h,u){return e(),o("div",null,l)}const _=a(n,[["render",d]]);export{m as __pageData,_ as default}; +import{_ as a,o as e,c as o,N as t}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"页面加载完成后事件","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/javascript/domLoad.md","lastUpdated":1694419899000}'),n={name:"src/article/javascript/domLoad.md"},s=t('

      页面加载完成后事件

      window.onload

      DOMContentLoaded

      js
      document.addEventListener('DOMContentLoaded', fun)

      <body onload="fun()">

      readyState

      js
      document.readyState\n\ndocument.onreadystatechange

      一个文档的 readyState 可以是以下之一:

      • loading / 加载 。document 仍在加载。
      • interactive / 互动。文档已经完成加载,文档已被解析,但是诸如图像,样式表和框架之类的子资源仍在加载。
      • complete / 完成。T 文档和所有子资源已完成加载。状态表示 load 事件即将被触发。
      ',9),l=[s];function d(r,c,p,i,h,u){return e(),o("div",null,l)}const _=a(n,[["render",d]]);export{m as __pageData,_ as default}; diff --git a/assets/src_article_javascript_domLoad.md.c8afd20d.lean.js b/assets/src_article_javascript_domLoad.md.f4dd6368.lean.js similarity index 85% rename from assets/src_article_javascript_domLoad.md.c8afd20d.lean.js rename to assets/src_article_javascript_domLoad.md.f4dd6368.lean.js index 32d62741b..3e7627488 100644 --- a/assets/src_article_javascript_domLoad.md.c8afd20d.lean.js +++ b/assets/src_article_javascript_domLoad.md.f4dd6368.lean.js @@ -1 +1 @@ -import{_ as a,o as e,c as o,N as t}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"页面加载完成后事件","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/javascript/domLoad.md","lastUpdated":1694276611000}'),n={name:"src/article/javascript/domLoad.md"},s=t("",9),l=[s];function d(r,c,p,i,h,u){return e(),o("div",null,l)}const _=a(n,[["render",d]]);export{m as __pageData,_ as default}; +import{_ as a,o as e,c as o,N as t}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"页面加载完成后事件","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/javascript/domLoad.md","lastUpdated":1694419899000}'),n={name:"src/article/javascript/domLoad.md"},s=t("",9),l=[s];function d(r,c,p,i,h,u){return e(),o("div",null,l)}const _=a(n,[["render",d]]);export{m as __pageData,_ as default}; diff --git a/assets/src_article_typescript_calculate.md.f31139e2.js b/assets/src_article_typescript_calculate.md.9ee3c861.js similarity index 99% rename from assets/src_article_typescript_calculate.md.f31139e2.js rename to assets/src_article_typescript_calculate.md.9ee3c861.js index 0489fd518..7b3af38b4 100644 --- a/assets/src_article_typescript_calculate.md.f31139e2.js +++ b/assets/src_article_typescript_calculate.md.9ee3c861.js @@ -1,4 +1,4 @@ -import{_ as s,o as n,c as a,N as p}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"数组长度做计数","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/calculate.md","lastUpdated":1694276611000}'),l={name:"src/article/typescript/calculate.md"},o=p(`

      数组长度做计数

      类型系统不是图灵完备,各种逻辑都能写么,但好像没发现数值相关的逻辑。

      没错,数值相关的逻辑比较绕,被我单独摘了出来,就是这节要讲的内容。

      这是类型体操的第四个套路:数组长度做计数。

      TypeScript 类型系统没有加减乘除运算符,怎么做数值运算呢?

      不知道大家有没有注意到数组类型取 length 就是数值。

      比如:

      ts
      type num1 = [unknown]['length']
      +import{_ as s,o as n,c as a,N as p}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"数组长度做计数","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/calculate.md","lastUpdated":1694419899000}'),l={name:"src/article/typescript/calculate.md"},o=p(`

      数组长度做计数

      类型系统不是图灵完备,各种逻辑都能写么,但好像没发现数值相关的逻辑。

      没错,数值相关的逻辑比较绕,被我单独摘了出来,就是这节要讲的内容。

      这是类型体操的第四个套路:数组长度做计数。

      TypeScript 类型系统没有加减乘除运算符,怎么做数值运算呢?

      不知道大家有没有注意到数组类型取 length 就是数值。

      比如:

      ts
      type num1 = [unknown]['length']
       // type num1 = 1
       type num2 = [unknown, unknown]['length']
       // type num1 = 2
      diff --git a/assets/src_article_typescript_calculate.md.f31139e2.lean.js b/assets/src_article_typescript_calculate.md.9ee3c861.lean.js
      similarity index 85%
      rename from assets/src_article_typescript_calculate.md.f31139e2.lean.js
      rename to assets/src_article_typescript_calculate.md.9ee3c861.lean.js
      index c4a869194..32999e96b 100644
      --- a/assets/src_article_typescript_calculate.md.f31139e2.lean.js
      +++ b/assets/src_article_typescript_calculate.md.9ee3c861.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as n,c as a,N as p}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"数组长度做计数","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/calculate.md","lastUpdated":1694276611000}'),l={name:"src/article/typescript/calculate.md"},o=p("",99),e=[o];function t(r,c,B,y,F,D){return n(),a("div",null,e)}const i=s(l,[["render",t]]);export{E as __pageData,i as default};
      +import{_ as s,o as n,c as a,N as p}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"数组长度做计数","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/calculate.md","lastUpdated":1694419899000}'),l={name:"src/article/typescript/calculate.md"},o=p("",99),e=[o];function t(r,c,B,y,F,D){return n(),a("div",null,e)}const i=s(l,[["render",t]]);export{E as __pageData,i as default};
      diff --git a/assets/src_article_typescript_index.md.9450f83c.js b/assets/src_article_typescript_index.md.8330b87a.js
      similarity index 99%
      rename from assets/src_article_typescript_index.md.9450f83c.js
      rename to assets/src_article_typescript_index.md.8330b87a.js
      index bf4ab3087..74f0fd76a 100644
      --- a/assets/src_article_typescript_index.md.9450f83c.js
      +++ b/assets/src_article_typescript_index.md.8330b87a.js
      @@ -1,4 +1,4 @@
      -import{_ as s,o as a,c as n,N as p}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"TypeScript 的类型系统","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/index.md","lastUpdated":1694276611000}'),l={name:"src/article/typescript/index.md"},o=p(`

      TypeScript 的类型系统

      一.类型是什么

      类型具体点来说就是指 number、boolean、string 等基础类型和 Object、Function 等复合类型,它们是编程语言提供的对不同内容的抽象:

      • 不同类型变量占据的内存大小不同: boolean 类型的变量会分配 4 个字节的内存,而 number 类型的变量则会分配 8 个字节的内存,给变量声明了不同的类型就代表了会占据不同的内存空间。

      • 不同类型变量可做的操作不同: number 类型可以做加减乘除等运算,boolean 就不可以,复合类型中不同类型的对象可用的方法不同,比如 Date 和 RegExp,变量的类型不同代表可以对该变量做的操作就不同。

      有了类型,那我们的操作必须和类型相匹配,否则就会报错,这就是类型检查。

      如果能保证对某种类型只做该类型允许的操作,这就叫做类型安全。

      类型检查可以在运行时做,也可以运行之前的编译期做。这是两种不同的类型,前者叫做动态类型检查,后者叫做静态类型检查。

      两种类型检查各有优缺点。动态类型检查 在源码中不保留类型信息,对某个变量赋什么值、做什么操作都是允许的,写代码很灵活。但这也埋下了类型不安全的隐患,比如对 string 做了乘除,对 Date 对象调用了 exec 方法,这些都是运行时才能检查出来的错误。

      其中,最常见的错误应该是 “null is not an object”、“undefined is not a function” 之类的了,写代码时没发现类型不匹配,到了运行的时候才发现,就会有很多这种报错。

      所以,动态类型虽然代码写起来简单,但代码中很容易藏着一些类型不匹配的隐患。

      静态类型检查则是在源码中保留类型信息,声明变量要指定类型,对变量做的操作要和类型匹配,会有专门的编译器在编译期间做检查。

      静态类型给写代码增加了一些难度,因为你除了要考虑代码要表达的逻辑之外,还要考虑类型逻辑:变量是什么类型的、是不是匹配、要不要做类型转换等。

      不过,静态类型也消除了类型不安全的隐患,因为在编译期间就做了类型检查,就不会出现对 string 做了乘除,调用了 Date 的 exec 方法这类问题。

      所以,静态类型虽然代码写起来要考虑的问题多一些,会复杂一些,但是却消除了代码中潜藏类型不安全问题的可能。

      知道了动态类型检查和静态类型检查的区别,我们自然可以得出这样的结论:

      动态类型只适合简单的场景,对于大项目却不太合适,因为代码中可能藏着的隐患太多了,万一线上报一个类型不匹配的错误,那可能就是大问题。

      而静态类型虽然会增加写代码的成本,但是却能更好的保证代码的健壮性,减少 Bug 率。

      所以,大型项目注定会用静态类型语言开发。

      二.类型系统的分类

      1.简单的类型系统

      变量、函数、类等都可以声明类型,编译器会基于声明的类型做类型检查,类型不匹配时会报错。

      这是最基础的类型系统,能保证类型安全,但有些死板。

      比如一个 add 函数既可以做整数加法、又可以做浮点数加法,却需要声明两个函数:

      c
      int add(int a, int b) {
      +import{_ as s,o as a,c as n,N as p}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"TypeScript 的类型系统","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/index.md","lastUpdated":1694419899000}'),l={name:"src/article/typescript/index.md"},o=p(`

      TypeScript 的类型系统

      一.类型是什么

      类型具体点来说就是指 number、boolean、string 等基础类型和 Object、Function 等复合类型,它们是编程语言提供的对不同内容的抽象:

      • 不同类型变量占据的内存大小不同: boolean 类型的变量会分配 4 个字节的内存,而 number 类型的变量则会分配 8 个字节的内存,给变量声明了不同的类型就代表了会占据不同的内存空间。

      • 不同类型变量可做的操作不同: number 类型可以做加减乘除等运算,boolean 就不可以,复合类型中不同类型的对象可用的方法不同,比如 Date 和 RegExp,变量的类型不同代表可以对该变量做的操作就不同。

      有了类型,那我们的操作必须和类型相匹配,否则就会报错,这就是类型检查。

      如果能保证对某种类型只做该类型允许的操作,这就叫做类型安全。

      类型检查可以在运行时做,也可以运行之前的编译期做。这是两种不同的类型,前者叫做动态类型检查,后者叫做静态类型检查。

      两种类型检查各有优缺点。动态类型检查 在源码中不保留类型信息,对某个变量赋什么值、做什么操作都是允许的,写代码很灵活。但这也埋下了类型不安全的隐患,比如对 string 做了乘除,对 Date 对象调用了 exec 方法,这些都是运行时才能检查出来的错误。

      其中,最常见的错误应该是 “null is not an object”、“undefined is not a function” 之类的了,写代码时没发现类型不匹配,到了运行的时候才发现,就会有很多这种报错。

      所以,动态类型虽然代码写起来简单,但代码中很容易藏着一些类型不匹配的隐患。

      静态类型检查则是在源码中保留类型信息,声明变量要指定类型,对变量做的操作要和类型匹配,会有专门的编译器在编译期间做检查。

      静态类型给写代码增加了一些难度,因为你除了要考虑代码要表达的逻辑之外,还要考虑类型逻辑:变量是什么类型的、是不是匹配、要不要做类型转换等。

      不过,静态类型也消除了类型不安全的隐患,因为在编译期间就做了类型检查,就不会出现对 string 做了乘除,调用了 Date 的 exec 方法这类问题。

      所以,静态类型虽然代码写起来要考虑的问题多一些,会复杂一些,但是却消除了代码中潜藏类型不安全问题的可能。

      知道了动态类型检查和静态类型检查的区别,我们自然可以得出这样的结论:

      动态类型只适合简单的场景,对于大项目却不太合适,因为代码中可能藏着的隐患太多了,万一线上报一个类型不匹配的错误,那可能就是大问题。

      而静态类型虽然会增加写代码的成本,但是却能更好的保证代码的健壮性,减少 Bug 率。

      所以,大型项目注定会用静态类型语言开发。

      二.类型系统的分类

      1.简单的类型系统

      变量、函数、类等都可以声明类型,编译器会基于声明的类型做类型检查,类型不匹配时会报错。

      这是最基础的类型系统,能保证类型安全,但有些死板。

      比如一个 add 函数既可以做整数加法、又可以做浮点数加法,却需要声明两个函数:

      c
      int add(int a, int b) {
           return a + b;
       }
       
      diff --git a/assets/src_article_typescript_index.md.9450f83c.lean.js b/assets/src_article_typescript_index.md.8330b87a.lean.js
      similarity index 85%
      rename from assets/src_article_typescript_index.md.9450f83c.lean.js
      rename to assets/src_article_typescript_index.md.8330b87a.lean.js
      index 259692787..fd07944f3 100644
      --- a/assets/src_article_typescript_index.md.9450f83c.lean.js
      +++ b/assets/src_article_typescript_index.md.8330b87a.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as a,c as n,N as p}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"TypeScript 的类型系统","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/index.md","lastUpdated":1694276611000}'),l={name:"src/article/typescript/index.md"},o=p("",253),e=[o];function t(c,r,y,B,D,F){return a(),n("div",null,e)}const E=s(l,[["render",t]]);export{A as __pageData,E as default};
      +import{_ as s,o as a,c as n,N as p}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"TypeScript 的类型系统","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/index.md","lastUpdated":1694419899000}'),l={name:"src/article/typescript/index.md"},o=p("",253),e=[o];function t(c,r,y,B,D,F){return a(),n("div",null,e)}const E=s(l,[["render",t]]);export{A as __pageData,E as default};
      diff --git a/assets/src_article_typescript_pattern.md.e19bc8e4.js b/assets/src_article_typescript_pattern.md.ed4c198d.js
      similarity index 99%
      rename from assets/src_article_typescript_pattern.md.e19bc8e4.js
      rename to assets/src_article_typescript_pattern.md.ed4c198d.js
      index acf010848..19de70b3f 100644
      --- a/assets/src_article_typescript_pattern.md.e19bc8e4.js
      +++ b/assets/src_article_typescript_pattern.md.ed4c198d.js
      @@ -1,4 +1,4 @@
      -import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"模式匹配提取","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/pattern.md","lastUpdated":1694276611000}'),p={name:"src/article/typescript/pattern.md"},o=l(`

      模式匹配提取

      字符串可以和正则做模式匹配,找到匹配的部分,提取子组,之后可以用 1,2 等引用匹配的子组。

      ts
      'abc'.replace(/a(b)c/, '$1,$1,$1')
      +import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"模式匹配提取","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/pattern.md","lastUpdated":1694419899000}'),p={name:"src/article/typescript/pattern.md"},o=l(`

      模式匹配提取

      字符串可以和正则做模式匹配,找到匹配的部分,提取子组,之后可以用 1,2 等引用匹配的子组。

      ts
      'abc'.replace(/a(b)c/, '$1,$1,$1')
       // 'b,b,b'

      Typescript 的类型也同样可以做模式匹配。

      比如这样一个 Promise 类型:

      ts
      type p = Promise<'value'>

      我们想提取 value 的类型,可以这样做:

      ts
      type GetValueType<P> = P extends Promise<infer Value> ? Value : never

      通过 extends 对传入的类型参数 P 做模式匹配,其中值的类型是需要提取的,通过 infer 声明一个局部变量 Value 来保存,如果匹配,就返回匹配到的 Value,否则就返回 never 代表没匹配到。

      ts
      // type GetValueResult = 'value'
       type GetValueResult = GetValueType<Promise<'value'>>

      这就是 Typescript 类型的模式匹配:

      Typescript 类型的模式匹配是通过 extends 对类型参数做匹配,结果保存到通过 infer 声明的局部类型变量里,如果匹配就能从该局部变量里拿到提取出的类型。

      这个模式匹配的套路有多有用呢?我们来看下在数组、字符串、函数、构造器等类型里的应用。

      1.数组类型

      提取第一个元素

      数组类型想提取第一个元素的类型怎么做呢?

      ts
      type arr = [1, 2, 3]

      用它来匹配一个模式类型,提取第一个元素的类型到通过 infer 声明的局部变量里返回。

      ts
      type GetFirst<Arr extends unknown[]> = Arr extends [infer First, ...unknown[]]
         ? First
      diff --git a/assets/src_article_typescript_pattern.md.e19bc8e4.lean.js b/assets/src_article_typescript_pattern.md.ed4c198d.lean.js
      similarity index 85%
      rename from assets/src_article_typescript_pattern.md.e19bc8e4.lean.js
      rename to assets/src_article_typescript_pattern.md.ed4c198d.lean.js
      index 5e7389022..96638dcf4 100644
      --- a/assets/src_article_typescript_pattern.md.e19bc8e4.lean.js
      +++ b/assets/src_article_typescript_pattern.md.ed4c198d.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"模式匹配提取","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/pattern.md","lastUpdated":1694276611000}'),p={name:"src/article/typescript/pattern.md"},o=l("",145),e=[o];function t(r,c,y,B,F,D){return a(),n("div",null,e)}const A=s(p,[["render",t]]);export{E as __pageData,A as default};
      +import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"模式匹配提取","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/pattern.md","lastUpdated":1694419899000}'),p={name:"src/article/typescript/pattern.md"},o=l("",145),e=[o];function t(r,c,y,B,F,D){return a(),n("div",null,e)}const A=s(p,[["render",t]]);export{E as __pageData,A as default};
      diff --git a/assets/src_article_typescript_reconstruction.md.a186fc17.js b/assets/src_article_typescript_reconstruction.md.21d449a5.js
      similarity index 99%
      rename from assets/src_article_typescript_reconstruction.md.a186fc17.js
      rename to assets/src_article_typescript_reconstruction.md.21d449a5.js
      index afae3e37f..36a624a47 100644
      --- a/assets/src_article_typescript_reconstruction.md.a186fc17.js
      +++ b/assets/src_article_typescript_reconstruction.md.21d449a5.js
      @@ -1,4 +1,4 @@
      -import{_ as s,o as a,c as n,N as p}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"重新构造做变换","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/reconstruction.md","lastUpdated":1694276611000}'),l={name:"src/article/typescript/reconstruction.md"},o=p(`

      重新构造做变换

      类型编程主要的目的就是对类型做各种转换,那么如何对类型做修改呢?

      TypeScript 类型系统支持 3 种可以声明任意类型的变量: type、infer、类型参数。

      type 叫做类型别名,其实就是声明一个变量存储某个类型:

      ts
      type ttt = Promise<number>

      infer 用于类型的提取,然后存到一个变量里,相当于局部变量:

      ts
      type GetValueType<P> = P extends Promise<infer Value> ? Value : never

      类型参数用于接受具体的类型,在类型运算中也相当于局部变量:

      ts
      type isTwo<T> = T extends 2 ? true : false

      但是,严格来说这三种也都不叫变量,因为它们不能被重新赋值。

      TypeScript 设计可以做类型编程的类型系统的目的就是为了产生各种复杂的类型,那不能修改怎么产生新类型呢?

      答案是重新构造。

      这就涉及到了第二个类型体操套路:重新构造做变换。

      重新构造

      TypeScript 的 type、infer、类型参数声明的变量都不能修改,想对类型做各种变换产生新的类型就需要重新构造。

      数组、字符串、函数等类型的重新构造比较简单。

      索引类型,也就是多个元素的聚合类型的重新构造复杂一些,涉及到了映射类型的语法。

      我们先从简单的开始:

      数组类型的重新构造

      Push

      有这样一个元组类型:

      ts
      type tuple = [1, 2, 3]

      我想给这个元组类型再添加一些类型,怎么做呢?

      TypeScript 类型变量不支持修改,我们可以构造一个新的元组类型:

      ts
      type Push<Arr extends unknown[], Ele> = [...Arr, Ele]

      类型参数 Arr 是要修改的数组/元组类型,元素的类型任意,也就是 unknown。

      类型参数 Ele 是添加的元素的类型。

      返回的是用 Arr 已有的元素加上 Ele 构造的新的元组类型。

      ts
      type PushResult = Push<[1, 2, 3], 4>
      +import{_ as s,o as a,c as n,N as p}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"重新构造做变换","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/reconstruction.md","lastUpdated":1694419899000}'),l={name:"src/article/typescript/reconstruction.md"},o=p(`

      重新构造做变换

      类型编程主要的目的就是对类型做各种转换,那么如何对类型做修改呢?

      TypeScript 类型系统支持 3 种可以声明任意类型的变量: type、infer、类型参数。

      type 叫做类型别名,其实就是声明一个变量存储某个类型:

      ts
      type ttt = Promise<number>

      infer 用于类型的提取,然后存到一个变量里,相当于局部变量:

      ts
      type GetValueType<P> = P extends Promise<infer Value> ? Value : never

      类型参数用于接受具体的类型,在类型运算中也相当于局部变量:

      ts
      type isTwo<T> = T extends 2 ? true : false

      但是,严格来说这三种也都不叫变量,因为它们不能被重新赋值。

      TypeScript 设计可以做类型编程的类型系统的目的就是为了产生各种复杂的类型,那不能修改怎么产生新类型呢?

      答案是重新构造。

      这就涉及到了第二个类型体操套路:重新构造做变换。

      重新构造

      TypeScript 的 type、infer、类型参数声明的变量都不能修改,想对类型做各种变换产生新的类型就需要重新构造。

      数组、字符串、函数等类型的重新构造比较简单。

      索引类型,也就是多个元素的聚合类型的重新构造复杂一些,涉及到了映射类型的语法。

      我们先从简单的开始:

      数组类型的重新构造

      Push

      有这样一个元组类型:

      ts
      type tuple = [1, 2, 3]

      我想给这个元组类型再添加一些类型,怎么做呢?

      TypeScript 类型变量不支持修改,我们可以构造一个新的元组类型:

      ts
      type Push<Arr extends unknown[], Ele> = [...Arr, Ele]

      类型参数 Arr 是要修改的数组/元组类型,元素的类型任意,也就是 unknown。

      类型参数 Ele 是添加的元素的类型。

      返回的是用 Arr 已有的元素加上 Ele 构造的新的元组类型。

      ts
      type PushResult = Push<[1, 2, 3], 4>
       // type PushResult = [1,2,3,4]

      这就是数组/元组的重新构造。

      数组和元组的区别:数组类型是指任意多个同一类型的元素构成的,比如 number[]Array<number>,而元组则是数量固定,类型可以不同的元素构成的,比如 [1, true, 'name']

      Unshift

      可以在后面添加,同样也可以在前面添加:

      ts
      type Unshift<Arr extends unknown[], Ele> = [Ele, ...Arr]

      Zip

      有这样两个元组:

      ts
      type tuple1 = [1, 2]
       type tuple2 = ['name', 'value']

      我们想把它们合并成这样的元组:

      ts
      type tuple = [[1, 'name'], [2, 'value']]

      思路很容易想到,提取元组中的两个元素,构造成新的元组:

      ts
      type Zip<
         One extends [unknown, unknown],
      diff --git a/assets/src_article_typescript_reconstruction.md.a186fc17.lean.js b/assets/src_article_typescript_reconstruction.md.21d449a5.lean.js
      similarity index 85%
      rename from assets/src_article_typescript_reconstruction.md.a186fc17.lean.js
      rename to assets/src_article_typescript_reconstruction.md.21d449a5.lean.js
      index 657adfb86..004374e39 100644
      --- a/assets/src_article_typescript_reconstruction.md.a186fc17.lean.js
      +++ b/assets/src_article_typescript_reconstruction.md.21d449a5.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as a,c as n,N as p}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"重新构造做变换","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/reconstruction.md","lastUpdated":1694276611000}'),l={name:"src/article/typescript/reconstruction.md"},o=p("",144),e=[o];function t(r,c,B,y,F,D){return a(),n("div",null,e)}const E=s(l,[["render",t]]);export{A as __pageData,E as default};
      +import{_ as s,o as a,c as n,N as p}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"重新构造做变换","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/reconstruction.md","lastUpdated":1694419899000}'),l={name:"src/article/typescript/reconstruction.md"},o=p("",144),e=[o];function t(r,c,B,y,F,D){return a(),n("div",null,e)}const E=s(l,[["render",t]]);export{A as __pageData,E as default};
      diff --git a/assets/src_article_typescript_recursion.md.9db97e45.js b/assets/src_article_typescript_recursion.md.061a1d67.js
      similarity index 99%
      rename from assets/src_article_typescript_recursion.md.9db97e45.js
      rename to assets/src_article_typescript_recursion.md.061a1d67.js
      index 4c1996645..4e5e472c1 100644
      --- a/assets/src_article_typescript_recursion.md.9db97e45.js
      +++ b/assets/src_article_typescript_recursion.md.061a1d67.js
      @@ -1,4 +1,4 @@
      -import{_ as s,o as n,c as a,N as p}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"递归复用","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/recursion.md","lastUpdated":1694276611000}'),l={name:"src/article/typescript/recursion.md"},o=p(`

      递归复用

      递归是把问题分解为一系列相似的小问题,通过函数不断调用自身来解决这一个个小问题,直到满足结束条件,就完成了问题的求解。

      TypeScript 的高级类型支持类型参数,可以做各种类型运算逻辑,返回新的类型,和函数调用是对应的,自然也支持递归。

      TypeScript 类型系统不支持循环,但支持递归。当处理数量(个数、长度、层数)不固定的类型的时候,可以只处理一个类型,然后递归的调用自身处理下一个类型,直到结束条件也就是所有的类型都处理完了,就完成了不确定数量的类型编程,达到循环的效果。

      既然提到了数组、字符串、对象等类型,那么我们就来看一下这些类型的递归案例吧。

      Promise 的递归复用

      DeepPromiseValueType

      先用 Promise 热热身,实现一个提取不确定层数的 Promise 中的 value 类型的高级类型。

      ts
      type ttt = Promise<Promise<Promise<Record<string, any>>>>

      这里是 3 层 Promise,value 类型是索引类型。

      数量不确定,一涉及到这个就要想到用递归来做,每次只处理一层的提取,然后剩下的到下次递归做,直到结束条件。

      所以高级类型是这样的:

      ts
      type DeepPromiseValueType<P extends Promise<unknown>> = P extends Promise<
      +import{_ as s,o as n,c as a,N as p}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"递归复用","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/recursion.md","lastUpdated":1694419899000}'),l={name:"src/article/typescript/recursion.md"},o=p(`

      递归复用

      递归是把问题分解为一系列相似的小问题,通过函数不断调用自身来解决这一个个小问题,直到满足结束条件,就完成了问题的求解。

      TypeScript 的高级类型支持类型参数,可以做各种类型运算逻辑,返回新的类型,和函数调用是对应的,自然也支持递归。

      TypeScript 类型系统不支持循环,但支持递归。当处理数量(个数、长度、层数)不固定的类型的时候,可以只处理一个类型,然后递归的调用自身处理下一个类型,直到结束条件也就是所有的类型都处理完了,就完成了不确定数量的类型编程,达到循环的效果。

      既然提到了数组、字符串、对象等类型,那么我们就来看一下这些类型的递归案例吧。

      Promise 的递归复用

      DeepPromiseValueType

      先用 Promise 热热身,实现一个提取不确定层数的 Promise 中的 value 类型的高级类型。

      ts
      type ttt = Promise<Promise<Promise<Record<string, any>>>>

      这里是 3 层 Promise,value 类型是索引类型。

      数量不确定,一涉及到这个就要想到用递归来做,每次只处理一层的提取,然后剩下的到下次递归做,直到结束条件。

      所以高级类型是这样的:

      ts
      type DeepPromiseValueType<P extends Promise<unknown>> = P extends Promise<
         infer ValueType
       >
         ? ValueType extends Promise<unknown>
      diff --git a/assets/src_article_typescript_recursion.md.9db97e45.lean.js b/assets/src_article_typescript_recursion.md.061a1d67.lean.js
      similarity index 85%
      rename from assets/src_article_typescript_recursion.md.9db97e45.lean.js
      rename to assets/src_article_typescript_recursion.md.061a1d67.lean.js
      index aa5d43310..99f80af54 100644
      --- a/assets/src_article_typescript_recursion.md.9db97e45.lean.js
      +++ b/assets/src_article_typescript_recursion.md.061a1d67.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as n,c as a,N as p}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"递归复用","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/recursion.md","lastUpdated":1694276611000}'),l={name:"src/article/typescript/recursion.md"},o=p("",123),e=[o];function t(r,c,B,y,F,D){return n(),a("div",null,e)}const i=s(l,[["render",t]]);export{E as __pageData,i as default};
      +import{_ as s,o as n,c as a,N as p}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"递归复用","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/recursion.md","lastUpdated":1694419899000}'),l={name:"src/article/typescript/recursion.md"},o=p("",123),e=[o];function t(r,c,B,y,F,D){return n(),a("div",null,e)}const i=s(l,[["render",t]]);export{E as __pageData,i as default};
      diff --git a/assets/src_article_typescript_unionType.md.0ba9cf91.js b/assets/src_article_typescript_unionType.md.2b84a746.js
      similarity index 99%
      rename from assets/src_article_typescript_unionType.md.0ba9cf91.js
      rename to assets/src_article_typescript_unionType.md.2b84a746.js
      index b3291c5f2..4944580ab 100644
      --- a/assets/src_article_typescript_unionType.md.0ba9cf91.js
      +++ b/assets/src_article_typescript_unionType.md.2b84a746.js
      @@ -1 +1 @@
      -import{_ as s,o as a,c as n,N as p}from"./chunks/framework.6fe2e870.js";const i=JSON.parse('{"title":"分布式条件类型","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/unionType.md","lastUpdated":1694276611000}'),l={name:"src/article/typescript/unionType.md"},o=p('

      分布式条件类型

      当类型参数为联合类型,并且在条件类型左边直接引用该类型参数的时候,TypeScript 会把每一个元素单独传入来做类型运算,最后再合并成联合类型,这种语法叫做分布式条件类型。

      比如这样一个联合类型:

      ts
      type Union = 'a' | 'b' | 'c'

      我们想把其中的 a 大写,就可以这样写:

      ts
      type UppercaseA<Item extends string> = Item extends 'a' ? Uppercase<Item> : Item
      ts
      type result = UppercaseA<Union>\n// type result = 'A' | 'b' | 'c';

      可以看到,我们类型参数 Item 约束为 string,条件类型的判断中也是判断是否是 a,但传入的是联合类型。

      这就是 TypeScript 对联合类型在条件类型中使用时的特殊处理:会把联合类型的每一个元素单独传入做类型计算,最后合并。

      这和联合类型遇到字符串时的处理一样:

      这样确实是简化了类型编程逻辑的,不需要递归提取每个元素再处理。

      TypeScript 之所以这样处理联合类型也很容易理解,因为联合类型的每个元素都是互不相关的,不像数组、索引、字符串那样元素之间是有关系的。所以设计成了每一个单独处理,最后合并。

      知道了 TypeScript 怎么处理的联合类型,趁热打铁来练习一下:

      CamelcaseUnion

      Camelcase 我们实现过,就是提取字符串中的字符,首字母大写以后重新构造一个新的。

      ts
      type Camelcase<Str extends string> =\n  Str extends `${infer Left}_${infer Right}${infer Rest}`\n    ? `${Left}${Uppercase<Right>}${Camelcase<Rest>}`\n    : Str

      提取 _ 左右的字符,把右边字符大写之后构造成新的字符串,余下的字符串递归处理。

      ts
      type CamelcaseResult = Camelcase<'aa_aa_aa'>\n// type CamelcaseResult = 'aaAaAa'

      如果是对字符串数组做 Camelcase,那就要递归处理每一个元素:

      ts
      type CamelcaseArr<Arr extends unknown[]> = Arr extends [\n  infer Item,\n  ...infer RestArr,\n]\n  ? [Camelcase<Item & string>, ...CamelcaseArr<RestArr>]\n  : []

      类型参数 Arr 为待处理数组。

      递归提取每一个元素做 Camelcase,因为 Camelcase 要求传入 string,这里要 & string 来变成 string 类型。

      那如果是联合类型呢?

      联合类型不需要递归提取每个元素,TypeScript 内部会把每一个元素传入单独做计算,之后把每个元素的计算结果合并成联合类型。

      ts
      type CamelcaseUnion<Item extends string> =\n  Item extends `${infer Left}_${infer Right}${infer Rest}`\n    ? `${Left}${Uppercase<Right>}${CamelcaseUnion<Rest>}`\n    : Item

      这不和单个字符串的处理没区别么?

      没错,对联合类型的处理和对单个类型的处理没什么区别,TypeScript 会把每个单独的类型拆开传入。不需要像数组类型那样需要递归提取每个元素做处理。

      确实简化了很多,好像都是优点?

      也不全是,其实这样处理也增加了一些认知成本,不信我们再来看个例子:

      IsUnion

      判断联合类型我们会这样写:

      ts
      type IsUnion<A, B = A> = A extends A ? ([B] extends [A] ? false : true) : never

      当传入联合类型时,会返回 true:

      ts
      type IsUnionResult = IsUnion<'a' | 'b' 'c'>\n// type IsUnionResult = true

      当传入其他类型时,会返回 false:

      ts
      type IsUnionResult = IsUnion<['a' | 'b' 'c']>\n// type IsUnionResult = false

      这就是分布式条件类型带来的认知成本。

      我们先来看这样一个类型:

      ts
      type TestUnion<A, B = A> = A extends A ? { a: A; b: B } : never\n\ntype TestUnionResult = TestUnion<'a' | 'b' | 'c'>

      传入联合类型 'a' | 'b' | 'c' 的时候,结果是这样的:

      A 和 B 都是同一个联合类型,为啥值还不一样呢?

      因为条件类型中如果左边的类型是联合类型,会把每个元素单独传入做计算,而右边不会。

      所以 A 是 'a' 的时候,B 是 'a' | 'b' | 'c', A 是 'b' 的时候,B 是 'a' | 'b' | 'c'。。。

      那么利用这个特点就可以实现 Union 类型的判断:

      ts
      type IsUnion<A, B = A> = A extends A ? ([B] extends [A] ? false : true) : never

      类型参数 A、B 是待判断的联合类型,B 默认值为 A,也就是同一个类型。

      A extends A 这段看似没啥意义,主要是为了触发分布式条件类型,让 A 的每个类型单独传入。

      [B] extends [A] 这样不直接写 B 就可以避免触发分布式条件类型,那么 B 就是整个联合类型。

      B 是联合类型整体,而 A 是单个类型,自然不成立,而其它类型没有这种特殊处理,A 和 B 都是同一个,怎么判断都成立。

      利用这个特点就可以判断出是否是联合类型。

      其中有两个点比较困惑,我们重点记一下:

      当 A 是联合类型时:

      A extends A 这种写法是为了触发分布式条件类型,让每个类型单独传入处理的,没别的意义。

      A extends A 和 [A] extends [A] 是不同的处理,前者是单个类型和整个类型做判断,后者两边都是整个联合类型,因为只有 extends 左边直接是类型参数才会触发分布式条件类型。

      理解了这两点,分布式条件类型就算掌握了。

      BEM

      bem 是 css 命名规范,用 block__element--modifier 的形式来描述某个区块下面的某个元素的某个状态的样式。

      那么我们可以写这样一个高级类型,传入 block、element、modifier,返回构造出的 class 名:

      这样使用:

      ts
      type bemResult = BEM<'guang', ['aaa', 'bbb'], ['warning', 'success']>

      它的实现就是三部分的合并,但传入的是数组,要递归遍历取出每一个元素来和其他部分组合,这样太麻烦了。

      而如果是联合类型就不用递归遍历了,因为联合类型遇到字符串也是会单独每个元素单独传入做处理。

      数组转联合类型可以这样写:

      ts
      type union = ['aaa', 'bbb'][number]\n// type union = 'aaa' | 'bbb'

      那么 BEM 就可以这样实现:

      ts
      type BEM<\n  Block extends string,\n  Element extends string[],\n  Modifiers extends string[],\n> = `${Block}__${Element[number]}--${Modifiers[number]}`

      类型参数 Block、Element、Modifiers 分别是 bem 规范的三部分,其中 Element 和 Modifiers 都可能多个,约束为 string[]。

      构造一个字符串类型,其中 Element 和 Modifiers 通过索引访问来变为联合类型。

      字符串类型中遇到联合类型的时候,会每个元素单独传入计算,也就是这样的效果:

      ts
      type RemResult = BEM<'a', ['b', 'c'], ['d', 'e']>\n// type RemResult = 'a__b--d' | 'a__b--e' | 'a__c--d' | 'a__b--e'

      可以看到,用好了联合类型,确实能简化类型编程逻辑。

      AllCombinations

      我们再来实现一个全组合的高级类型,也是联合类型相关的:

      希望传入 'A' | 'B' 的时候,能够返回所有的组合: 'A' | 'B' | 'BA' | 'AB'。

      这种全组合问题的实现思路就是两两组合,组合出的字符串再和其他字符串两两组和:

      比如 'A' | 'B' | 'c',就是 A 和 B、C 组合,B 和 A、C 组合,C 和 A、B 组合。然后组合出来的字符串再和其他字符串组合。

      任何两个类型的组合有四种:A、B、AB、BA

      ts
      type Combination<A extends string, B extends string> =\n  | A\n  | B\n  | `${A}${B}`\n  | `${B}${A}`

      然后构造出来的字符串再和其他字符串组合。

      所以全组合的高级类型就是这样:

      ts
      type AllCombinations<A extends string, B extends string = A> = A extends A\n  ? Combination<A, AllCombinations<Exclude<B, A>>>\n  : never

      类型参数 A、B 是待组合的两个联合类型,B 默认是 A 也就是同一个。

      A extends A 的意义就是让联合类型每个类型单独传入做处理,上面我们刚学会。

      A 的处理就是 A 和 B 中去掉 A 以后的所有类型组合,也就是 Combination<A, B 去掉 A 以后的所有组合>。

      而 B 去掉 A 以后的所有组合就是 AllCombinations<Exclude<B, A>>,所以全组合就是 Combination<A, AllCombinations<Exclude<B, A>>>。

      总结

      联合类型中的每个类型都是相互独立的,TypeScript 对它做了特殊处理,也就是遇到字符串类型、条件类型的时候会把每个类型单独传入做计算,最后把每个类型的计算结果合并成联合类型。

      条件类型左边是联合类型的时候就会触法这种处理,叫做分布式条件类型。

      有两点特别要注意:

      • A extends A 不是没意义,意义是取出联合类型中的单个类型放入 A

      • A extends A 才是分布式条件类型, [A] extends [A] 就不是了,只有左边是单独的类型参数才可以。

      我们后面做了一些案例,发现联合类型的这种 distributive 的特性确实能简化类型编程,但是也增加了认知成本,不过这也是不可避免的事。

      ',91),e=[o];function t(c,r,B,y,F,D){return a(),n("div",null,e)}const E=s(l,[["render",t]]);export{i as __pageData,E as default}; +import{_ as s,o as a,c as n,N as p}from"./chunks/framework.6fe2e870.js";const i=JSON.parse('{"title":"分布式条件类型","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/unionType.md","lastUpdated":1694419899000}'),l={name:"src/article/typescript/unionType.md"},o=p('

      分布式条件类型

      当类型参数为联合类型,并且在条件类型左边直接引用该类型参数的时候,TypeScript 会把每一个元素单独传入来做类型运算,最后再合并成联合类型,这种语法叫做分布式条件类型。

      比如这样一个联合类型:

      ts
      type Union = 'a' | 'b' | 'c'

      我们想把其中的 a 大写,就可以这样写:

      ts
      type UppercaseA<Item extends string> = Item extends 'a' ? Uppercase<Item> : Item
      ts
      type result = UppercaseA<Union>\n// type result = 'A' | 'b' | 'c';

      可以看到,我们类型参数 Item 约束为 string,条件类型的判断中也是判断是否是 a,但传入的是联合类型。

      这就是 TypeScript 对联合类型在条件类型中使用时的特殊处理:会把联合类型的每一个元素单独传入做类型计算,最后合并。

      这和联合类型遇到字符串时的处理一样:

      这样确实是简化了类型编程逻辑的,不需要递归提取每个元素再处理。

      TypeScript 之所以这样处理联合类型也很容易理解,因为联合类型的每个元素都是互不相关的,不像数组、索引、字符串那样元素之间是有关系的。所以设计成了每一个单独处理,最后合并。

      知道了 TypeScript 怎么处理的联合类型,趁热打铁来练习一下:

      CamelcaseUnion

      Camelcase 我们实现过,就是提取字符串中的字符,首字母大写以后重新构造一个新的。

      ts
      type Camelcase<Str extends string> =\n  Str extends `${infer Left}_${infer Right}${infer Rest}`\n    ? `${Left}${Uppercase<Right>}${Camelcase<Rest>}`\n    : Str

      提取 _ 左右的字符,把右边字符大写之后构造成新的字符串,余下的字符串递归处理。

      ts
      type CamelcaseResult = Camelcase<'aa_aa_aa'>\n// type CamelcaseResult = 'aaAaAa'

      如果是对字符串数组做 Camelcase,那就要递归处理每一个元素:

      ts
      type CamelcaseArr<Arr extends unknown[]> = Arr extends [\n  infer Item,\n  ...infer RestArr,\n]\n  ? [Camelcase<Item & string>, ...CamelcaseArr<RestArr>]\n  : []

      类型参数 Arr 为待处理数组。

      递归提取每一个元素做 Camelcase,因为 Camelcase 要求传入 string,这里要 & string 来变成 string 类型。

      那如果是联合类型呢?

      联合类型不需要递归提取每个元素,TypeScript 内部会把每一个元素传入单独做计算,之后把每个元素的计算结果合并成联合类型。

      ts
      type CamelcaseUnion<Item extends string> =\n  Item extends `${infer Left}_${infer Right}${infer Rest}`\n    ? `${Left}${Uppercase<Right>}${CamelcaseUnion<Rest>}`\n    : Item

      这不和单个字符串的处理没区别么?

      没错,对联合类型的处理和对单个类型的处理没什么区别,TypeScript 会把每个单独的类型拆开传入。不需要像数组类型那样需要递归提取每个元素做处理。

      确实简化了很多,好像都是优点?

      也不全是,其实这样处理也增加了一些认知成本,不信我们再来看个例子:

      IsUnion

      判断联合类型我们会这样写:

      ts
      type IsUnion<A, B = A> = A extends A ? ([B] extends [A] ? false : true) : never

      当传入联合类型时,会返回 true:

      ts
      type IsUnionResult = IsUnion<'a' | 'b' 'c'>\n// type IsUnionResult = true

      当传入其他类型时,会返回 false:

      ts
      type IsUnionResult = IsUnion<['a' | 'b' 'c']>\n// type IsUnionResult = false

      这就是分布式条件类型带来的认知成本。

      我们先来看这样一个类型:

      ts
      type TestUnion<A, B = A> = A extends A ? { a: A; b: B } : never\n\ntype TestUnionResult = TestUnion<'a' | 'b' | 'c'>

      传入联合类型 'a' | 'b' | 'c' 的时候,结果是这样的:

      A 和 B 都是同一个联合类型,为啥值还不一样呢?

      因为条件类型中如果左边的类型是联合类型,会把每个元素单独传入做计算,而右边不会。

      所以 A 是 'a' 的时候,B 是 'a' | 'b' | 'c', A 是 'b' 的时候,B 是 'a' | 'b' | 'c'。。。

      那么利用这个特点就可以实现 Union 类型的判断:

      ts
      type IsUnion<A, B = A> = A extends A ? ([B] extends [A] ? false : true) : never

      类型参数 A、B 是待判断的联合类型,B 默认值为 A,也就是同一个类型。

      A extends A 这段看似没啥意义,主要是为了触发分布式条件类型,让 A 的每个类型单独传入。

      [B] extends [A] 这样不直接写 B 就可以避免触发分布式条件类型,那么 B 就是整个联合类型。

      B 是联合类型整体,而 A 是单个类型,自然不成立,而其它类型没有这种特殊处理,A 和 B 都是同一个,怎么判断都成立。

      利用这个特点就可以判断出是否是联合类型。

      其中有两个点比较困惑,我们重点记一下:

      当 A 是联合类型时:

      A extends A 这种写法是为了触发分布式条件类型,让每个类型单独传入处理的,没别的意义。

      A extends A 和 [A] extends [A] 是不同的处理,前者是单个类型和整个类型做判断,后者两边都是整个联合类型,因为只有 extends 左边直接是类型参数才会触发分布式条件类型。

      理解了这两点,分布式条件类型就算掌握了。

      BEM

      bem 是 css 命名规范,用 block__element--modifier 的形式来描述某个区块下面的某个元素的某个状态的样式。

      那么我们可以写这样一个高级类型,传入 block、element、modifier,返回构造出的 class 名:

      这样使用:

      ts
      type bemResult = BEM<'guang', ['aaa', 'bbb'], ['warning', 'success']>

      它的实现就是三部分的合并,但传入的是数组,要递归遍历取出每一个元素来和其他部分组合,这样太麻烦了。

      而如果是联合类型就不用递归遍历了,因为联合类型遇到字符串也是会单独每个元素单独传入做处理。

      数组转联合类型可以这样写:

      ts
      type union = ['aaa', 'bbb'][number]\n// type union = 'aaa' | 'bbb'

      那么 BEM 就可以这样实现:

      ts
      type BEM<\n  Block extends string,\n  Element extends string[],\n  Modifiers extends string[],\n> = `${Block}__${Element[number]}--${Modifiers[number]}`

      类型参数 Block、Element、Modifiers 分别是 bem 规范的三部分,其中 Element 和 Modifiers 都可能多个,约束为 string[]。

      构造一个字符串类型,其中 Element 和 Modifiers 通过索引访问来变为联合类型。

      字符串类型中遇到联合类型的时候,会每个元素单独传入计算,也就是这样的效果:

      ts
      type RemResult = BEM<'a', ['b', 'c'], ['d', 'e']>\n// type RemResult = 'a__b--d' | 'a__b--e' | 'a__c--d' | 'a__b--e'

      可以看到,用好了联合类型,确实能简化类型编程逻辑。

      AllCombinations

      我们再来实现一个全组合的高级类型,也是联合类型相关的:

      希望传入 'A' | 'B' 的时候,能够返回所有的组合: 'A' | 'B' | 'BA' | 'AB'。

      这种全组合问题的实现思路就是两两组合,组合出的字符串再和其他字符串两两组和:

      比如 'A' | 'B' | 'c',就是 A 和 B、C 组合,B 和 A、C 组合,C 和 A、B 组合。然后组合出来的字符串再和其他字符串组合。

      任何两个类型的组合有四种:A、B、AB、BA

      ts
      type Combination<A extends string, B extends string> =\n  | A\n  | B\n  | `${A}${B}`\n  | `${B}${A}`

      然后构造出来的字符串再和其他字符串组合。

      所以全组合的高级类型就是这样:

      ts
      type AllCombinations<A extends string, B extends string = A> = A extends A\n  ? Combination<A, AllCombinations<Exclude<B, A>>>\n  : never

      类型参数 A、B 是待组合的两个联合类型,B 默认是 A 也就是同一个。

      A extends A 的意义就是让联合类型每个类型单独传入做处理,上面我们刚学会。

      A 的处理就是 A 和 B 中去掉 A 以后的所有类型组合,也就是 Combination<A, B 去掉 A 以后的所有组合>。

      而 B 去掉 A 以后的所有组合就是 AllCombinations<Exclude<B, A>>,所以全组合就是 Combination<A, AllCombinations<Exclude<B, A>>>。

      总结

      联合类型中的每个类型都是相互独立的,TypeScript 对它做了特殊处理,也就是遇到字符串类型、条件类型的时候会把每个类型单独传入做计算,最后把每个类型的计算结果合并成联合类型。

      条件类型左边是联合类型的时候就会触法这种处理,叫做分布式条件类型。

      有两点特别要注意:

      • A extends A 不是没意义,意义是取出联合类型中的单个类型放入 A

      • A extends A 才是分布式条件类型, [A] extends [A] 就不是了,只有左边是单独的类型参数才可以。

      我们后面做了一些案例,发现联合类型的这种 distributive 的特性确实能简化类型编程,但是也增加了认知成本,不过这也是不可避免的事。

      ',91),e=[o];function t(c,r,B,y,F,D){return a(),n("div",null,e)}const E=s(l,[["render",t]]);export{i as __pageData,E as default}; diff --git a/assets/src_article_typescript_unionType.md.0ba9cf91.lean.js b/assets/src_article_typescript_unionType.md.2b84a746.lean.js similarity index 85% rename from assets/src_article_typescript_unionType.md.0ba9cf91.lean.js rename to assets/src_article_typescript_unionType.md.2b84a746.lean.js index b1b5b6818..5b051a3a0 100644 --- a/assets/src_article_typescript_unionType.md.0ba9cf91.lean.js +++ b/assets/src_article_typescript_unionType.md.2b84a746.lean.js @@ -1 +1 @@ -import{_ as s,o as a,c as n,N as p}from"./chunks/framework.6fe2e870.js";const i=JSON.parse('{"title":"分布式条件类型","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/unionType.md","lastUpdated":1694276611000}'),l={name:"src/article/typescript/unionType.md"},o=p("",91),e=[o];function t(c,r,B,y,F,D){return a(),n("div",null,e)}const E=s(l,[["render",t]]);export{i as __pageData,E as default}; +import{_ as s,o as a,c as n,N as p}from"./chunks/framework.6fe2e870.js";const i=JSON.parse('{"title":"分布式条件类型","description":"","frontmatter":{},"headers":[],"relativePath":"src/article/typescript/unionType.md","lastUpdated":1694419899000}'),l={name:"src/article/typescript/unionType.md"},o=p("",91),e=[o];function t(c,r,B,y,F,D){return a(),n("div",null,e)}const E=s(l,[["render",t]]);export{i as __pageData,E as default}; diff --git a/assets/src_ranui_button_index.md.32a9d03f.js b/assets/src_ranui_button_index.md.eb788bcc.js similarity index 99% rename from assets/src_ranui_button_index.md.32a9d03f.js rename to assets/src_ranui_button_index.md.eb788bcc.js index cf6ba87e8..c6ac41944 100644 --- a/assets/src_ranui_button_index.md.32a9d03f.js +++ b/assets/src_ranui_button_index.md.eb788bcc.js @@ -1,4 +1,4 @@ -import{_ as n,o,c as t,N as s,x as a}from"./chunks/framework.6fe2e870.js";const h=JSON.parse('{"title":"Button 按钮","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/button/index.md","lastUpdated":1694276611000}'),l={name:"src/ranui/button/index.md"},p=s(`

      Button 按钮

      按钮用于开始一个即时操作。

      代码演示

      Button
      xml
      <r-button >Button</r-button>

      属性

      类型type

      按钮有四种类型

      主要按钮
      警告按钮
      文本按钮
      默认按钮
      xml
      <r-button type="primary">主要按钮</r-button>
      +import{_ as n,o,c as t,N as s,x as a}from"./chunks/framework.6fe2e870.js";const h=JSON.parse('{"title":"Button 按钮","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/button/index.md","lastUpdated":1694419899000}'),l={name:"src/ranui/button/index.md"},p=s(`

      Button 按钮

      按钮用于开始一个即时操作。

      代码演示

      Button
      xml
      <r-button >Button</r-button>

      属性

      类型type

      按钮有四种类型

      主要按钮
      警告按钮
      文本按钮
      默认按钮
      xml
      <r-button type="primary">主要按钮</r-button>
        <r-button type="warning">警告按钮</r-button>
        <r-button type="text">文本按钮</r-button>
        <r-button >默认按钮</r-button>

      不可用状态disabled

      添加 disabled 属性即可让按钮处于不可用状态,同时按钮样式也会改变。

      主要按钮
      警告按钮
      文本按钮
      默认按钮
      xml
      <r-button type="primary" disabled>主要按钮</r-button>
      diff --git a/assets/src_ranui_button_index.md.32a9d03f.lean.js b/assets/src_ranui_button_index.md.eb788bcc.lean.js
      similarity index 88%
      rename from assets/src_ranui_button_index.md.32a9d03f.lean.js
      rename to assets/src_ranui_button_index.md.eb788bcc.lean.js
      index 751350cad..6c1438d71 100644
      --- a/assets/src_ranui_button_index.md.32a9d03f.lean.js
      +++ b/assets/src_ranui_button_index.md.eb788bcc.lean.js
      @@ -1 +1 @@
      -import{_ as n,o,c as t,N as s,x as a}from"./chunks/framework.6fe2e870.js";const h=JSON.parse('{"title":"Button 按钮","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/button/index.md","lastUpdated":1694276611000}'),l={name:"src/ranui/button/index.md"},p=s("",28),e=a("r-button",{type:"default",effect:"fase",icon:"user"},"默认按钮",-1),r=a("r-button",{type:"primary",effect:"fase",icon:"home"},"主要按钮",-1),c=s("",1),D=[p,e,r,c];function y(F,i,u,d,b,g){return o(),t("div",null,D)}const E=n(l,[["render",y]]);export{h as __pageData,E as default};
      +import{_ as n,o,c as t,N as s,x as a}from"./chunks/framework.6fe2e870.js";const h=JSON.parse('{"title":"Button 按钮","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/button/index.md","lastUpdated":1694419899000}'),l={name:"src/ranui/button/index.md"},p=s("",28),e=a("r-button",{type:"default",effect:"fase",icon:"user"},"默认按钮",-1),r=a("r-button",{type:"primary",effect:"fase",icon:"home"},"主要按钮",-1),c=s("",1),D=[p,e,r,c];function y(F,i,u,d,b,g){return o(),t("div",null,D)}const E=n(l,[["render",y]]);export{h as __pageData,E as default};
      diff --git a/assets/src_ranui_icon_index.md.11f7a3d7.js b/assets/src_ranui_icon_index.md.e1b014ce.js
      similarity index 99%
      rename from assets/src_ranui_icon_index.md.11f7a3d7.js
      rename to assets/src_ranui_icon_index.md.e1b014ce.js
      index f88348e55..47407666c 100644
      --- a/assets/src_ranui_icon_index.md.11f7a3d7.js
      +++ b/assets/src_ranui_icon_index.md.e1b014ce.js
      @@ -1,4 +1,4 @@
      -import{_ as c,o as r,c as F,N as t,x as a}from"./chunks/framework.6fe2e870.js";const D=()=>{setTimeout(()=>{const e=["add-user","book","check-circle","close-circle","eye-close","eye","info-circle","loading","lock","message","power-off","setting","team","unlock","user"];if(typeof document<"u"){const o=document.getElementById("icon-list");e.forEach(l=>{const s=document.createElement("div");s.style.setProperty("display","flex"),s.style.setProperty("align-items","center"),s.style.setProperty("margin","15px"),s.style.setProperty("justify-content","center"),s.style.setProperty("flex-flow","column nowrap");const n=document.createElement("r-icon");n.setAttribute("name",l),n.setAttribute("size","50"),s.appendChild(n);const p=document.createElement("span");p.innerHTML=l,s.appendChild(p),o==null||o.appendChild(s)})}},0)};D();const q=JSON.parse('{"title":"Icon 图标","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/icon/index.md","lastUpdated":1694276611000}'),y={name:"src/ranui/icon/index.md"},i=t(`

      Icon 图标

      语义化的矢量图形

      代码演示

      xml
      <r-icon name="lock"  ></r-icon>
      +import{_ as c,o as r,c as F,N as t,x as a}from"./chunks/framework.6fe2e870.js";const D=()=>{setTimeout(()=>{const e=["add-user","book","check-circle","close-circle","eye-close","eye","info-circle","loading","lock","message","power-off","setting","team","unlock","user"];if(typeof document<"u"){const o=document.getElementById("icon-list");e.forEach(l=>{const s=document.createElement("div");s.style.setProperty("display","flex"),s.style.setProperty("align-items","center"),s.style.setProperty("margin","15px"),s.style.setProperty("justify-content","center"),s.style.setProperty("flex-flow","column nowrap");const n=document.createElement("r-icon");n.setAttribute("name",l),n.setAttribute("size","50"),s.appendChild(n);const p=document.createElement("span");p.innerHTML=l,s.appendChild(p),o==null||o.appendChild(s)})}},0)};D();const q=JSON.parse('{"title":"Icon 图标","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/icon/index.md","lastUpdated":1694419899000}'),y={name:"src/ranui/icon/index.md"},i=t(`

      Icon 图标

      语义化的矢量图形

      代码演示

      xml
      <r-icon name="lock"  ></r-icon>
        <r-icon name="eye"  ></r-icon>
        <r-icon name="user"  ></r-icon>

      属性

      名称name

      根据名称选择不同的图标

      html
      <r-icon name="lock"></r-icon>
       <r-icon name="eye"></r-icon>
      diff --git a/assets/src_ranui_icon_index.md.11f7a3d7.lean.js b/assets/src_ranui_icon_index.md.e1b014ce.lean.js
      similarity index 95%
      rename from assets/src_ranui_icon_index.md.11f7a3d7.lean.js
      rename to assets/src_ranui_icon_index.md.e1b014ce.lean.js
      index 231513e5e..65fbb2941 100644
      --- a/assets/src_ranui_icon_index.md.11f7a3d7.lean.js
      +++ b/assets/src_ranui_icon_index.md.e1b014ce.lean.js
      @@ -1 +1 @@
      -import{_ as c,o as r,c as F,N as t,x as a}from"./chunks/framework.6fe2e870.js";const D=()=>{setTimeout(()=>{const e=["add-user","book","check-circle","close-circle","eye-close","eye","info-circle","loading","lock","message","power-off","setting","team","unlock","user"];if(typeof document<"u"){const o=document.getElementById("icon-list");e.forEach(l=>{const s=document.createElement("div");s.style.setProperty("display","flex"),s.style.setProperty("align-items","center"),s.style.setProperty("margin","15px"),s.style.setProperty("justify-content","center"),s.style.setProperty("flex-flow","column nowrap");const n=document.createElement("r-icon");n.setAttribute("name",l),n.setAttribute("size","50"),s.appendChild(n);const p=document.createElement("span");p.innerHTML=l,s.appendChild(p),o==null||o.appendChild(s)})}},0)};D();const q=JSON.parse('{"title":"Icon 图标","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/icon/index.md","lastUpdated":1694276611000}'),y={name:"src/ranui/icon/index.md"},i=t("",18),u=a("div",{style:{display:"flex"}},[a("r-icon",{name:"loading",size:"50",color:"#1E90FF",spin:"0.7"}),a("r-icon",{name:"loading",size:"50",color:"#1E90FF",spin:""}),a("r-icon",{name:"loading",size:"50",color:"#1E90FF",spin:"5"})],-1),d=t("",3),E=[i,u,d];function m(e,o,l,s,n,p){return r(),F("div",null,E)}const h=c(y,[["render",m]]);export{q as __pageData,h as default};
      +import{_ as c,o as r,c as F,N as t,x as a}from"./chunks/framework.6fe2e870.js";const D=()=>{setTimeout(()=>{const e=["add-user","book","check-circle","close-circle","eye-close","eye","info-circle","loading","lock","message","power-off","setting","team","unlock","user"];if(typeof document<"u"){const o=document.getElementById("icon-list");e.forEach(l=>{const s=document.createElement("div");s.style.setProperty("display","flex"),s.style.setProperty("align-items","center"),s.style.setProperty("margin","15px"),s.style.setProperty("justify-content","center"),s.style.setProperty("flex-flow","column nowrap");const n=document.createElement("r-icon");n.setAttribute("name",l),n.setAttribute("size","50"),s.appendChild(n);const p=document.createElement("span");p.innerHTML=l,s.appendChild(p),o==null||o.appendChild(s)})}},0)};D();const q=JSON.parse('{"title":"Icon 图标","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/icon/index.md","lastUpdated":1694419899000}'),y={name:"src/ranui/icon/index.md"},i=t("",18),u=a("div",{style:{display:"flex"}},[a("r-icon",{name:"loading",size:"50",color:"#1E90FF",spin:"0.7"}),a("r-icon",{name:"loading",size:"50",color:"#1E90FF",spin:""}),a("r-icon",{name:"loading",size:"50",color:"#1E90FF",spin:"5"})],-1),d=t("",3),E=[i,u,d];function m(e,o,l,s,n,p){return r(),F("div",null,E)}const h=c(y,[["render",m]]);export{q as __pageData,h as default};
      diff --git a/assets/src_ranui_image_index.md.08e89593.js b/assets/src_ranui_image_index.md.c0b5dda1.js
      similarity index 98%
      rename from assets/src_ranui_image_index.md.08e89593.js
      rename to assets/src_ranui_image_index.md.c0b5dda1.js
      index 550771f7c..44092f4d2 100644
      --- a/assets/src_ranui_image_index.md.08e89593.js
      +++ b/assets/src_ranui_image_index.md.c0b5dda1.js
      @@ -1 +1 @@
      -import{_ as A,o as a,c as E,N as Q,x as o}from"./chunks/framework.6fe2e870.js";const I=JSON.parse('{"title":"Image 图片","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/image/index.md","lastUpdated":1694276611000}'),e={name:"src/ranui/image/index.md"},s=Q('

      Image 图片

      代码演示

      xml
      <r-img src="" fallback=""></r-img>

      属性

      图片加载地址src

      图片的地址

      图片加载失败fallback

      src配置的图片加载失败,兜底的图片地址,下面是默认加载失败图片

      ',8),n=o("r-img",{fallback:"data:image/png;base64,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"},null,-1),g=[s,n];function l(t,c,i,r,B,d){return a(),E("div",null,g)}const C=A(e,[["render",l]]);export{I as __pageData,C as default}; +import{_ as A,o as a,c as E,N as Q,x as o}from"./chunks/framework.6fe2e870.js";const I=JSON.parse('{"title":"Image 图片","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/image/index.md","lastUpdated":1694419899000}'),e={name:"src/ranui/image/index.md"},s=Q('

      Image 图片

      代码演示

      xml
      <r-img src="" fallback=""></r-img>

      属性

      图片加载地址src

      图片的地址

      图片加载失败fallback

      src配置的图片加载失败,兜底的图片地址,下面是默认加载失败图片

      ',8),n=o("r-img",{fallback:"data:image/png;base64,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"},null,-1),g=[s,n];function l(t,c,i,r,B,d){return a(),E("div",null,g)}const C=A(e,[["render",l]]);export{I as __pageData,C as default}; diff --git a/assets/src_ranui_image_index.md.08e89593.lean.js b/assets/src_ranui_image_index.md.c0b5dda1.lean.js similarity index 98% rename from assets/src_ranui_image_index.md.08e89593.lean.js rename to assets/src_ranui_image_index.md.c0b5dda1.lean.js index fc4b2cfbe..f3e3dc722 100644 --- a/assets/src_ranui_image_index.md.08e89593.lean.js +++ b/assets/src_ranui_image_index.md.c0b5dda1.lean.js @@ -1 +1 @@ -import{_ as A,o as a,c as E,N as Q,x as o}from"./chunks/framework.6fe2e870.js";const I=JSON.parse('{"title":"Image 图片","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/image/index.md","lastUpdated":1694276611000}'),e={name:"src/ranui/image/index.md"},s=Q("",8),n=o("r-img",{fallback:"data:image/png;base64,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"},null,-1),g=[s,n];function l(t,c,i,r,B,d){return a(),E("div",null,g)}const C=A(e,[["render",l]]);export{I as __pageData,C as default}; +import{_ as A,o as a,c as E,N as Q,x as o}from"./chunks/framework.6fe2e870.js";const I=JSON.parse('{"title":"Image 图片","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/image/index.md","lastUpdated":1694419899000}'),e={name:"src/ranui/image/index.md"},s=Q("",8),n=o("r-img",{fallback:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMIAAADDCAYAAADQvc6UAAABRWlDQ1BJQ0MgUHJvZmlsZQAAKJFjYGASSSwoyGFhYGDIzSspCnJ3UoiIjFJgf8LAwSDCIMogwMCcmFxc4BgQ4ANUwgCjUcG3awyMIPqyLsis7PPOq3QdDFcvjV3jOD1boQVTPQrgSkktTgbSf4A4LbmgqISBgTEFyFYuLykAsTuAbJEioKOA7DkgdjqEvQHEToKwj4DVhAQ5A9k3gGyB5IxEoBmML4BsnSQk8XQkNtReEOBxcfXxUQg1Mjc0dyHgXNJBSWpFCYh2zi+oLMpMzyhRcASGUqqCZ16yno6CkYGRAQMDKMwhqj/fAIcloxgHQqxAjIHBEugw5sUIsSQpBobtQPdLciLEVJYzMPBHMDBsayhILEqEO4DxG0txmrERhM29nYGBddr//5/DGRjYNRkY/l7////39v///y4Dmn+LgeHANwDrkl1AuO+pmgAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAwqADAAQAAAABAAAAwwAAAAD9b/HnAAAHlklEQVR4Ae3dP3PTWBSGcbGzM6GCKqlIBRV0dHRJFarQ0eUT8LH4BnRU0NHR0UEFVdIlFRV7TzRksomPY8uykTk/zewQfKw/9znv4yvJynLv4uLiV2dBoDiBf4qP3/ARuCRABEFAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghggQAQZQKAnYEaQBAQaASKIAQJEkAEEegJmBElAoBEgghgg0Aj8i0JO4OzsrPv69Wv+hi2qPHr0qNvf39+iI97soRIh4f3z58/u7du3SXX7Xt7Z2enevHmzfQe+oSN2apSAPj09TSrb+XKI/f379+08+A0cNRE2ANkupk+ACNPvkSPcAAEibACyXUyfABGm3yNHuAECRNgAZLuYPgEirKlHu7u7XdyytGwHAd8jjNyng4OD7vnz51dbPT8/7z58+NB9+/bt6jU/TI+AGWHEnrx48eJ/EsSmHzx40L18+fLyzxF3ZVMjEyDCiEDjMYZZS5wiPXnyZFbJaxMhQIQRGzHvWR7XCyOCXsOmiDAi1HmPMMQjDpbpEiDCiL358eNHurW/5SnWdIBbXiDCiA38/Pnzrce2YyZ4//59F3ePLNMl4PbpiL2J0L979+7yDtHDhw8vtzzvdGnEXdvUigSIsCLAWavHp/+qM0BcXMd/q25n1vF57TYBp0a3mUzilePj4+7k5KSLb6gt6ydAhPUzXnoPR0dHl79WGTNCfBnn1uvSCJdegQhLI1vvCk+fPu2ePXt2tZOYEV6/fn31dz+shwAR1sP1cqvLntbEN9MxA9xcYjsxS1jWR4AIa2Ibzx0tc44fYX/16lV6NDFLXH+YL32jwiACRBiEbf5KcXoTIsQSpzXx4N28Ja4BQoK7rgXiydbHjx/P25TaQAJEGAguWy0+2Q8PD6/Ki4R8EVl+bzBOnZY95fq9rj9zAkTI2SxdidBHqG9+skdw43borCXO/ZcJdraPWdv22uIEiLA4q7nvvCug8WTqzQveOH26fodo7g6uFe/a17W3+nFBAkRYENRdb1vkkz1CH9cPsVy/jrhr27PqMYvENYNlHAIesRiBYwRy0V+8iXP8+/fvX11Mr7L7ECueb/r48eMqm7FuI2BGWDEG8cm+7G3NEOfmdcTQw4h9/55lhm7DekRYKQPZF2ArbXTAyu4kDYB2YxUzwg0gi/41ztHnfQG26HbGel/crVrm7tNY+/1btkOEAZ2M05r4FB7r9GbAIdxaZYrHdOsgJ/wCEQY0J74TmOKnbxxT9n3FgGGWWsVdowHtjt9Nnvf7yQM2aZU/TIAIAxrw6dOnAWtZZcoEnBpNuTuObWMEiLAx1HY0ZQJEmHJ3HNvGCBBhY6jtaMoEiJB0Z29vL6ls58vxPcO8/zfrdo5qvKO+d3Fx8Wu8zf1dW4p/cPzLly/dtv9Ts/EbcvGAHhHyfBIhZ6NSiIBTo0LNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiECRCjUbEPNCRAhZ6NSiAARCjXbUHMCRMjZqBQiQIRCzTbUnAARcjYqhQgQoVCzDTUnQIScjUohAkQo1GxDzQkQIWejUogAEQo121BzAkTI2agUIkCEQs021JwAEXI2KoUIEKFQsw01J0CEnI1KIQJEKNRsQ80JECFno1KIABEKNdtQcwJEyNmoFCJAhELNNtScABFyNiqFCBChULMNNSdAhJyNSiEC/wGgKKC4YMA4TAAAAABJRU5ErkJggg=="},null,-1),g=[s,n];function l(t,c,i,r,B,d){return a(),E("div",null,g)}const C=A(e,[["render",l]]);export{I as __pageData,C as default}; diff --git a/assets/src_ranui_index.md.0d4c041d.js b/assets/src_ranui_index.md.8ed6a12e.js similarity index 99% rename from assets/src_ranui_index.md.0d4c041d.js rename to assets/src_ranui_index.md.8ed6a12e.js index 7ae81fba1..caee98f58 100644 --- a/assets/src_ranui_index.md.0d4c041d.js +++ b/assets/src_ranui_index.md.8ed6a12e.js @@ -1,4 +1,4 @@ -import{_ as n,o as l,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/customElements.ed27d2e2.png",v=JSON.parse('{"title":"ranui","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/index.md","lastUpdated":1694276611000}'),e={name:"src/ranui/index.md"},t=a(`

      ranui

      基于 Web Components UI组件库

      Feature 特点

      1. 基于Web Components开发,跨框架复用,统一所有情况。
      2. TypeScript开发,有声明和类型文件。
      3. 纯原生手写,基础组件无依赖。
      4. 文档基于vitepress,所有组件实例可交互。
      5. MIT协议。

      Situation 项目情况

      Build Statusnpm-vnpm-dbrotlimodule formats: umd, esm

      • githttps://github.com/chaxus/ran/tree/main/packages/ranui
      • npmhttps://www.npmjs.com/package/ranui

      Usage 使用

      大多数情况都可以像原生的 div 标签一样使用。

      接下来是一些使用例子

      1. html
      2. js
      3. jsx
      4. vue
      5. tsx

      1.html

      html
      <script src="./ranui/dist/umd/index.umd.cjs"></script>
      +import{_ as n,o as l,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/customElements.ed27d2e2.png",v=JSON.parse('{"title":"ranui","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/index.md","lastUpdated":1694419899000}'),e={name:"src/ranui/index.md"},t=a(`

      ranui

      基于 Web Components UI组件库

      Feature 特点

      1. 基于Web Components开发,跨框架复用,统一所有情况。
      2. TypeScript开发,有声明和类型文件。
      3. 纯原生手写,基础组件无依赖。
      4. 文档基于vitepress,所有组件实例可交互。
      5. MIT协议。

      Situation 项目情况

      Build Statusnpm-vnpm-dbrotlimodule formats: umd, esm

      • githttps://github.com/chaxus/ran/tree/main/packages/ranui
      • npmhttps://www.npmjs.com/package/ranui

      Usage 使用

      大多数情况都可以像原生的 div 标签一样使用。

      接下来是一些使用例子

      1. html
      2. js
      3. jsx
      4. vue
      5. tsx

      1.html

      html
      <script src="./ranui/dist/umd/index.umd.cjs"></script>
       
       <body>
         <r-button>Button</r-button>
      diff --git a/assets/src_ranui_index.md.0d4c041d.lean.js b/assets/src_ranui_index.md.8ed6a12e.lean.js
      similarity index 93%
      rename from assets/src_ranui_index.md.0d4c041d.lean.js
      rename to assets/src_ranui_index.md.8ed6a12e.lean.js
      index c7a0a9a65..e75790ed6 100644
      --- a/assets/src_ranui_index.md.0d4c041d.lean.js
      +++ b/assets/src_ranui_index.md.8ed6a12e.lean.js
      @@ -1 +1 @@
      -import{_ as n,o as l,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/customElements.ed27d2e2.png",v=JSON.parse('{"title":"ranui","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/index.md","lastUpdated":1694276611000}'),e={name:"src/ranui/index.md"},t=a("",40),c=s("div",{style:{display:"flex"}},[s("r-icon",{name:"lock",size:"50"}),s("r-icon",{name:"user",size:"50"}),s("r-icon",{name:"loading",size:"50",color:"#1E90FF",spin:""})],-1),r=a("",9),F=s("r-button",{onclick:"message.info('这是一条提示')"},"信息提示",-1),i=s("r-button",{onclick:"message.warning('这是一条提示')"},"警告提示",-1),y=s("r-button",{onclick:"message.error('这是一条提示')"},"错误提示",-1),D=s("r-button",{onclick:"message.success('这是一条提示')"},"成功提示",-1),B=s("r-button",{onclick:"message.toast('这是一条提示')"},"toast 提示",-1),d=a("",16),u=[t,c,r,F,i,y,D,B,d];function h(m,g,E,A,b,C){return l(),o("div",null,u)}const _=n(e,[["render",h]]);export{v as __pageData,_ as default};
      +import{_ as n,o as l,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/customElements.ed27d2e2.png",v=JSON.parse('{"title":"ranui","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/index.md","lastUpdated":1694419899000}'),e={name:"src/ranui/index.md"},t=a("",40),c=s("div",{style:{display:"flex"}},[s("r-icon",{name:"lock",size:"50"}),s("r-icon",{name:"user",size:"50"}),s("r-icon",{name:"loading",size:"50",color:"#1E90FF",spin:""})],-1),r=a("",9),F=s("r-button",{onclick:"message.info('这是一条提示')"},"信息提示",-1),i=s("r-button",{onclick:"message.warning('这是一条提示')"},"警告提示",-1),y=s("r-button",{onclick:"message.error('这是一条提示')"},"错误提示",-1),D=s("r-button",{onclick:"message.success('这是一条提示')"},"成功提示",-1),B=s("r-button",{onclick:"message.toast('这是一条提示')"},"toast 提示",-1),d=a("",16),u=[t,c,r,F,i,y,D,B,d];function h(m,g,E,A,b,C){return l(),o("div",null,u)}const _=n(e,[["render",h]]);export{v as __pageData,_ as default};
      diff --git a/assets/src_ranui_input_index.md.24d6061b.js b/assets/src_ranui_input_index.md.755c9dc7.js
      similarity index 99%
      rename from assets/src_ranui_input_index.md.24d6061b.js
      rename to assets/src_ranui_input_index.md.755c9dc7.js
      index ace2f6e2e..7f265cce1 100644
      --- a/assets/src_ranui_input_index.md.24d6061b.js
      +++ b/assets/src_ranui_input_index.md.755c9dc7.js
      @@ -1,4 +1,4 @@
      -import{_ as n,o as l,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/input-input.f80a45d3.jpg",q=JSON.parse('{"title":"Input 输入框","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/input/index.md","lastUpdated":1694276611000}'),e={name:"src/ranui/input/index.md"},t=a('

      Input 输入框

      通过鼠标或键盘输入内容,是最基础的表单域的包装。

      代码演示

      输入框:
      xml
      <r-input></r-input>

      属性

      标签label

      提供类似于 Metiral Design 的输入体验。

      html
      <r-input label="user"></r-input>

      占位placeholder

      与原生placeholder一致。

      html
      <r-input placeholder="user"></r-input>

      禁用disabled

      通过disabled可以禁用输入框,禁用后该按钮上的事件失效。

      html
      <r-input label="user" disabled></r-input>

      value

      设置或返回输入框的value属性值。

      类型type

      目前支持passwordnumber这几种类型,设置后会出现额外的ui控件。

      密码输入框

      支持密码明文和密文切换。

      html
      <r-input icon="lock" type="password"></r-input>

      图标icon

      可以设置一个icon来表示标签标识。

      html
      <r-input icon="user"></r-input>

      数字输入框

      数字输入框,类似于原生input[type=number],支持minmaxstep属性,支持键盘上下键切换数字。

      html
      <r-input type="number" min="-10" max="10" step="0.5"></r-input>

      name 属性名

      跟 form 组件联动的时候有效,form 提交时收集的字段名字

      status 状态

      • error

      默认色值: #ff4d4f

      ',40),c=s("div",null,[s("r-input",{status:"error"})],-1),r=a('
      xml
      <r-input status="error"></r-input>
      • warning

      默认色值: #ff7875

      ',3),D=s("div",null,[s("r-input",{status:"warning"})],-1),i=a('
      xml
      <r-input  status="warning"></r-input>

      事件event

      常见的回调事件。

      onchange

      文本改变的时候触发。

      ',5),F=s("r-input",{onchange:"console.log(this.value)"},null,-1),y=a(`
      html
      <r-input onchange="func(this.value)"></r-input>
      js
      const input = document.createElement('r-input')
      +import{_ as n,o as l,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/input-input.f80a45d3.jpg",q=JSON.parse('{"title":"Input 输入框","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/input/index.md","lastUpdated":1694419899000}'),e={name:"src/ranui/input/index.md"},t=a('

      Input 输入框

      通过鼠标或键盘输入内容,是最基础的表单域的包装。

      代码演示

      输入框:
      xml
      <r-input></r-input>

      属性

      标签label

      提供类似于 Metiral Design 的输入体验。

      html
      <r-input label="user"></r-input>

      占位placeholder

      与原生placeholder一致。

      html
      <r-input placeholder="user"></r-input>

      禁用disabled

      通过disabled可以禁用输入框,禁用后该按钮上的事件失效。

      html
      <r-input label="user" disabled></r-input>

      value

      设置或返回输入框的value属性值。

      类型type

      目前支持passwordnumber这几种类型,设置后会出现额外的ui控件。

      密码输入框

      支持密码明文和密文切换。

      html
      <r-input icon="lock" type="password"></r-input>

      图标icon

      可以设置一个icon来表示标签标识。

      html
      <r-input icon="user"></r-input>

      数字输入框

      数字输入框,类似于原生input[type=number],支持minmaxstep属性,支持键盘上下键切换数字。

      html
      <r-input type="number" min="-10" max="10" step="0.5"></r-input>

      name 属性名

      跟 form 组件联动的时候有效,form 提交时收集的字段名字

      status 状态

      • error

      默认色值: #ff4d4f

      ',40),c=s("div",null,[s("r-input",{status:"error"})],-1),r=a('
      xml
      <r-input status="error"></r-input>
      • warning

      默认色值: #ff7875

      ',3),D=s("div",null,[s("r-input",{status:"warning"})],-1),i=a('
      xml
      <r-input  status="warning"></r-input>

      事件event

      常见的回调事件。

      onchange

      文本改变的时候触发。

      ',5),F=s("r-input",{onchange:"console.log(this.value)"},null,-1),y=a(`
      html
      <r-input onchange="func(this.value)"></r-input>
      js
      const input = document.createElement('r-input')
       input.setAttribute('label', 'home')
       const func = (e) => {
         console.log(e)
      diff --git a/assets/src_ranui_input_index.md.24d6061b.lean.js b/assets/src_ranui_input_index.md.755c9dc7.lean.js
      similarity index 91%
      rename from assets/src_ranui_input_index.md.24d6061b.lean.js
      rename to assets/src_ranui_input_index.md.755c9dc7.lean.js
      index 88e08a3ec..881369f4b 100644
      --- a/assets/src_ranui_input_index.md.24d6061b.lean.js
      +++ b/assets/src_ranui_input_index.md.755c9dc7.lean.js
      @@ -1 +1 @@
      -import{_ as n,o as l,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/input-input.f80a45d3.jpg",q=JSON.parse('{"title":"Input 输入框","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/input/index.md","lastUpdated":1694276611000}'),e={name:"src/ranui/input/index.md"},t=a("",40),c=s("div",null,[s("r-input",{status:"error"})],-1),r=a("",3),D=s("div",null,[s("r-input",{status:"warning"})],-1),i=a("",5),F=s("r-input",{onchange:"console.log(this.value)"},null,-1),y=a("",4),d=s("r-input",{oninput:"console.log(this.value)"},null,-1),u=a("",2),h=[t,c,r,D,i,F,y,d,u];function _(m,A,E,g,b,B){return l(),o("div",null,h)}const v=n(e,[["render",_]]);export{q as __pageData,v as default};
      +import{_ as n,o as l,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/input-input.f80a45d3.jpg",q=JSON.parse('{"title":"Input 输入框","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/input/index.md","lastUpdated":1694419899000}'),e={name:"src/ranui/input/index.md"},t=a("",40),c=s("div",null,[s("r-input",{status:"error"})],-1),r=a("",3),D=s("div",null,[s("r-input",{status:"warning"})],-1),i=a("",5),F=s("r-input",{onchange:"console.log(this.value)"},null,-1),y=a("",4),d=s("r-input",{oninput:"console.log(this.value)"},null,-1),u=a("",2),h=[t,c,r,D,i,F,y,d,u];function _(m,A,E,g,b,B){return l(),o("div",null,h)}const v=n(e,[["render",_]]);export{q as __pageData,v as default};
      diff --git a/assets/src_ranui_message_index.md.fa827f88.js b/assets/src_ranui_message_index.md.2e7373db.js
      similarity index 99%
      rename from assets/src_ranui_message_index.md.fa827f88.js
      rename to assets/src_ranui_message_index.md.2e7373db.js
      index e395c4f69..a5f0443cc 100644
      --- a/assets/src_ranui_message_index.md.fa827f88.js
      +++ b/assets/src_ranui_message_index.md.2e7373db.js
      @@ -1,4 +1,4 @@
      -import{_ as n,o as t,c as l,x as s,a as o,N as a}from"./chunks/framework.6fe2e870.js";const q=JSON.parse('{"title":"message 全局提示","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/message/index.md","lastUpdated":1694276611000}'),e={name:"src/ranui/message/index.md"},p=s("h1",{id:"message-全局提示",tabindex:"-1"},[o("message 全局提示 "),s("a",{class:"header-anchor",href:"#message-全局提示","aria-label":'Permalink to "message 全局提示"'},"​")],-1),c=s("p",null,"全局展示操作反馈信息。",-1),r=s("h2",{id:"代码演示",tabindex:"-1"},[o("代码演示 "),s("a",{class:"header-anchor",href:"#代码演示","aria-label":'Permalink to "代码演示"'},"​")],-1),D=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{type:"primary",onclick:"message.info('这是一条提示')"},"点击触发全局提示")],-1),F=a('
      xml
      <r-button type="primary" onclick="message.info('这是一条提示')">点击触发全局提示</r-button>

      属性

      类型type

      不同的提示类型

      ',4),i=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.info('这是一条提示')"},"信息提示")],-1),y=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.warning('这是一条提示')"},"警告提示")],-1),d=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.error('这是一条提示')"},"错误提示")],-1),g=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.success('这是一条提示')"},"成功提示")],-1),m=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.toast('这是一条提示')"},"toast提示")],-1),u=a(`
      html
      <r-button onclick="message.info('这是一条提示')">信息提示</r-button>
      +import{_ as n,o as t,c as l,x as s,a as o,N as a}from"./chunks/framework.6fe2e870.js";const q=JSON.parse('{"title":"message 全局提示","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/message/index.md","lastUpdated":1694419899000}'),e={name:"src/ranui/message/index.md"},p=s("h1",{id:"message-全局提示",tabindex:"-1"},[o("message 全局提示 "),s("a",{class:"header-anchor",href:"#message-全局提示","aria-label":'Permalink to "message 全局提示"'},"​")],-1),c=s("p",null,"全局展示操作反馈信息。",-1),r=s("h2",{id:"代码演示",tabindex:"-1"},[o("代码演示 "),s("a",{class:"header-anchor",href:"#代码演示","aria-label":'Permalink to "代码演示"'},"​")],-1),D=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{type:"primary",onclick:"message.info('这是一条提示')"},"点击触发全局提示")],-1),F=a('
      xml
      <r-button type="primary" onclick="message.info('这是一条提示')">点击触发全局提示</r-button>

      属性

      类型type

      不同的提示类型

      ',4),i=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.info('这是一条提示')"},"信息提示")],-1),y=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.warning('这是一条提示')"},"警告提示")],-1),d=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.error('这是一条提示')"},"错误提示")],-1),g=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.success('这是一条提示')"},"成功提示")],-1),m=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.toast('这是一条提示')"},"toast提示")],-1),u=a(`
      html
      <r-button onclick="message.info('这是一条提示')">信息提示</r-button>
       <r-button onclick="message.warning('这是一条提示')">警告提示</r-button>
       <r-button onclick="message.error('这是一条提示')">错误提示</r-button>
       <r-button onclick="message.success('这是一条提示')">成功提示</r-button>
      diff --git a/assets/src_ranui_message_index.md.fa827f88.lean.js b/assets/src_ranui_message_index.md.2e7373db.lean.js
      similarity index 96%
      rename from assets/src_ranui_message_index.md.fa827f88.lean.js
      rename to assets/src_ranui_message_index.md.2e7373db.lean.js
      index 6352a01d2..6bce2bb2e 100644
      --- a/assets/src_ranui_message_index.md.fa827f88.lean.js
      +++ b/assets/src_ranui_message_index.md.2e7373db.lean.js
      @@ -1 +1 @@
      -import{_ as n,o as t,c as l,x as s,a as o,N as a}from"./chunks/framework.6fe2e870.js";const q=JSON.parse('{"title":"message 全局提示","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/message/index.md","lastUpdated":1694276611000}'),e={name:"src/ranui/message/index.md"},p=s("h1",{id:"message-全局提示",tabindex:"-1"},[o("message 全局提示 "),s("a",{class:"header-anchor",href:"#message-全局提示","aria-label":'Permalink to "message 全局提示"'},"​")],-1),c=s("p",null,"全局展示操作反馈信息。",-1),r=s("h2",{id:"代码演示",tabindex:"-1"},[o("代码演示 "),s("a",{class:"header-anchor",href:"#代码演示","aria-label":'Permalink to "代码演示"'},"​")],-1),D=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{type:"primary",onclick:"message.info('这是一条提示')"},"点击触发全局提示")],-1),F=a("",4),i=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.info('这是一条提示')"},"信息提示")],-1),y=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.warning('这是一条提示')"},"警告提示")],-1),d=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.error('这是一条提示')"},"错误提示")],-1),g=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.success('这是一条提示')"},"成功提示")],-1),m=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.toast('这是一条提示')"},"toast提示")],-1),u=a("",16),h=[p,c,r,D,F,i,y,d,g,m,u];function _(b,E,A,C,k,x){return t(),l("div",null,h)}const f=n(e,[["render",_]]);export{q as __pageData,f as default};
      +import{_ as n,o as t,c as l,x as s,a as o,N as a}from"./chunks/framework.6fe2e870.js";const q=JSON.parse('{"title":"message 全局提示","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/message/index.md","lastUpdated":1694419899000}'),e={name:"src/ranui/message/index.md"},p=s("h1",{id:"message-全局提示",tabindex:"-1"},[o("message 全局提示 "),s("a",{class:"header-anchor",href:"#message-全局提示","aria-label":'Permalink to "message 全局提示"'},"​")],-1),c=s("p",null,"全局展示操作反馈信息。",-1),r=s("h2",{id:"代码演示",tabindex:"-1"},[o("代码演示 "),s("a",{class:"header-anchor",href:"#代码演示","aria-label":'Permalink to "代码演示"'},"​")],-1),D=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{type:"primary",onclick:"message.info('这是一条提示')"},"点击触发全局提示")],-1),F=a("",4),i=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.info('这是一条提示')"},"信息提示")],-1),y=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.warning('这是一条提示')"},"警告提示")],-1),d=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.error('这是一条提示')"},"错误提示")],-1),g=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.success('这是一条提示')"},"成功提示")],-1),m=s("div",{style:{display:"inline-block","margin-right":"8px","margin-bottom":"12px"}},[s("r-button",{onclick:"message.toast('这是一条提示')"},"toast提示")],-1),u=a("",16),h=[p,c,r,D,F,i,y,d,g,m,u];function _(b,E,A,C,k,x){return t(),l("div",null,h)}const f=n(e,[["render",_]]);export{q as __pageData,f as default};
      diff --git a/assets/src_ranui_modal_index.md.f410050d.js b/assets/src_ranui_modal_index.md.69c2268b.js
      similarity index 82%
      rename from assets/src_ranui_modal_index.md.f410050d.js
      rename to assets/src_ranui_modal_index.md.69c2268b.js
      index 70fb0ffb7..9b293fec1 100644
      --- a/assets/src_ranui_modal_index.md.f410050d.js
      +++ b/assets/src_ranui_modal_index.md.69c2268b.js
      @@ -1 +1 @@
      -import{_ as e,o as t,c as a}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/modal/index.md","lastUpdated":1694276611000}'),r={name:"src/ranui/modal/index.md"};function n(o,s,c,d,i,p){return t(),a("div")}const l=e(r,[["render",n]]);export{m as __pageData,l as default};
      +import{_ as e,o as t,c as a}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/modal/index.md","lastUpdated":1694419899000}'),r={name:"src/ranui/modal/index.md"};function n(o,s,c,d,i,p){return t(),a("div")}const l=e(r,[["render",n]]);export{m as __pageData,l as default};
      diff --git a/assets/src_ranui_modal_index.md.f410050d.lean.js b/assets/src_ranui_modal_index.md.69c2268b.lean.js
      similarity index 82%
      rename from assets/src_ranui_modal_index.md.f410050d.lean.js
      rename to assets/src_ranui_modal_index.md.69c2268b.lean.js
      index 70fb0ffb7..9b293fec1 100644
      --- a/assets/src_ranui_modal_index.md.f410050d.lean.js
      +++ b/assets/src_ranui_modal_index.md.69c2268b.lean.js
      @@ -1 +1 @@
      -import{_ as e,o as t,c as a}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/modal/index.md","lastUpdated":1694276611000}'),r={name:"src/ranui/modal/index.md"};function n(o,s,c,d,i,p){return t(),a("div")}const l=e(r,[["render",n]]);export{m as __pageData,l as default};
      +import{_ as e,o as t,c as a}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/modal/index.md","lastUpdated":1694419899000}'),r={name:"src/ranui/modal/index.md"};function n(o,s,c,d,i,p){return t(),a("div")}const l=e(r,[["render",n]]);export{m as __pageData,l as default};
      diff --git a/assets/src_ranui_preview_index.md.9a6fa2f6.js b/assets/src_ranui_preview_index.md.fa3a8f12.js
      similarity index 99%
      rename from assets/src_ranui_preview_index.md.9a6fa2f6.js
      rename to assets/src_ranui_preview_index.md.fa3a8f12.js
      index de0836333..11bde954a 100644
      --- a/assets/src_ranui_preview_index.md.9a6fa2f6.js
      +++ b/assets/src_ranui_preview_index.md.fa3a8f12.js
      @@ -1,4 +1,4 @@
      -import{_ as n,o as l,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"preview 文件预览","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/preview/index.md","lastUpdated":1694276611000}'),p={name:"src/ranui/preview/index.md"},e=a('

      preview 文件预览

      支持docxpptxpdf,xlsx文件的预览

      代码演示

      ',3),t=s("div",{style:{width:"100px","margin-top":"10px"}},[s("r-preview",{id:"preview"}),s("r-button",{type:"primary",onclick:"uploadFile('preview')"},"choose file to preview")],-1),c=a(`
      html
      <r-preview id="preview"></r-preview>
      +import{_ as n,o as l,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"preview 文件预览","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/preview/index.md","lastUpdated":1694419899000}'),p={name:"src/ranui/preview/index.md"},e=a('

      preview 文件预览

      支持docxpptxpdf,xlsx文件的预览

      代码演示

      ',3),t=s("div",{style:{width:"100px","margin-top":"10px"}},[s("r-preview",{id:"preview"}),s("r-button",{type:"primary",onclick:"uploadFile('preview')"},"choose file to preview")],-1),c=a(`
      html
      <r-preview id="preview"></r-preview>
       <r-button type="primary" onclick="uploadFile()"
         >choose file to preview</r-button
       >
      diff --git a/assets/src_ranui_preview_index.md.9a6fa2f6.lean.js b/assets/src_ranui_preview_index.md.fa3a8f12.lean.js
      similarity index 89%
      rename from assets/src_ranui_preview_index.md.9a6fa2f6.lean.js
      rename to assets/src_ranui_preview_index.md.fa3a8f12.lean.js
      index 3c6a46b7c..b08652b8a 100644
      --- a/assets/src_ranui_preview_index.md.9a6fa2f6.lean.js
      +++ b/assets/src_ranui_preview_index.md.fa3a8f12.lean.js
      @@ -1 +1 @@
      -import{_ as n,o as l,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"preview 文件预览","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/preview/index.md","lastUpdated":1694276611000}'),p={name:"src/ranui/preview/index.md"},e=a("",3),t=s("div",{style:{width:"100px","margin-top":"10px"}},[s("r-preview",{id:"preview"}),s("r-button",{type:"primary",onclick:"uploadFile('preview')"},"choose file to preview")],-1),c=a("",8),r=[e,t,c];function F(y,D,i,d,A,u){return l(),o("div",null,r)}const h=n(p,[["render",F]]);export{E as __pageData,h as default};
      +import{_ as n,o as l,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"preview 文件预览","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/preview/index.md","lastUpdated":1694419899000}'),p={name:"src/ranui/preview/index.md"},e=a("",3),t=s("div",{style:{width:"100px","margin-top":"10px"}},[s("r-preview",{id:"preview"}),s("r-button",{type:"primary",onclick:"uploadFile('preview')"},"choose file to preview")],-1),c=a("",8),r=[e,t,c];function F(y,D,i,d,A,u){return l(),o("div",null,r)}const h=n(p,[["render",F]]);export{E as __pageData,h as default};
      diff --git a/assets/src_ranui_skeleton_index.md.472eb512.js b/assets/src_ranui_skeleton_index.md.51e3be48.js
      similarity index 95%
      rename from assets/src_ranui_skeleton_index.md.472eb512.js
      rename to assets/src_ranui_skeleton_index.md.51e3be48.js
      index cbcad4d57..ac770c3f0 100644
      --- a/assets/src_ranui_skeleton_index.md.472eb512.js
      +++ b/assets/src_ranui_skeleton_index.md.51e3be48.js
      @@ -1 +1 @@
      -import{_ as e,o as t,c as s,N as a}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"skeleton 骨架屏","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/skeleton/index.md","lastUpdated":1694276611000}'),n={name:"src/ranui/skeleton/index.md"},o=a('

      skeleton 骨架屏

      在需要等待加载内容的位置提供一个占位图形组合。

      代码演示

      骨架长度跟随父级元素的长度

      xml
      <r-skeleton ></r-skeleton>
      ',9),l=[o];function r(i,p,c,d,_,k){return t(),s("div",null,l)}const x=e(n,[["render",r]]);export{m as __pageData,x as default}; +import{_ as e,o as t,c as s,N as a}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"skeleton 骨架屏","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/skeleton/index.md","lastUpdated":1694419899000}'),n={name:"src/ranui/skeleton/index.md"},o=a('

      skeleton 骨架屏

      在需要等待加载内容的位置提供一个占位图形组合。

      代码演示

      骨架长度跟随父级元素的长度

      xml
      <r-skeleton ></r-skeleton>
      ',9),l=[o];function r(i,p,c,d,_,k){return t(),s("div",null,l)}const x=e(n,[["render",r]]);export{m as __pageData,x as default}; diff --git a/assets/src_ranui_skeleton_index.md.472eb512.lean.js b/assets/src_ranui_skeleton_index.md.51e3be48.lean.js similarity index 84% rename from assets/src_ranui_skeleton_index.md.472eb512.lean.js rename to assets/src_ranui_skeleton_index.md.51e3be48.lean.js index 99014109e..cf3d40325 100644 --- a/assets/src_ranui_skeleton_index.md.472eb512.lean.js +++ b/assets/src_ranui_skeleton_index.md.51e3be48.lean.js @@ -1 +1 @@ -import{_ as e,o as t,c as s,N as a}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"skeleton 骨架屏","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/skeleton/index.md","lastUpdated":1694276611000}'),n={name:"src/ranui/skeleton/index.md"},o=a("",9),l=[o];function r(i,p,c,d,_,k){return t(),s("div",null,l)}const x=e(n,[["render",r]]);export{m as __pageData,x as default}; +import{_ as e,o as t,c as s,N as a}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"skeleton 骨架屏","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/skeleton/index.md","lastUpdated":1694419899000}'),n={name:"src/ranui/skeleton/index.md"},o=a("",9),l=[o];function r(i,p,c,d,_,k){return t(),s("div",null,l)}const x=e(n,[["render",r]]);export{m as __pageData,x as default}; diff --git a/assets/src_ranui_tab_index.md.087770cd.js b/assets/src_ranui_tab_index.md.ec0122dc.js similarity index 99% rename from assets/src_ranui_tab_index.md.087770cd.js rename to assets/src_ranui_tab_index.md.ec0122dc.js index 423bef8de..40e8b68cd 100644 --- a/assets/src_ranui_tab_index.md.087770cd.js +++ b/assets/src_ranui_tab_index.md.ec0122dc.js @@ -1,4 +1,4 @@ -import{_ as l,o as n,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const q=JSON.parse('{"title":"Tab 图标","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/tab/index.md","lastUpdated":1694276611000}'),p={name:"src/ranui/tab/index.md"},t=a(`

      Tab 图标

      标签页,其中r-tab需要和r-tabs搭配使用

      代码演示

      111112222233333
      xml
      <r-tabs >
      +import{_ as l,o as n,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const q=JSON.parse('{"title":"Tab 图标","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/tab/index.md","lastUpdated":1694419899000}'),p={name:"src/ranui/tab/index.md"},t=a(`

      Tab 图标

      标签页,其中r-tab需要和r-tabs搭配使用

      代码演示

      111112222233333
      xml
      <r-tabs >
             <r-tab label="tab1">11111</r-tab>
             <r-tab label="tab2">22222</r-tab>
             <r-tab label="tab3">33333</r-tab>
      diff --git a/assets/src_ranui_tab_index.md.087770cd.lean.js b/assets/src_ranui_tab_index.md.ec0122dc.lean.js
      similarity index 94%
      rename from assets/src_ranui_tab_index.md.087770cd.lean.js
      rename to assets/src_ranui_tab_index.md.ec0122dc.lean.js
      index 170d128fa..c6cd31339 100644
      --- a/assets/src_ranui_tab_index.md.087770cd.lean.js
      +++ b/assets/src_ranui_tab_index.md.ec0122dc.lean.js
      @@ -1 +1 @@
      -import{_ as l,o as n,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const q=JSON.parse('{"title":"Tab 图标","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/tab/index.md","lastUpdated":1694276611000}'),p={name:"src/ranui/tab/index.md"},t=a("",13),e=s("div",{style:{width:"100%"}},[s("r-tabs",{active:"1"},[s("r-tab",{label:"tab1"},"11111"),s("r-tab",{label:"tab2"},"22222"),s("r-tab",{label:"tab3"},"33333")])],-1),r=a("",2),c=s("div",{style:{width:"100%"}},[s("r-tabs",{active:"c"},[s("r-tab",{label:"tab1",ranKey:"a"},"11111"),s("r-tab",{label:"tab2",ranKey:"b"},"22222"),s("r-tab",{label:"tab3",ranKey:"c"},"33333"),s("r-tab",{label:"tab4"},"4")])],-1),D=a("",3),F=s("div",{style:{width:"100%"}},[s("r-tabs",{active:"c"},[s("r-tab",{label:"tab1",ranKey:"a",disabled:""},"11111"),s("r-tab",{label:"tab2",ranKey:"b"},"22222"),s("r-tab",{label:"tab3",ranKey:"c"},"33333"),s("r-tab",{label:"tab4"},"4")])],-1),y=a("",20),b=[t,e,r,c,D,F,y];function i(d,E,u,B,g,A){return n(),o("div",null,b)}const h=l(p,[["render",i]]);export{q as __pageData,h as default};
      +import{_ as l,o as n,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const q=JSON.parse('{"title":"Tab 图标","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/tab/index.md","lastUpdated":1694419899000}'),p={name:"src/ranui/tab/index.md"},t=a("",13),e=s("div",{style:{width:"100%"}},[s("r-tabs",{active:"1"},[s("r-tab",{label:"tab1"},"11111"),s("r-tab",{label:"tab2"},"22222"),s("r-tab",{label:"tab3"},"33333")])],-1),r=a("",2),c=s("div",{style:{width:"100%"}},[s("r-tabs",{active:"c"},[s("r-tab",{label:"tab1",ranKey:"a"},"11111"),s("r-tab",{label:"tab2",ranKey:"b"},"22222"),s("r-tab",{label:"tab3",ranKey:"c"},"33333"),s("r-tab",{label:"tab4"},"4")])],-1),D=a("",3),F=s("div",{style:{width:"100%"}},[s("r-tabs",{active:"c"},[s("r-tab",{label:"tab1",ranKey:"a",disabled:""},"11111"),s("r-tab",{label:"tab2",ranKey:"b"},"22222"),s("r-tab",{label:"tab3",ranKey:"c"},"33333"),s("r-tab",{label:"tab4"},"4")])],-1),y=a("",20),b=[t,e,r,c,D,F,y];function i(d,E,u,B,g,A){return n(),o("div",null,b)}const h=l(p,[["render",i]]);export{q as __pageData,h as default};
      diff --git a/assets/src_ranui_tabs_index.md.eff91b6b.js b/assets/src_ranui_tabs_index.md.301a2c3b.js
      similarity index 99%
      rename from assets/src_ranui_tabs_index.md.eff91b6b.js
      rename to assets/src_ranui_tabs_index.md.301a2c3b.js
      index 7c80133b2..ff0e62d9f 100644
      --- a/assets/src_ranui_tabs_index.md.eff91b6b.js
      +++ b/assets/src_ranui_tabs_index.md.301a2c3b.js
      @@ -1,4 +1,4 @@
      -import{_ as l,o as n,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const B=JSON.parse('{"title":"Tab","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/tabs/index.md","lastUpdated":1694276611000}'),p={name:"src/ranui/tabs/index.md"},t=a(`

      Tab

      代码展示

      tab1tab2tab3
      xml
      <r-tabs>
      +import{_ as l,o as n,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const B=JSON.parse('{"title":"Tab","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/tabs/index.md","lastUpdated":1694419899000}'),p={name:"src/ranui/tabs/index.md"},t=a(`

      Tab

      代码展示

      tab1tab2tab3
      xml
      <r-tabs>
           <r-tab label="tab1">tab1</r-tab>
           <r-tab label="tab2">tab2</r-tab>
           <r-tab label="tab3">tab3</r-tab>
      diff --git a/assets/src_ranui_tabs_index.md.eff91b6b.lean.js b/assets/src_ranui_tabs_index.md.301a2c3b.lean.js
      similarity index 91%
      rename from assets/src_ranui_tabs_index.md.eff91b6b.lean.js
      rename to assets/src_ranui_tabs_index.md.301a2c3b.lean.js
      index d10bb61a3..07af12a71 100644
      --- a/assets/src_ranui_tabs_index.md.eff91b6b.lean.js
      +++ b/assets/src_ranui_tabs_index.md.301a2c3b.lean.js
      @@ -1 +1 @@
      -import{_ as l,o as n,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const B=JSON.parse('{"title":"Tab","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/tabs/index.md","lastUpdated":1694276611000}'),p={name:"src/ranui/tabs/index.md"},t=a("",16),e=s("r-tabs",{active:"B"},[s("r-tab",{label:"tab1","r-key":"A"},"tab1"),s("r-tab",{label:"tab2","r-key":"B"},"tab2"),s("r-tab",{label:"tab3","r-key":"C"},"tab3")],-1),c=a("",6),r=s("r-tabs",null,[s("r-tab",{icon:"home",iconSize:"22"},"tab1"),s("r-tab",{icon:"message",iconSize:"22"},"tab2"),s("r-tab",{icon:"user",iconSize:"22"},"tab3")],-1),D=a("",7),F=[t,e,c,r,D];function y(b,i,d,u,h,E){return n(),o("div",null,F)}const q=l(p,[["render",y]]);export{B as __pageData,q as default};
      +import{_ as l,o as n,c as o,N as a,x as s}from"./chunks/framework.6fe2e870.js";const B=JSON.parse('{"title":"Tab","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranui/tabs/index.md","lastUpdated":1694419899000}'),p={name:"src/ranui/tabs/index.md"},t=a("",16),e=s("r-tabs",{active:"B"},[s("r-tab",{label:"tab1","r-key":"A"},"tab1"),s("r-tab",{label:"tab2","r-key":"B"},"tab2"),s("r-tab",{label:"tab3","r-key":"C"},"tab3")],-1),c=a("",6),r=s("r-tabs",null,[s("r-tab",{icon:"home",iconSize:"22"},"tab1"),s("r-tab",{icon:"message",iconSize:"22"},"tab2"),s("r-tab",{icon:"user",iconSize:"22"},"tab3")],-1),D=a("",7),F=[t,e,c,r,D];function y(b,i,d,u,h,E){return n(),o("div",null,F)}const q=l(p,[["render",y]]);export{B as __pageData,q as default};
      diff --git a/assets/src_ranuts_binaryTree_index.md.9df1bc99.js b/assets/src_ranuts_binaryTree_index.md.493e0878.js
      similarity index 99%
      rename from assets/src_ranuts_binaryTree_index.md.9df1bc99.js
      rename to assets/src_ranuts_binaryTree_index.md.493e0878.js
      index 067d46815..d0eccc697 100644
      --- a/assets/src_ranuts_binaryTree_index.md.9df1bc99.js
      +++ b/assets/src_ranuts_binaryTree_index.md.493e0878.js
      @@ -1 +1 @@
      -import{_ as a,o as e,c as r,N as i}from"./chunks/framework.6fe2e870.js";const t="/ran/assets/balanceTree.3d01d012.png",m=JSON.parse('{"title":"二叉树的定义","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/binaryTree/index.md","lastUpdated":1694276611000}'),h={name:"src/ranuts/binaryTree/index.md"},l=i('

      二叉树的定义

      在计算机科学中,二叉树(Binary tree)是每个节点最多只有两个分支(即不存在分支度大于 2 的节点)的树结构。通常分支被称作“左子树”或“右子树”。二叉树的分支具有左右次序,不能随意颠倒[1]。。

      二叉树的性质

      • 在二叉树的第 i 层上最多有 2^(i-1)个结点(i>=1)
      • 深度为 h 的二叉树,最多有 2^h-1 个结点,最少有 h 个结点(h>=1)
      • 包含 n 个结点的二叉树的高度至少为(log2n)+1
      • 非空的二叉树,分支度为 0 的总数为 n0,分支度为 2 的总数为 n2,则 n0=n2+1
      • 二叉树的总结点数 n = n1 + n2 + n0
      • 总连线数等于总节点数减一(B = n - 1)
      • 总连线数等于分支度为 2 的节点的两倍加上分支度为 1 的节点(B = n2 _ 2 + n1 _ 1)

      二叉树的类型

      满二叉树

      一棵深度为 k 且有 2k-1 个节点的二叉树称为满二叉树。 除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树[2]

      完全二叉树

      一棵深度为 k 的有 n 个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为 i(1≤i≤n)的结点与满二叉树中编号为 i 的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。

      二叉搜索树

      二叉搜索树(BST)又称二叉查找树或二叉排序树。它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。

      平衡二叉树

      平衡二叉树(AVL)一定是二叉搜索树,且左子树和右子树的高度差的绝对值不超过 1。 平衡二叉树

      B 树

      B 树属于多叉树又名平衡多路查找树(查找路径不只两个)

      B+树

      B+树是 B 树的变体,也是一种多路搜索树。

      B*树

      B* 树是 B+树的变体,在 B+树的非根和非叶子结点再增加指向兄弟的指针;B* 树定义了非叶子结点关键字个数至少为(2/3)M,即块的最低使用率为 2/3(代替 B+树的 1/2)。B 树分配新结点的概率比 B+树要低,空间使用率更高;

      红黑树

      红黑树是一种平衡二叉查找树的变体,它的左右子树高差有可能大于 1,所以红黑树不是严格意义上的平衡二叉树(AVL),但对它进行平衡的代价较低, 其平均统计性能要强于 AVL 。

      遍历

      前序遍历

      后序遍历

      中序遍历

      层序遍历

      常见算法题

      镜像二叉树

      重建二叉树

      二叉树深度

      二叉树节点总数

      判断二叉树子结构

      输入两棵二叉树 A 和 B,判断 B 是不是 A 的子结构。(ps:约定空树不是任意一个树的子结构)

      参考文档

      1. 维基百科二叉树
      2. 百度百科满二叉树
      ',36),o=[l];function n(d,s,c,u,b,q){return e(),r("div",null,o)}const f=a(h,[["render",n]]);export{m as __pageData,f as default}; +import{_ as a,o as e,c as r,N as i}from"./chunks/framework.6fe2e870.js";const t="/ran/assets/balanceTree.3d01d012.png",m=JSON.parse('{"title":"二叉树的定义","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/binaryTree/index.md","lastUpdated":1694419899000}'),h={name:"src/ranuts/binaryTree/index.md"},l=i('

      二叉树的定义

      在计算机科学中,二叉树(Binary tree)是每个节点最多只有两个分支(即不存在分支度大于 2 的节点)的树结构。通常分支被称作“左子树”或“右子树”。二叉树的分支具有左右次序,不能随意颠倒[1]。。

      二叉树的性质

      • 在二叉树的第 i 层上最多有 2^(i-1)个结点(i>=1)
      • 深度为 h 的二叉树,最多有 2^h-1 个结点,最少有 h 个结点(h>=1)
      • 包含 n 个结点的二叉树的高度至少为(log2n)+1
      • 非空的二叉树,分支度为 0 的总数为 n0,分支度为 2 的总数为 n2,则 n0=n2+1
      • 二叉树的总结点数 n = n1 + n2 + n0
      • 总连线数等于总节点数减一(B = n - 1)
      • 总连线数等于分支度为 2 的节点的两倍加上分支度为 1 的节点(B = n2 _ 2 + n1 _ 1)

      二叉树的类型

      满二叉树

      一棵深度为 k 且有 2k-1 个节点的二叉树称为满二叉树。 除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树[2]

      完全二叉树

      一棵深度为 k 的有 n 个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为 i(1≤i≤n)的结点与满二叉树中编号为 i 的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。

      二叉搜索树

      二叉搜索树(BST)又称二叉查找树或二叉排序树。它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。

      平衡二叉树

      平衡二叉树(AVL)一定是二叉搜索树,且左子树和右子树的高度差的绝对值不超过 1。 平衡二叉树

      B 树

      B 树属于多叉树又名平衡多路查找树(查找路径不只两个)

      B+树

      B+树是 B 树的变体,也是一种多路搜索树。

      B*树

      B* 树是 B+树的变体,在 B+树的非根和非叶子结点再增加指向兄弟的指针;B* 树定义了非叶子结点关键字个数至少为(2/3)M,即块的最低使用率为 2/3(代替 B+树的 1/2)。B 树分配新结点的概率比 B+树要低,空间使用率更高;

      红黑树

      红黑树是一种平衡二叉查找树的变体,它的左右子树高差有可能大于 1,所以红黑树不是严格意义上的平衡二叉树(AVL),但对它进行平衡的代价较低, 其平均统计性能要强于 AVL 。

      遍历

      前序遍历

      后序遍历

      中序遍历

      层序遍历

      常见算法题

      镜像二叉树

      重建二叉树

      二叉树深度

      二叉树节点总数

      判断二叉树子结构

      输入两棵二叉树 A 和 B,判断 B 是不是 A 的子结构。(ps:约定空树不是任意一个树的子结构)

      参考文档

      1. 维基百科二叉树
      2. 百度百科满二叉树
      ',36),o=[l];function n(d,s,c,u,b,q){return e(),r("div",null,o)}const f=a(h,[["render",n]]);export{m as __pageData,f as default}; diff --git a/assets/src_ranuts_binaryTree_index.md.9df1bc99.lean.js b/assets/src_ranuts_binaryTree_index.md.493e0878.lean.js similarity index 86% rename from assets/src_ranuts_binaryTree_index.md.9df1bc99.lean.js rename to assets/src_ranuts_binaryTree_index.md.493e0878.lean.js index e0c69479f..55d8337d3 100644 --- a/assets/src_ranuts_binaryTree_index.md.9df1bc99.lean.js +++ b/assets/src_ranuts_binaryTree_index.md.493e0878.lean.js @@ -1 +1 @@ -import{_ as a,o as e,c as r,N as i}from"./chunks/framework.6fe2e870.js";const t="/ran/assets/balanceTree.3d01d012.png",m=JSON.parse('{"title":"二叉树的定义","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/binaryTree/index.md","lastUpdated":1694276611000}'),h={name:"src/ranuts/binaryTree/index.md"},l=i("",36),o=[l];function n(d,s,c,u,b,q){return e(),r("div",null,o)}const f=a(h,[["render",n]]);export{m as __pageData,f as default}; +import{_ as a,o as e,c as r,N as i}from"./chunks/framework.6fe2e870.js";const t="/ran/assets/balanceTree.3d01d012.png",m=JSON.parse('{"title":"二叉树的定义","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/binaryTree/index.md","lastUpdated":1694419899000}'),h={name:"src/ranuts/binaryTree/index.md"},l=i("",36),o=[l];function n(d,s,c,u,b,q){return e(),r("div",null,o)}const f=a(h,[["render",n]]);export{m as __pageData,f as default}; diff --git a/assets/src_ranuts_bundler_index.md.605ec91e.js b/assets/src_ranuts_bundler_index.md.bf6a07c5.js similarity index 96% rename from assets/src_ranuts_bundler_index.md.605ec91e.js rename to assets/src_ranuts_bundler_index.md.bf6a07c5.js index b0cd2ee86..dc1a24d0b 100644 --- a/assets/src_ranuts_bundler_index.md.605ec91e.js +++ b/assets/src_ranuts_bundler_index.md.bf6a07c5.js @@ -1,4 +1,4 @@ -import{_ as n,o as s,c as a,N as e}from"./chunks/framework.6fe2e870.js";const l="/ran/assets/bundle.9ebe4911.png",m=JSON.parse('{"title":"Bundler","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/bundler/index.md","lastUpdated":1694276611000}'),t={name:"src/ranuts/bundler/index.md"},p=e(`

      Bundler

      Bundler的使用: 传入 options 参数

      function build(options: Options):Promise<Build> {
      +import{_ as n,o as s,c as a,N as e}from"./chunks/framework.6fe2e870.js";const l="/ran/assets/bundle.9ebe4911.png",m=JSON.parse('{"title":"Bundler","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/bundler/index.md","lastUpdated":1694419899000}'),t={name:"src/ranuts/bundler/index.md"},p=e(`

      Bundler

      Bundler的使用: 传入 options 参数

      function build(options: Options):Promise<Build> {
         const bundle = new Bundle({
           entry: options.input
         });
      diff --git a/assets/src_ranuts_bundler_index.md.605ec91e.lean.js b/assets/src_ranuts_bundler_index.md.bf6a07c5.lean.js
      similarity index 85%
      rename from assets/src_ranuts_bundler_index.md.605ec91e.lean.js
      rename to assets/src_ranuts_bundler_index.md.bf6a07c5.lean.js
      index cc69917ce..e73bd0251 100644
      --- a/assets/src_ranuts_bundler_index.md.605ec91e.lean.js
      +++ b/assets/src_ranuts_bundler_index.md.bf6a07c5.lean.js
      @@ -1 +1 @@
      -import{_ as n,o as s,c as a,N as e}from"./chunks/framework.6fe2e870.js";const l="/ran/assets/bundle.9ebe4911.png",m=JSON.parse('{"title":"Bundler","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/bundler/index.md","lastUpdated":1694276611000}'),t={name:"src/ranuts/bundler/index.md"},p=e("",5),o=[p];function r(c,d,i,b,u,_){return s(),a("div",null,o)}const y=n(t,[["render",r]]);export{m as __pageData,y as default};
      +import{_ as n,o as s,c as a,N as e}from"./chunks/framework.6fe2e870.js";const l="/ran/assets/bundle.9ebe4911.png",m=JSON.parse('{"title":"Bundler","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/bundler/index.md","lastUpdated":1694419899000}'),t={name:"src/ranuts/bundler/index.md"},p=e("",5),o=[p];function r(c,d,i,b,u,_){return s(),a("div",null,o)}const y=n(t,[["render",r]]);export{m as __pageData,y as default};
      diff --git a/assets/src_ranuts_file_index.md.177e1adc.js b/assets/src_ranuts_file_index.md.3ff8632d.js
      similarity index 96%
      rename from assets/src_ranuts_file_index.md.177e1adc.js
      rename to assets/src_ranuts_file_index.md.3ff8632d.js
      index e1224e831..74d156035 100644
      --- a/assets/src_ranuts_file_index.md.177e1adc.js
      +++ b/assets/src_ranuts_file_index.md.3ff8632d.js
      @@ -1 +1 @@
      -import{_ as t,o as e,c as a,N as d}from"./chunks/framework.6fe2e870.js";const b=JSON.parse('{"title":"文件操作函数","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/file/index.md","lastUpdated":1694276611000}'),r={name:"src/ranuts/file/index.md"},o=d('

      文件操作函数

      watchFile

      观察一个文件是否改变

      API

      Return

      • Promise
      参数说明类型描述
      status文件是否被改变booleantrue 文件改变 false 文件没变

      Options

      参数说明类型默认值
      path文件路径,需要监听的文件stringundefined
      interval监听文件改变的时间,单位毫秒。number20
      ',9),h=[o];function i(n,l,s,c,u,_){return e(),a("div",null,h)}const f=t(r,[["render",i]]);export{b as __pageData,f as default}; +import{_ as t,o as e,c as a,N as d}from"./chunks/framework.6fe2e870.js";const b=JSON.parse('{"title":"文件操作函数","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/file/index.md","lastUpdated":1694419899000}'),r={name:"src/ranuts/file/index.md"},o=d('

      文件操作函数

      watchFile

      观察一个文件是否改变

      API

      Return

      • Promise
      参数说明类型描述
      status文件是否被改变booleantrue 文件改变 false 文件没变

      Options

      参数说明类型默认值
      path文件路径,需要监听的文件stringundefined
      interval监听文件改变的时间,单位毫秒。number20
      ',9),h=[o];function i(n,l,s,c,u,_){return e(),a("div",null,h)}const f=t(r,[["render",i]]);export{b as __pageData,f as default}; diff --git a/assets/src_ranuts_file_index.md.177e1adc.lean.js b/assets/src_ranuts_file_index.md.3ff8632d.lean.js similarity index 84% rename from assets/src_ranuts_file_index.md.177e1adc.lean.js rename to assets/src_ranuts_file_index.md.3ff8632d.lean.js index 9a759dce7..fecb160d2 100644 --- a/assets/src_ranuts_file_index.md.177e1adc.lean.js +++ b/assets/src_ranuts_file_index.md.3ff8632d.lean.js @@ -1 +1 @@ -import{_ as t,o as e,c as a,N as d}from"./chunks/framework.6fe2e870.js";const b=JSON.parse('{"title":"文件操作函数","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/file/index.md","lastUpdated":1694276611000}'),r={name:"src/ranuts/file/index.md"},o=d("",9),h=[o];function i(n,l,s,c,u,_){return e(),a("div",null,h)}const f=t(r,[["render",i]]);export{b as __pageData,f as default}; +import{_ as t,o as e,c as a,N as d}from"./chunks/framework.6fe2e870.js";const b=JSON.parse('{"title":"文件操作函数","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/file/index.md","lastUpdated":1694419899000}'),r={name:"src/ranuts/file/index.md"},o=d("",9),h=[o];function i(n,l,s,c,u,_){return e(),a("div",null,h)}const f=t(r,[["render",i]]);export{b as __pageData,f as default}; diff --git a/assets/src_ranuts_index.md.238fdd9e.js b/assets/src_ranuts_index.md.f4ae71e9.js similarity index 81% rename from assets/src_ranuts_index.md.238fdd9e.js rename to assets/src_ranuts_index.md.f4ae71e9.js index 3a4a79a6b..2ecb1c08f 100644 --- a/assets/src_ranuts_index.md.238fdd9e.js +++ b/assets/src_ranuts_index.md.f4ae71e9.js @@ -1 +1 @@ -import{_ as e,o as t,c as a}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/index.md","lastUpdated":1694276611000}'),r={name:"src/ranuts/index.md"};function s(n,c,o,d,i,p){return t(),a("div")}const f=e(r,[["render",s]]);export{m as __pageData,f as default}; +import{_ as e,o as t,c as a}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/index.md","lastUpdated":1694419899000}'),r={name:"src/ranuts/index.md"};function s(n,c,o,d,i,p){return t(),a("div")}const f=e(r,[["render",s]]);export{m as __pageData,f as default}; diff --git a/assets/src_ranuts_index.md.238fdd9e.lean.js b/assets/src_ranuts_index.md.f4ae71e9.lean.js similarity index 81% rename from assets/src_ranuts_index.md.238fdd9e.lean.js rename to assets/src_ranuts_index.md.f4ae71e9.lean.js index 3a4a79a6b..2ecb1c08f 100644 --- a/assets/src_ranuts_index.md.238fdd9e.lean.js +++ b/assets/src_ranuts_index.md.f4ae71e9.lean.js @@ -1 +1 @@ -import{_ as e,o as t,c as a}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/index.md","lastUpdated":1694276611000}'),r={name:"src/ranuts/index.md"};function s(n,c,o,d,i,p){return t(),a("div")}const f=e(r,[["render",s]]);export{m as __pageData,f as default}; +import{_ as e,o as t,c as a}from"./chunks/framework.6fe2e870.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/index.md","lastUpdated":1694419899000}'),r={name:"src/ranuts/index.md"};function s(n,c,o,d,i,p){return t(),a("div")}const f=e(r,[["render",s]]);export{m as __pageData,f as default}; diff --git a/assets/src_ranuts_sort_bubble_index.md.3b551a0c.js b/assets/src_ranuts_sort_bubble_index.md.d2e4bc60.js similarity index 99% rename from assets/src_ranuts_sort_bubble_index.md.3b551a0c.js rename to assets/src_ranuts_sort_bubble_index.md.d2e4bc60.js index f10ebd1a8..e2dc775fc 100644 --- a/assets/src_ranuts_sort_bubble_index.md.3b551a0c.js +++ b/assets/src_ranuts_sort_bubble_index.md.d2e4bc60.js @@ -1,4 +1,4 @@ -import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/bubble.287f9a70.gif",E=JSON.parse('{"title":"冒泡排序(Bubble Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/bubble/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/bubble/index.md"},e=l('

      冒泡排序(Bubble Sort)

      冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

      算法描述

      • 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
      • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
      • 针对所有的元素重复以上的步骤,除了最后一个;
      • 重复步骤 1~3,直到排序完成。

      动图演示

      冒泡排序

      代码演示

      js
      function bubbleSort(arr) {
      +import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/bubble.287f9a70.gif",E=JSON.parse('{"title":"冒泡排序(Bubble Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/bubble/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/bubble/index.md"},e=l('

      冒泡排序(Bubble Sort)

      冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

      算法描述

      • 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
      • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
      • 针对所有的元素重复以上的步骤,除了最后一个;
      • 重复步骤 1~3,直到排序完成。

      动图演示

      冒泡排序

      代码演示

      js
      function bubbleSort(arr) {
         var len = arr.length
         for (var i = 0; i < len - 1; i++) {
           for (var j = 0; j < len - 1 - i; j++) {
      diff --git a/assets/src_ranuts_sort_bubble_index.md.3b551a0c.lean.js b/assets/src_ranuts_sort_bubble_index.md.d2e4bc60.lean.js
      similarity index 86%
      rename from assets/src_ranuts_sort_bubble_index.md.3b551a0c.lean.js
      rename to assets/src_ranuts_sort_bubble_index.md.d2e4bc60.lean.js
      index d170d3d53..5942c44da 100644
      --- a/assets/src_ranuts_sort_bubble_index.md.3b551a0c.lean.js
      +++ b/assets/src_ranuts_sort_bubble_index.md.d2e4bc60.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/bubble.287f9a70.gif",E=JSON.parse('{"title":"冒泡排序(Bubble Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/bubble/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/bubble/index.md"},e=l("",8),t=[e];function r(c,y,F,D,i,B){return a(),n("div",null,t)}const b=s(p,[["render",r]]);export{E as __pageData,b as default};
      +import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/bubble.287f9a70.gif",E=JSON.parse('{"title":"冒泡排序(Bubble Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/bubble/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/bubble/index.md"},e=l("",8),t=[e];function r(c,y,F,D,i,B){return a(),n("div",null,t)}const b=s(p,[["render",r]]);export{E as __pageData,b as default};
      diff --git a/assets/src_ranuts_sort_bucket_index.md.755536c3.js b/assets/src_ranuts_sort_bucket_index.md.39a1b5ca.js
      similarity index 99%
      rename from assets/src_ranuts_sort_bucket_index.md.755536c3.js
      rename to assets/src_ranuts_sort_bucket_index.md.39a1b5ca.js
      index 083892d4b..b4ec310f5 100644
      --- a/assets/src_ranuts_sort_bucket_index.md.755536c3.js
      +++ b/assets/src_ranuts_sort_bucket_index.md.39a1b5ca.js
      @@ -1,4 +1,4 @@
      -import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"桶排序 (Bucket Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/bucket/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/bucket/index.md"},o=l(`

      桶排序 (Bucket Sort)

      高效与否的关键在于这个分桶函数。将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。

      算法描述

      • 设置一个定量的数组当作空桶;
      • 遍历输入数据,并且把数据一个一个放到对应的桶里去;
      • 对每个不是空的桶进行排序;
      • 从不是空的桶里把排好序的数据拼接起来。

      代码演示

      ts
      const count = (list: Array<number>, max: number = 100): Array<number> => {
      +import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"桶排序 (Bucket Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/bucket/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/bucket/index.md"},o=l(`

      桶排序 (Bucket Sort)

      高效与否的关键在于这个分桶函数。将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。

      算法描述

      • 设置一个定量的数组当作空桶;
      • 遍历输入数据,并且把数据一个一个放到对应的桶里去;
      • 对每个不是空的桶进行排序;
      • 从不是空的桶里把排好序的数据拼接起来。

      代码演示

      ts
      const count = (list: Array<number>, max: number = 100): Array<number> => {
         const countList = new Array(max + 1)
         for (let i = 0; i < list.length; i++) {
           if (!countList[list[i]]) {
      diff --git a/assets/src_ranuts_sort_bucket_index.md.755536c3.lean.js b/assets/src_ranuts_sort_bucket_index.md.39a1b5ca.lean.js
      similarity index 85%
      rename from assets/src_ranuts_sort_bucket_index.md.755536c3.lean.js
      rename to assets/src_ranuts_sort_bucket_index.md.39a1b5ca.lean.js
      index cf655c363..d393ab2cb 100644
      --- a/assets/src_ranuts_sort_bucket_index.md.755536c3.lean.js
      +++ b/assets/src_ranuts_sort_bucket_index.md.39a1b5ca.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"桶排序 (Bucket Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/bucket/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/bucket/index.md"},o=l("",8),t=[o];function e(c,r,y,F,D,B){return n(),a("div",null,t)}const E=s(p,[["render",e]]);export{A as __pageData,E as default};
      +import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"桶排序 (Bucket Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/bucket/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/bucket/index.md"},o=l("",8),t=[o];function e(c,r,y,F,D,B){return n(),a("div",null,t)}const E=s(p,[["render",e]]);export{A as __pageData,E as default};
      diff --git a/assets/src_ranuts_sort_count_index.md.52dd4e7c.js b/assets/src_ranuts_sort_count_index.md.bcf7daeb.js
      similarity index 99%
      rename from assets/src_ranuts_sort_count_index.md.52dd4e7c.js
      rename to assets/src_ranuts_sort_count_index.md.bcf7daeb.js
      index e41f38456..b62008a3b 100644
      --- a/assets/src_ranuts_sort_count_index.md.52dd4e7c.js
      +++ b/assets/src_ranuts_sort_count_index.md.bcf7daeb.js
      @@ -1,4 +1,4 @@
      -import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/count.9e7ca98e.gif",E=JSON.parse('{"title":"计数排序( Count Sort )","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/count/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/count/index.md"},t=l('

      计数排序( Count Sort )

      计数排序(counting sort)就是一种牺牲内存空间来换取低时间复杂度的排序算法,同时它也是一种不基于比较的算法。这里的不基于比较指的是数组元素之间不存在比较大小的排序算法,我们知道,用分治法来解决排序问题最快也只能使算法的时间复杂度接近 Θ(nlogn),即基于比较的时间复杂度存在下界 Ω(nlog⁡n),而不基于比较的排序算法可以突破这一下界。

      算法描述

      • 找出待排序的数组中最大和最小的元素;
      • 统计数组中每个值为 i 的元素出现的次数,存入数组 C 的第 i 项;
      • 对所有的计数累加(从 C 中的第一个元素开始,每一项和前一项相加);
      • 反向填充目标数组:将每个元素 i 放在新数组的第 C(i)项,每放一个元素就将 C(i)减去 1。

      动图演示

      计数排序

      代码演示

      ts
      const getMax = (list: Array<number>) => {
      +import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/count.9e7ca98e.gif",E=JSON.parse('{"title":"计数排序( Count Sort )","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/count/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/count/index.md"},t=l('

      计数排序( Count Sort )

      计数排序(counting sort)就是一种牺牲内存空间来换取低时间复杂度的排序算法,同时它也是一种不基于比较的算法。这里的不基于比较指的是数组元素之间不存在比较大小的排序算法,我们知道,用分治法来解决排序问题最快也只能使算法的时间复杂度接近 Θ(nlogn),即基于比较的时间复杂度存在下界 Ω(nlog⁡n),而不基于比较的排序算法可以突破这一下界。

      算法描述

      • 找出待排序的数组中最大和最小的元素;
      • 统计数组中每个值为 i 的元素出现的次数,存入数组 C 的第 i 项;
      • 对所有的计数累加(从 C 中的第一个元素开始,每一项和前一项相加);
      • 反向填充目标数组:将每个元素 i 放在新数组的第 C(i)项,每放一个元素就将 C(i)减去 1。

      动图演示

      计数排序

      代码演示

      ts
      const getMax = (list: Array<number>) => {
         let max = list[0]
         for (let i = 0; i < list.length; i++) {
           if (max < list[i]) {
      diff --git a/assets/src_ranuts_sort_count_index.md.52dd4e7c.lean.js b/assets/src_ranuts_sort_count_index.md.bcf7daeb.lean.js
      similarity index 86%
      rename from assets/src_ranuts_sort_count_index.md.52dd4e7c.lean.js
      rename to assets/src_ranuts_sort_count_index.md.bcf7daeb.lean.js
      index 51ca3d867..2a5d6b8f7 100644
      --- a/assets/src_ranuts_sort_count_index.md.52dd4e7c.lean.js
      +++ b/assets/src_ranuts_sort_count_index.md.bcf7daeb.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/count.9e7ca98e.gif",E=JSON.parse('{"title":"计数排序( Count Sort )","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/count/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/count/index.md"},t=l("",10),e=[t];function c(r,y,F,D,i,B){return n(),a("div",null,e)}const f=s(p,[["render",c]]);export{E as __pageData,f as default};
      +import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/count.9e7ca98e.gif",E=JSON.parse('{"title":"计数排序( Count Sort )","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/count/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/count/index.md"},t=l("",10),e=[t];function c(r,y,F,D,i,B){return n(),a("div",null,e)}const f=s(p,[["render",c]]);export{E as __pageData,f as default};
      diff --git a/assets/src_ranuts_sort_heap_index.md.c3678584.js b/assets/src_ranuts_sort_heap_index.md.ed19bcdb.js
      similarity index 99%
      rename from assets/src_ranuts_sort_heap_index.md.c3678584.js
      rename to assets/src_ranuts_sort_heap_index.md.ed19bcdb.js
      index 19aa0ff5a..022aa3068 100644
      --- a/assets/src_ranuts_sort_heap_index.md.c3678584.js
      +++ b/assets/src_ranuts_sort_heap_index.md.ed19bcdb.js
      @@ -1,4 +1,4 @@
      -import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/heap.0c214e72.gif",E=JSON.parse('{"title":"堆排序(Heap Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/heap/index.md","lastUpdated":1694276611000}'),o={name:"src/ranuts/sort/heap/index.md"},t=l('

      堆排序(Heap Sort)

      堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

      算法描述

      • 将初始待排序关键字序列(R1,R2….Rn)构建成大顶堆,此堆为初始的无序区;
      • 将堆顶元素 R[1]与最后一个元素 R[n]交换,此时得到新的无序区(R1,R2,……Rn-1)和新的有序区(Rn),且满足 R[1,2…n-1]<=R[n];
      • 由于交换后新的堆顶 R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,……Rn-1)调整为新堆,然后再次将 R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2….Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为 n-1,则整个排序过程完成。
      • 升序用大根堆,降序用小根堆

      动图演示

      堆排序

      代码演示

      ts
      class Heap {
      +import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/heap.0c214e72.gif",E=JSON.parse('{"title":"堆排序(Heap Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/heap/index.md","lastUpdated":1694419899000}'),o={name:"src/ranuts/sort/heap/index.md"},t=l('

      堆排序(Heap Sort)

      堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

      算法描述

      • 将初始待排序关键字序列(R1,R2….Rn)构建成大顶堆,此堆为初始的无序区;
      • 将堆顶元素 R[1]与最后一个元素 R[n]交换,此时得到新的无序区(R1,R2,……Rn-1)和新的有序区(Rn),且满足 R[1,2…n-1]<=R[n];
      • 由于交换后新的堆顶 R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,……Rn-1)调整为新堆,然后再次将 R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2….Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为 n-1,则整个排序过程完成。
      • 升序用大根堆,降序用小根堆

      动图演示

      堆排序

      代码演示

      ts
      class Heap {
         arr: Array<number>
         size: number
         constructor(arr: Array<number>) {
      diff --git a/assets/src_ranuts_sort_heap_index.md.c3678584.lean.js b/assets/src_ranuts_sort_heap_index.md.ed19bcdb.lean.js
      similarity index 86%
      rename from assets/src_ranuts_sort_heap_index.md.c3678584.lean.js
      rename to assets/src_ranuts_sort_heap_index.md.ed19bcdb.lean.js
      index 8f75e55ae..90976a6cc 100644
      --- a/assets/src_ranuts_sort_heap_index.md.c3678584.lean.js
      +++ b/assets/src_ranuts_sort_heap_index.md.ed19bcdb.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/heap.0c214e72.gif",E=JSON.parse('{"title":"堆排序(Heap Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/heap/index.md","lastUpdated":1694276611000}'),o={name:"src/ranuts/sort/heap/index.md"},t=l("",8),e=[t];function r(c,y,F,D,B,i){return a(),n("div",null,e)}const h=s(o,[["render",r]]);export{E as __pageData,h as default};
      +import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const p="/ran/assets/heap.0c214e72.gif",E=JSON.parse('{"title":"堆排序(Heap Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/heap/index.md","lastUpdated":1694419899000}'),o={name:"src/ranuts/sort/heap/index.md"},t=l("",8),e=[t];function r(c,y,F,D,B,i){return a(),n("div",null,e)}const h=s(o,[["render",r]]);export{E as __pageData,h as default};
      diff --git a/assets/src_ranuts_sort_index.md.b7c48f70.js b/assets/src_ranuts_sort_index.md.fb0f8a4a.js
      similarity index 96%
      rename from assets/src_ranuts_sort_index.md.b7c48f70.js
      rename to assets/src_ranuts_sort_index.md.fb0f8a4a.js
      index 1a8cc21a3..ef3c4d670 100644
      --- a/assets/src_ranuts_sort_index.md.b7c48f70.js
      +++ b/assets/src_ranuts_sort_index.md.fb0f8a4a.js
      @@ -1 +1 @@
      -import{_ as t,o as a,c as s,N as e}from"./chunks/framework.6fe2e870.js";const r="/ran/assets/sort.0e02a465.png",n="/ran/assets/complexity.aded73a0.png",b=JSON.parse('{"title":"十大经典排序","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/index.md","lastUpdated":1694276611000}'),o={name:"src/ranuts/sort/index.md"},i=e('

      十大经典排序

      十种常见排序算法可以分为两大类:

      • 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破 O(nlogn),因此也称为非线性时间比较类排序。
      • 非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。 排序分类 0.2 算法复杂度

      算法复杂度 0.3 相关概念

      • 稳定:如果 a 原本在 b 前面,而 a=b,排序之后 a 仍然在 b 的前面。
      • 不稳定:如果 a 原本在 b 的前面,而 a=b,排序之后 a 可能会出现在 b 的后面。
      • 时间复杂度:对排序数据的总的操作次数。反映当 n 变化时,操作次数呈现什么规律。
      • 空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模 n 的函数。
      ',5),l=[i];function _(c,d,p,m,u,g){return a(),s("div",null,l)}const f=t(o,[["render",_]]);export{b as __pageData,f as default}; +import{_ as t,o as a,c as s,N as e}from"./chunks/framework.6fe2e870.js";const r="/ran/assets/sort.0e02a465.png",n="/ran/assets/complexity.aded73a0.png",b=JSON.parse('{"title":"十大经典排序","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/index.md","lastUpdated":1694419899000}'),o={name:"src/ranuts/sort/index.md"},i=e('

      十大经典排序

      十种常见排序算法可以分为两大类:

      • 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破 O(nlogn),因此也称为非线性时间比较类排序。
      • 非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。 排序分类 0.2 算法复杂度

      算法复杂度 0.3 相关概念

      • 稳定:如果 a 原本在 b 前面,而 a=b,排序之后 a 仍然在 b 的前面。
      • 不稳定:如果 a 原本在 b 的前面,而 a=b,排序之后 a 可能会出现在 b 的后面。
      • 时间复杂度:对排序数据的总的操作次数。反映当 n 变化时,操作次数呈现什么规律。
      • 空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模 n 的函数。
      ',5),l=[i];function _(c,d,p,m,u,g){return a(),s("div",null,l)}const f=t(o,[["render",_]]);export{b as __pageData,f as default}; diff --git a/assets/src_ranuts_sort_index.md.b7c48f70.lean.js b/assets/src_ranuts_sort_index.md.fb0f8a4a.lean.js similarity index 86% rename from assets/src_ranuts_sort_index.md.b7c48f70.lean.js rename to assets/src_ranuts_sort_index.md.fb0f8a4a.lean.js index bc4e93729..5d1032845 100644 --- a/assets/src_ranuts_sort_index.md.b7c48f70.lean.js +++ b/assets/src_ranuts_sort_index.md.fb0f8a4a.lean.js @@ -1 +1 @@ -import{_ as t,o as a,c as s,N as e}from"./chunks/framework.6fe2e870.js";const r="/ran/assets/sort.0e02a465.png",n="/ran/assets/complexity.aded73a0.png",b=JSON.parse('{"title":"十大经典排序","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/index.md","lastUpdated":1694276611000}'),o={name:"src/ranuts/sort/index.md"},i=e("",5),l=[i];function _(c,d,p,m,u,g){return a(),s("div",null,l)}const f=t(o,[["render",_]]);export{b as __pageData,f as default}; +import{_ as t,o as a,c as s,N as e}from"./chunks/framework.6fe2e870.js";const r="/ran/assets/sort.0e02a465.png",n="/ran/assets/complexity.aded73a0.png",b=JSON.parse('{"title":"十大经典排序","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/index.md","lastUpdated":1694419899000}'),o={name:"src/ranuts/sort/index.md"},i=e("",5),l=[i];function _(c,d,p,m,u,g){return a(),s("div",null,l)}const f=t(o,[["render",_]]);export{b as __pageData,f as default}; diff --git a/assets/src_ranuts_sort_insert_index.md.de43fe03.js b/assets/src_ranuts_sort_insert_index.md.032011a9.js similarity index 99% rename from assets/src_ranuts_sort_insert_index.md.de43fe03.js rename to assets/src_ranuts_sort_insert_index.md.032011a9.js index ade44178f..66c5d2805 100644 --- a/assets/src_ranuts_sort_insert_index.md.de43fe03.js +++ b/assets/src_ranuts_sort_insert_index.md.032011a9.js @@ -1,4 +1,4 @@ -import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/insert.4cd822c8.gif",A=JSON.parse('{"title":"插入排序(Insert Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/insert/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/insert/index.md"},t=l('

      插入排序(Insert Sort)

      表现稳定的排序算法,因为无论什么数据进去都是 O(n2)的时间复杂度,所以用到它的时候,数据规模越小越好。优点是不占用额外的内存空间。工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

      算法描述

      • 从第一个元素开始,该元素可以认为已经被排序;
      • 取出下一个元素,在已经排序的元素序列中从后向前扫描;
      • 如果该元素(已排序)大于新元素,将该元素移到下一位置;
      • 重复步骤 3,直到找到已排序的元素小于或者等于新元素的位置;
      • 将新元素插入到该位置后;
      • 重复步骤 2~5。

      动图演示

      插入排序

      代码演示

      ts
      const insert = (list: Array<string>): Array<string> => {
      +import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/insert.4cd822c8.gif",A=JSON.parse('{"title":"插入排序(Insert Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/insert/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/insert/index.md"},t=l('

      插入排序(Insert Sort)

      表现稳定的排序算法,因为无论什么数据进去都是 O(n2)的时间复杂度,所以用到它的时候,数据规模越小越好。优点是不占用额外的内存空间。工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

      算法描述

      • 从第一个元素开始,该元素可以认为已经被排序;
      • 取出下一个元素,在已经排序的元素序列中从后向前扫描;
      • 如果该元素(已排序)大于新元素,将该元素移到下一位置;
      • 重复步骤 3,直到找到已排序的元素小于或者等于新元素的位置;
      • 将新元素插入到该位置后;
      • 重复步骤 2~5。

      动图演示

      插入排序

      代码演示

      ts
      const insert = (list: Array<string>): Array<string> => {
         const { length } = list
         for (let i = 1; i < length; i++) {
           let preIndex = i - 1
      diff --git a/assets/src_ranuts_sort_insert_index.md.de43fe03.lean.js b/assets/src_ranuts_sort_insert_index.md.032011a9.lean.js
      similarity index 86%
      rename from assets/src_ranuts_sort_insert_index.md.de43fe03.lean.js
      rename to assets/src_ranuts_sort_insert_index.md.032011a9.lean.js
      index 75043e428..816123869 100644
      --- a/assets/src_ranuts_sort_insert_index.md.de43fe03.lean.js
      +++ b/assets/src_ranuts_sort_insert_index.md.032011a9.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/insert.4cd822c8.gif",A=JSON.parse('{"title":"插入排序(Insert Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/insert/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/insert/index.md"},t=l("",10),e=[t];function r(c,y,F,D,i,B){return a(),n("div",null,e)}const E=s(p,[["render",r]]);export{A as __pageData,E as default};
      +import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/insert.4cd822c8.gif",A=JSON.parse('{"title":"插入排序(Insert Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/insert/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/insert/index.md"},t=l("",10),e=[t];function r(c,y,F,D,i,B){return a(),n("div",null,e)}const E=s(p,[["render",r]]);export{A as __pageData,E as default};
      diff --git a/assets/src_ranuts_sort_merge_index.md.46e8a482.js b/assets/src_ranuts_sort_merge_index.md.d6dbf578.js
      similarity index 99%
      rename from assets/src_ranuts_sort_merge_index.md.46e8a482.js
      rename to assets/src_ranuts_sort_merge_index.md.d6dbf578.js
      index 2d383fd1c..c5e0fbdaa 100644
      --- a/assets/src_ranuts_sort_merge_index.md.46e8a482.js
      +++ b/assets/src_ranuts_sort_merge_index.md.d6dbf578.js
      @@ -1,4 +1,4 @@
      -import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/merge.7613b4a8.gif",E=JSON.parse('{"title":"归并排序(Merge Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/merge/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/merge/index.md"},t=l('

      归并排序(Merge Sort)

      归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为 2-路归并。

      算法描述

      • 把长度为 n 的输入序列分成两个长度为 n/2 的子序列;
      • 对这两个子序列分别采用归并排序;
      • 将两个排序好的子序列合并成一个最终的排序序列。

      动图演示

      归并排序

      代码演示

      ts
      const combine = (left: Array<number>, right: Array<number>) => {
      +import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/merge.7613b4a8.gif",E=JSON.parse('{"title":"归并排序(Merge Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/merge/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/merge/index.md"},t=l('

      归并排序(Merge Sort)

      归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为 2-路归并。

      算法描述

      • 把长度为 n 的输入序列分成两个长度为 n/2 的子序列;
      • 对这两个子序列分别采用归并排序;
      • 将两个排序好的子序列合并成一个最终的排序序列。

      动图演示

      归并排序

      代码演示

      ts
      const combine = (left: Array<number>, right: Array<number>) => {
         const list: Array<number> = []
         while (left.length > 0 && right.length > 0) {
           if (left[0] <= right[0]) {
      diff --git a/assets/src_ranuts_sort_merge_index.md.46e8a482.lean.js b/assets/src_ranuts_sort_merge_index.md.d6dbf578.lean.js
      similarity index 86%
      rename from assets/src_ranuts_sort_merge_index.md.46e8a482.lean.js
      rename to assets/src_ranuts_sort_merge_index.md.d6dbf578.lean.js
      index afdd210c7..92b82f2f3 100644
      --- a/assets/src_ranuts_sort_merge_index.md.46e8a482.lean.js
      +++ b/assets/src_ranuts_sort_merge_index.md.d6dbf578.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/merge.7613b4a8.gif",E=JSON.parse('{"title":"归并排序(Merge Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/merge/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/merge/index.md"},t=l("",10),e=[t];function c(r,y,F,D,i,B){return n(),a("div",null,e)}const f=s(p,[["render",c]]);export{E as __pageData,f as default};
      +import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/merge.7613b4a8.gif",E=JSON.parse('{"title":"归并排序(Merge Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/merge/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/merge/index.md"},t=l("",10),e=[t];function c(r,y,F,D,i,B){return n(),a("div",null,e)}const f=s(p,[["render",c]]);export{E as __pageData,f as default};
      diff --git a/assets/src_ranuts_sort_quick_index.md.9ea0bd8c.js b/assets/src_ranuts_sort_quick_index.md.3d358bda.js
      similarity index 99%
      rename from assets/src_ranuts_sort_quick_index.md.9ea0bd8c.js
      rename to assets/src_ranuts_sort_quick_index.md.3d358bda.js
      index d35f28d41..904aef841 100644
      --- a/assets/src_ranuts_sort_quick_index.md.9ea0bd8c.js
      +++ b/assets/src_ranuts_sort_quick_index.md.3d358bda.js
      @@ -1,4 +1,4 @@
      -import{_ as s,o as l,c as n,N as a}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/quick.e1c33863.gif",f=JSON.parse('{"title":"快速排序(Quick Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/quick/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/quick/index.md"},t=a('

      快速排序(Quick Sort)

      快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

      算法描述

      快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:

      • 从数列中挑出一个元素,称为 “基准”(pivot);
      • 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
      • 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

      动图演示

      快速排序

      代码演示

      ts
      /**
      +import{_ as s,o as l,c as n,N as a}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/quick.e1c33863.gif",f=JSON.parse('{"title":"快速排序(Quick Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/quick/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/quick/index.md"},t=a('

      快速排序(Quick Sort)

      快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

      算法描述

      快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:

      • 从数列中挑出一个元素,称为 “基准”(pivot);
      • 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
      • 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

      动图演示

      快速排序

      代码演示

      ts
      /**
        * @description: 设置基准值pivot
        * @param {Array} list
        * @param {number} left
      diff --git a/assets/src_ranuts_sort_quick_index.md.9ea0bd8c.lean.js b/assets/src_ranuts_sort_quick_index.md.3d358bda.lean.js
      similarity index 86%
      rename from assets/src_ranuts_sort_quick_index.md.9ea0bd8c.lean.js
      rename to assets/src_ranuts_sort_quick_index.md.3d358bda.lean.js
      index 3fa7cce49..982d085d8 100644
      --- a/assets/src_ranuts_sort_quick_index.md.9ea0bd8c.lean.js
      +++ b/assets/src_ranuts_sort_quick_index.md.3d358bda.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as l,c as n,N as a}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/quick.e1c33863.gif",f=JSON.parse('{"title":"快速排序(Quick Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/quick/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/quick/index.md"},t=a("",9),e=[t];function c(r,y,i,F,D,B){return l(),n("div",null,e)}const A=s(p,[["render",c]]);export{f as __pageData,A as default};
      +import{_ as s,o as l,c as n,N as a}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/quick.e1c33863.gif",f=JSON.parse('{"title":"快速排序(Quick Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/quick/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/quick/index.md"},t=a("",9),e=[t];function c(r,y,i,F,D,B){return l(),n("div",null,e)}const A=s(p,[["render",c]]);export{f as __pageData,A as default};
      diff --git a/assets/src_ranuts_sort_radix_index.md.45ded274.js b/assets/src_ranuts_sort_radix_index.md.55bb0018.js
      similarity index 99%
      rename from assets/src_ranuts_sort_radix_index.md.45ded274.js
      rename to assets/src_ranuts_sort_radix_index.md.55bb0018.js
      index 38bbbdac7..71286f9ef 100644
      --- a/assets/src_ranuts_sort_radix_index.md.45ded274.js
      +++ b/assets/src_ranuts_sort_radix_index.md.55bb0018.js
      @@ -1,4 +1,4 @@
      -import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/radix.101a451a.gif",E=JSON.parse('{"title":"基数排序(Radix Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/radix/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/radix/index.md"},t=l('

      基数排序(Radix Sort)

      基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。桶排序扩展,类似于指定桶排序按位数排序规则,同时能利用计数排序适用于小范围数的特点。

      算法描述

      • 取得数组中的最大数,并取得位数;
      • arr 为原始数组,从最低位开始取每个位组成 radix 数组;
      • 对 radix 进行计数排序(利用计数排序适用于小范围数的特点);

      动图演示

      基数排序

      代码演示

      ts
      const getMax = (list: Array<number>) => {
      +import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/radix.101a451a.gif",E=JSON.parse('{"title":"基数排序(Radix Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/radix/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/radix/index.md"},t=l('

      基数排序(Radix Sort)

      基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。桶排序扩展,类似于指定桶排序按位数排序规则,同时能利用计数排序适用于小范围数的特点。

      算法描述

      • 取得数组中的最大数,并取得位数;
      • arr 为原始数组,从最低位开始取每个位组成 radix 数组;
      • 对 radix 进行计数排序(利用计数排序适用于小范围数的特点);

      动图演示

      基数排序

      代码演示

      ts
      const getMax = (list: Array<number>) => {
         let max = list[0]
         for (let i = 0; i < list.length; i++) {
           if (max < list[i]) {
      diff --git a/assets/src_ranuts_sort_radix_index.md.45ded274.lean.js b/assets/src_ranuts_sort_radix_index.md.55bb0018.lean.js
      similarity index 86%
      rename from assets/src_ranuts_sort_radix_index.md.45ded274.lean.js
      rename to assets/src_ranuts_sort_radix_index.md.55bb0018.lean.js
      index 16a34e4ff..1c7b5b46e 100644
      --- a/assets/src_ranuts_sort_radix_index.md.45ded274.lean.js
      +++ b/assets/src_ranuts_sort_radix_index.md.55bb0018.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/radix.101a451a.gif",E=JSON.parse('{"title":"基数排序(Radix Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/radix/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/radix/index.md"},t=l("",11),e=[t];function c(r,y,F,D,i,B){return a(),n("div",null,e)}const d=s(p,[["render",c]]);export{E as __pageData,d as default};
      +import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/radix.101a451a.gif",E=JSON.parse('{"title":"基数排序(Radix Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/radix/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/radix/index.md"},t=l("",11),e=[t];function c(r,y,F,D,i,B){return a(),n("div",null,e)}const d=s(p,[["render",c]]);export{E as __pageData,d as default};
      diff --git a/assets/src_ranuts_sort_select_index.md.f91454eb.js b/assets/src_ranuts_sort_select_index.md.cb9012a3.js
      similarity index 99%
      rename from assets/src_ranuts_sort_select_index.md.f91454eb.js
      rename to assets/src_ranuts_sort_select_index.md.cb9012a3.js
      index 428a9b969..c561a8fb8 100644
      --- a/assets/src_ranuts_sort_select_index.md.f91454eb.js
      +++ b/assets/src_ranuts_sort_select_index.md.cb9012a3.js
      @@ -1,4 +1,4 @@
      -import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/select.5aa51d89.gif",E=JSON.parse('{"title":"选择排序(Selection Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/select/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/select/index.md"},e=l('

      选择排序(Selection Sort)

      选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

      算法描述

      n 个记录的直接选择排序可经过 n-1 趟直接选择排序得到有序结果。具体算法描述如下:

      • 初始状态:无序区为 R[1..n],有序区为空;
      • 第 i 趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为 R[1..i-1]和 R(i..n)。该趟排序从当前无序区中-选出关键字最小的记录 R[k],将它与无序区的第 1 个记录 R 交换,使 R[1..i]和 R[i+1..n)分别变为记录个数增加 1 个的新有序区和记录个数减少 1 个的新无序区;
      • n-1 趟结束,数组有序化了。

      动图演示

      选择排序

      代码实现

      js
      function selectionSort(arr) {
      +import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/select.5aa51d89.gif",E=JSON.parse('{"title":"选择排序(Selection Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/select/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/select/index.md"},e=l('

      选择排序(Selection Sort)

      选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

      算法描述

      n 个记录的直接选择排序可经过 n-1 趟直接选择排序得到有序结果。具体算法描述如下:

      • 初始状态:无序区为 R[1..n],有序区为空;
      • 第 i 趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为 R[1..i-1]和 R(i..n)。该趟排序从当前无序区中-选出关键字最小的记录 R[k],将它与无序区的第 1 个记录 R 交换,使 R[1..i]和 R[i+1..n)分别变为记录个数增加 1 个的新有序区和记录个数减少 1 个的新无序区;
      • n-1 趟结束,数组有序化了。

      动图演示

      选择排序

      代码实现

      js
      function selectionSort(arr) {
         var len = arr.length
         var minIndex, temp
         for (var i = 0; i < len - 1; i++) {
      diff --git a/assets/src_ranuts_sort_select_index.md.f91454eb.lean.js b/assets/src_ranuts_sort_select_index.md.cb9012a3.lean.js
      similarity index 86%
      rename from assets/src_ranuts_sort_select_index.md.f91454eb.lean.js
      rename to assets/src_ranuts_sort_select_index.md.cb9012a3.lean.js
      index fffde6444..399e9a312 100644
      --- a/assets/src_ranuts_sort_select_index.md.f91454eb.lean.js
      +++ b/assets/src_ranuts_sort_select_index.md.cb9012a3.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/select.5aa51d89.gif",E=JSON.parse('{"title":"选择排序(Selection Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/select/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/select/index.md"},e=l("",11),t=[e];function r(c,y,F,i,D,B){return a(),n("div",null,t)}const d=s(p,[["render",r]]);export{E as __pageData,d as default};
      +import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/select.5aa51d89.gif",E=JSON.parse('{"title":"选择排序(Selection Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/select/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/select/index.md"},e=l("",11),t=[e];function r(c,y,F,i,D,B){return a(),n("div",null,t)}const d=s(p,[["render",r]]);export{E as __pageData,d as default};
      diff --git a/assets/src_ranuts_sort_shell_index.md.fb9ca14b.js b/assets/src_ranuts_sort_shell_index.md.11a9ac10.js
      similarity index 99%
      rename from assets/src_ranuts_sort_shell_index.md.fb9ca14b.js
      rename to assets/src_ranuts_sort_shell_index.md.11a9ac10.js
      index 25412dc38..34e74bca5 100644
      --- a/assets/src_ranuts_sort_shell_index.md.fb9ca14b.js
      +++ b/assets/src_ranuts_sort_shell_index.md.11a9ac10.js
      @@ -1,4 +1,4 @@
      -import{_ as s,o as a,c as l,N as n}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/shell.7f63988c.gif",E=JSON.parse('{"title":"希尔排序(Shell Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/shell/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/shell/index.md"},t=n('

      希尔排序(Shell Sort)

      1959 年 Shell 发明,第一个突破 O(n2)的排序算法,是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。

      算法描述

      先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述:

      • 选择一个增量序列 t1,t2,…,tk,其中 ti>tj,tk=1;
      • 按增量序列个数 k,对序列进行 k 趟排序;
      • 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

      动图演示

      希尔排序

      代码实现

      js
      /**
      +import{_ as s,o as a,c as l,N as n}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/shell.7f63988c.gif",E=JSON.parse('{"title":"希尔排序(Shell Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/shell/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/shell/index.md"},t=n('

      希尔排序(Shell Sort)

      1959 年 Shell 发明,第一个突破 O(n2)的排序算法,是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。

      算法描述

      先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述:

      • 选择一个增量序列 t1,t2,…,tk,其中 ti>tj,tk=1;
      • 按增量序列个数 k,对序列进行 k 趟排序;
      • 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

      动图演示

      希尔排序

      代码实现

      js
      /**
        * @description: 希尔排序,是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。
        * @param {Array} list
        * @return {Array}
      diff --git a/assets/src_ranuts_sort_shell_index.md.fb9ca14b.lean.js b/assets/src_ranuts_sort_shell_index.md.11a9ac10.lean.js
      similarity index 86%
      rename from assets/src_ranuts_sort_shell_index.md.fb9ca14b.lean.js
      rename to assets/src_ranuts_sort_shell_index.md.11a9ac10.lean.js
      index 296a23719..4152ec4a6 100644
      --- a/assets/src_ranuts_sort_shell_index.md.fb9ca14b.lean.js
      +++ b/assets/src_ranuts_sort_shell_index.md.11a9ac10.lean.js
      @@ -1 +1 @@
      -import{_ as s,o as a,c as l,N as n}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/shell.7f63988c.gif",E=JSON.parse('{"title":"希尔排序(Shell Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/shell/index.md","lastUpdated":1694276611000}'),p={name:"src/ranuts/sort/shell/index.md"},t=n("",11),e=[t];function c(r,y,F,D,i,B){return a(),l("div",null,e)}const h=s(p,[["render",c]]);export{E as __pageData,h as default};
      +import{_ as s,o as a,c as l,N as n}from"./chunks/framework.6fe2e870.js";const o="/ran/assets/shell.7f63988c.gif",E=JSON.parse('{"title":"希尔排序(Shell Sort)","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/sort/shell/index.md","lastUpdated":1694419899000}'),p={name:"src/ranuts/sort/shell/index.md"},t=n("",11),e=[t];function c(r,y,F,D,i,B){return a(),l("div",null,e)}const h=s(p,[["render",c]]);export{E as __pageData,h as default};
      diff --git a/assets/src_ranuts_utils_index.md.0a4014cb.js b/assets/src_ranuts_utils_index.md.5d834957.js
      similarity index 97%
      rename from assets/src_ranuts_utils_index.md.0a4014cb.js
      rename to assets/src_ranuts_utils_index.md.5d834957.js
      index fcddc8783..f17eb807a 100644
      --- a/assets/src_ranuts_utils_index.md.0a4014cb.js
      +++ b/assets/src_ranuts_utils_index.md.5d834957.js
      @@ -1 +1 @@
      -import{_ as t,o as e,c as d,N as a}from"./chunks/framework.6fe2e870.js";const p=JSON.parse('{"title":"通用函数","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/utils/index.md","lastUpdated":1694276611000}'),r={name:"src/ranuts/utils/index.md"},o=a('

      通用函数

      filterObj

      过滤对象的属性,去除对象中在 list 数组里面有的属性,返回一个新对象,一般是用于去除空字符和 null

      API

      Return

      参数说明类型
      run启动轮询(...params: TParams) => void
      runAsync启动轮询(...params: TParams) => Promise<TData>
      cancel停止轮询() => void

      Options

      参数说明类型默认值
      pollingInterval轮询间隔,单位为毫秒。如果值大于 0,则启动轮询模式。number0
      pollingWhenHidden在页面隐藏时,是否继续轮询。如果设置为 false,在页面隐藏时会暂时停止轮询,页面重新显示时继续上次轮询。booleantrue
      pollingErrorRetryCount轮询错误重试次数。如果设置为 -1,则无限次number-1
      ',8),n=[o];function i(l,c,s,h,u,_){return e(),d("div",null,n)}const m=t(r,[["render",i]]);export{p as __pageData,m as default}; +import{_ as t,o as e,c as d,N as a}from"./chunks/framework.6fe2e870.js";const p=JSON.parse('{"title":"通用函数","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/utils/index.md","lastUpdated":1694419899000}'),r={name:"src/ranuts/utils/index.md"},o=a('

      通用函数

      filterObj

      过滤对象的属性,去除对象中在 list 数组里面有的属性,返回一个新对象,一般是用于去除空字符和 null

      API

      Return

      参数说明类型
      run启动轮询(...params: TParams) => void
      runAsync启动轮询(...params: TParams) => Promise<TData>
      cancel停止轮询() => void

      Options

      参数说明类型默认值
      pollingInterval轮询间隔,单位为毫秒。如果值大于 0,则启动轮询模式。number0
      pollingWhenHidden在页面隐藏时,是否继续轮询。如果设置为 false,在页面隐藏时会暂时停止轮询,页面重新显示时继续上次轮询。booleantrue
      pollingErrorRetryCount轮询错误重试次数。如果设置为 -1,则无限次number-1
      ',8),n=[o];function i(l,c,s,h,u,_){return e(),d("div",null,n)}const m=t(r,[["render",i]]);export{p as __pageData,m as default}; diff --git a/assets/src_ranuts_utils_index.md.0a4014cb.lean.js b/assets/src_ranuts_utils_index.md.5d834957.lean.js similarity index 84% rename from assets/src_ranuts_utils_index.md.0a4014cb.lean.js rename to assets/src_ranuts_utils_index.md.5d834957.lean.js index 99bb1d02d..bf6158ce8 100644 --- a/assets/src_ranuts_utils_index.md.0a4014cb.lean.js +++ b/assets/src_ranuts_utils_index.md.5d834957.lean.js @@ -1 +1 @@ -import{_ as t,o as e,c as d,N as a}from"./chunks/framework.6fe2e870.js";const p=JSON.parse('{"title":"通用函数","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/utils/index.md","lastUpdated":1694276611000}'),r={name:"src/ranuts/utils/index.md"},o=a("",8),n=[o];function i(l,c,s,h,u,_){return e(),d("div",null,n)}const m=t(r,[["render",i]]);export{p as __pageData,m as default}; +import{_ as t,o as e,c as d,N as a}from"./chunks/framework.6fe2e870.js";const p=JSON.parse('{"title":"通用函数","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/utils/index.md","lastUpdated":1694419899000}'),r={name:"src/ranuts/utils/index.md"},o=a("",8),n=[o];function i(l,c,s,h,u,_){return e(),d("div",null,n)}const m=t(r,[["render",i]]);export{p as __pageData,m as default}; diff --git a/assets/src_ranuts_utils_task.md.71af1297.js b/assets/src_ranuts_utils_task.md.5c6e5a88.js similarity index 99% rename from assets/src_ranuts_utils_task.md.71af1297.js rename to assets/src_ranuts_utils_task.md.5c6e5a88.js index 30c0a0e1e..4767d35fe 100644 --- a/assets/src_ranuts_utils_task.md.71af1297.js +++ b/assets/src_ranuts_utils_task.md.5c6e5a88.js @@ -1 +1 @@ -import{_ as e,o as a,c as t,N as o}from"./chunks/framework.6fe2e870.js";const k=JSON.parse('{"title":"统计执行时间","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/utils/task.md","lastUpdated":1694276611000}'),s={name:"src/ranuts/utils/task.md"},n=o('

      统计执行时间

      有的时候,我们需要统计一个函数的执行时间,用于分析性能。因此封装了startTasktaskEnd函数。同时介绍其他三种统计方法

      1. new Date().getTime(),
      2. console.time()console.timeEnd(),
      3. performance.now()

      一.startTask,taskEnd

      1.startTask

      任务开始之前执行

      Return

      参数说明类型
      taskId任务标识unique symbol

      2.taskEnd

      任务结束的时候执行,需要传入startTask返回的任务标识

      Options

      参数说明类型默认值
      taskId任务标识unique symbol 无默认值,参数必传,否则无法识别是哪个任务

      Return

      参数说明类型
      timetask执行的时间number

      3.使用例子

      js
      const taskId = startTask()\n\n// do something\n\nconst time = taskEnd(taskId)\n\nconsole.log('task 执行花费的时间', time)

      二.new Date().getTime()

      new Date().getTime() 返回一个数值,表示从 1970 年 1 月 1 日 0 时 0 分 0 秒(UTC,即协调世界时)距离该日期对象所代表时间的毫秒数。用来计算 JS 执行时间会有两个问题:

      1. 某些情况下,毫秒级精度可能不够。
      2. new Date() 解析的时间在不同浏览器,或者不同设备上可能并不一致。MDN 说明

        由于浏览器之间的差异与不一致性,强烈不推荐使用 Date 构造函数来解析日期字符串 (或使用与其等价的 Date.parse)。对 RFC 2822 格式的日期仅有约定俗成的支持。对 ISO 8601 格式的支持中,仅有日期的串 (例如 "1970-01-01") 会被处理为 UTC 而不是本地时间,与其他格式的串的处理不同。

      三.console.time(), console.timeEnd()

      启动一个计时器来跟踪某一个操作的占用时长。每一个计时器必须拥有唯一的名字,页面中最多能同时运行 10,000 个计时器。当以此计时器名字为参数调用 console.timeEnd() 时,浏览器将以毫秒为单位,输出对应计时器所经过的时间。比起new Date().getTime(),统计时间更加精确,可以统计到 0.001 毫秒(比如:0.134ms)

      四.performance.now()

      performance.now()返回的时间精度最高可达微秒级,且不会受到系统时间的影响(系统时钟可能会被手动调整或被 NTP 等软件篡改)。另外,performance.timing.navigationStart + performance.now() 约等于 Date.now()。因此对于统计 JS 执行耗时方面,更推荐使用performance.now()

      注意:为了提供对定时攻击和指纹的保护,performance.now() 的精度可能会根据浏览器的设置而被舍弃。 在 Firefox 中,privacy.reduceTimerPrecision 偏好是默认启用的,默认值为 1ms。可以启用 privacy.resistFingerprinting 这将精度改为 100ms 或privacy.resistFingerprinting.reduceTimerPrecision.microseconds 的值,以较大者为准。

      ',24),r=[n];function c(d,l,i,p,h,m){return a(),t("div",null,r)}const b=e(s,[["render",c]]);export{k as __pageData,b as default}; +import{_ as e,o as a,c as t,N as o}from"./chunks/framework.6fe2e870.js";const k=JSON.parse('{"title":"统计执行时间","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/utils/task.md","lastUpdated":1694419899000}'),s={name:"src/ranuts/utils/task.md"},n=o('

      统计执行时间

      有的时候,我们需要统计一个函数的执行时间,用于分析性能。因此封装了startTasktaskEnd函数。同时介绍其他三种统计方法

      1. new Date().getTime(),
      2. console.time()console.timeEnd(),
      3. performance.now()

      一.startTask,taskEnd

      1.startTask

      任务开始之前执行

      Return

      参数说明类型
      taskId任务标识unique symbol

      2.taskEnd

      任务结束的时候执行,需要传入startTask返回的任务标识

      Options

      参数说明类型默认值
      taskId任务标识unique symbol 无默认值,参数必传,否则无法识别是哪个任务

      Return

      参数说明类型
      timetask执行的时间number

      3.使用例子

      js
      const taskId = startTask()\n\n// do something\n\nconst time = taskEnd(taskId)\n\nconsole.log('task 执行花费的时间', time)

      二.new Date().getTime()

      new Date().getTime() 返回一个数值,表示从 1970 年 1 月 1 日 0 时 0 分 0 秒(UTC,即协调世界时)距离该日期对象所代表时间的毫秒数。用来计算 JS 执行时间会有两个问题:

      1. 某些情况下,毫秒级精度可能不够。
      2. new Date() 解析的时间在不同浏览器,或者不同设备上可能并不一致。MDN 说明

        由于浏览器之间的差异与不一致性,强烈不推荐使用 Date 构造函数来解析日期字符串 (或使用与其等价的 Date.parse)。对 RFC 2822 格式的日期仅有约定俗成的支持。对 ISO 8601 格式的支持中,仅有日期的串 (例如 "1970-01-01") 会被处理为 UTC 而不是本地时间,与其他格式的串的处理不同。

      三.console.time(), console.timeEnd()

      启动一个计时器来跟踪某一个操作的占用时长。每一个计时器必须拥有唯一的名字,页面中最多能同时运行 10,000 个计时器。当以此计时器名字为参数调用 console.timeEnd() 时,浏览器将以毫秒为单位,输出对应计时器所经过的时间。比起new Date().getTime(),统计时间更加精确,可以统计到 0.001 毫秒(比如:0.134ms)

      四.performance.now()

      performance.now()返回的时间精度最高可达微秒级,且不会受到系统时间的影响(系统时钟可能会被手动调整或被 NTP 等软件篡改)。另外,performance.timing.navigationStart + performance.now() 约等于 Date.now()。因此对于统计 JS 执行耗时方面,更推荐使用performance.now()

      注意:为了提供对定时攻击和指纹的保护,performance.now() 的精度可能会根据浏览器的设置而被舍弃。 在 Firefox 中,privacy.reduceTimerPrecision 偏好是默认启用的,默认值为 1ms。可以启用 privacy.resistFingerprinting 这将精度改为 100ms 或privacy.resistFingerprinting.reduceTimerPrecision.microseconds 的值,以较大者为准。

      ',24),r=[n];function c(d,l,i,p,h,m){return a(),t("div",null,r)}const b=e(s,[["render",c]]);export{k as __pageData,b as default}; diff --git a/assets/src_ranuts_utils_task.md.71af1297.lean.js b/assets/src_ranuts_utils_task.md.5c6e5a88.lean.js similarity index 84% rename from assets/src_ranuts_utils_task.md.71af1297.lean.js rename to assets/src_ranuts_utils_task.md.5c6e5a88.lean.js index 5af208fdb..b8114a33f 100644 --- a/assets/src_ranuts_utils_task.md.71af1297.lean.js +++ b/assets/src_ranuts_utils_task.md.5c6e5a88.lean.js @@ -1 +1 @@ -import{_ as e,o as a,c as t,N as o}from"./chunks/framework.6fe2e870.js";const k=JSON.parse('{"title":"统计执行时间","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/utils/task.md","lastUpdated":1694276611000}'),s={name:"src/ranuts/utils/task.md"},n=o("",24),r=[n];function c(d,l,i,p,h,m){return a(),t("div",null,r)}const b=e(s,[["render",c]]);export{k as __pageData,b as default}; +import{_ as e,o as a,c as t,N as o}from"./chunks/framework.6fe2e870.js";const k=JSON.parse('{"title":"统计执行时间","description":"","frontmatter":{},"headers":[],"relativePath":"src/ranuts/utils/task.md","lastUpdated":1694419899000}'),s={name:"src/ranuts/utils/task.md"},n=o("",24),r=[n];function c(d,l,i,p,h,m){return a(),t("div",null,r)}const b=e(s,[["render",c]]);export{k as __pageData,b as default}; diff --git "a/assets/src_types_TS\347\261\273\345\236\213.md.c98631f5.js" "b/assets/src_types_TS\347\261\273\345\236\213.md.7ed2f3b0.js" similarity index 99% rename from "assets/src_types_TS\347\261\273\345\236\213.md.c98631f5.js" rename to "assets/src_types_TS\347\261\273\345\236\213.md.7ed2f3b0.js" index 93e759ca2..31d3115fe 100644 --- "a/assets/src_types_TS\347\261\273\345\236\213.md.c98631f5.js" +++ "b/assets/src_types_TS\347\261\273\345\236\213.md.7ed2f3b0.js" @@ -1,4 +1,4 @@ -import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"TypeScript 类型系统中的类型","description":"","frontmatter":{},"headers":[],"relativePath":"src/types/TS类型.md","lastUpdated":1694276611000}'),p={name:"src/types/TS类型.md"},o=l(`

      TypeScript 类型系统中的类型

      1. 基本类型: number、boolean、string、object、bigint、symbol、undefined、null
      2. 复合类型: class、Array、元组(Tuple)、接口(Interface)、枚举(Enum)
      3. 特殊的类型:void、never、any、unknown

      Tuple

      元组(Tuple)就是元素个数和类型固定的数组类型:

      ts
      type Tuple = [number, string]

      Interface

      接口(Interface)可以描述函数、对象、构造器的结构:

      • 对象
      ts
      interface IPerson {
      +import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"TypeScript 类型系统中的类型","description":"","frontmatter":{},"headers":[],"relativePath":"src/types/TS类型.md","lastUpdated":1694419899000}'),p={name:"src/types/TS类型.md"},o=l(`

      TypeScript 类型系统中的类型

      1. 基本类型: number、boolean、string、object、bigint、symbol、undefined、null
      2. 复合类型: class、Array、元组(Tuple)、接口(Interface)、枚举(Enum)
      3. 特殊的类型:void、never、any、unknown

      Tuple

      元组(Tuple)就是元素个数和类型固定的数组类型:

      ts
      type Tuple = [number, string]

      Interface

      接口(Interface)可以描述函数、对象、构造器的结构:

      • 对象
      ts
      interface IPerson {
         name: string
         age: number
       }
      diff --git "a/assets/src_types_TS\347\261\273\345\236\213.md.c98631f5.lean.js" "b/assets/src_types_TS\347\261\273\345\236\213.md.7ed2f3b0.lean.js"
      similarity index 84%
      rename from "assets/src_types_TS\347\261\273\345\236\213.md.c98631f5.lean.js"
      rename to "assets/src_types_TS\347\261\273\345\236\213.md.7ed2f3b0.lean.js"
      index 66930b6d7..6e79b136c 100644
      --- "a/assets/src_types_TS\347\261\273\345\236\213.md.c98631f5.lean.js"
      +++ "b/assets/src_types_TS\347\261\273\345\236\213.md.7ed2f3b0.lean.js"
      @@ -1 +1 @@
      -import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"TypeScript 类型系统中的类型","description":"","frontmatter":{},"headers":[],"relativePath":"src/types/TS类型.md","lastUpdated":1694276611000}'),p={name:"src/types/TS类型.md"},o=l("",33),e=[o];function t(c,r,y,D,F,B){return a(),n("div",null,e)}const A=s(p,[["render",t]]);export{E as __pageData,A as default};
      +import{_ as s,o as a,c as n,N as l}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"TypeScript 类型系统中的类型","description":"","frontmatter":{},"headers":[],"relativePath":"src/types/TS类型.md","lastUpdated":1694419899000}'),p={name:"src/types/TS类型.md"},o=l("",33),e=[o];function t(c,r,y,D,F,B){return a(),n("div",null,e)}const A=s(p,[["render",t]]);export{E as __pageData,A as default};
      diff --git "a/assets/src_types_\346\250\241\345\274\217\345\214\271\351\205\215.md.78b179d7.js" "b/assets/src_types_\346\250\241\345\274\217\345\214\271\351\205\215.md.c289dbd1.js"
      similarity index 99%
      rename from "assets/src_types_\346\250\241\345\274\217\345\214\271\351\205\215.md.78b179d7.js"
      rename to "assets/src_types_\346\250\241\345\274\217\345\214\271\351\205\215.md.c289dbd1.js"
      index 1522f2e36..25aec7e12 100644
      --- "a/assets/src_types_\346\250\241\345\274\217\345\214\271\351\205\215.md.78b179d7.js"
      +++ "b/assets/src_types_\346\250\241\345\274\217\345\214\271\351\205\215.md.c289dbd1.js"
      @@ -1,4 +1,4 @@
      -import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"模式匹配","description":"","frontmatter":{},"headers":[],"relativePath":"src/types/模式匹配.md","lastUpdated":1694276611000}'),p={name:"src/types/模式匹配.md"},o=l(`

      模式匹配

      Typescript 的类型也同样可以做模式匹配。

      比如这样一个 Promise 类型:

      ts
      type p = Promise<'value'>

      我们想提取 value 的类型,可以这样做:

      ts
      type GetPromiseValue<T> = T extends Promise<infer value> ? value : never

      通过 extends 对传入的类型参数 P 做模式匹配,其中值的类型是需要提取的,通过 infer 声明一个局部变量 Value 来保存,如果匹配,就返回匹配到的 Value,否则就返回 never 代表没匹配到。

      ts
      type result = GetPromiseValue<Promise<'name'>> // name

      数组类型

      数组类型想提取第一个元素的类型怎么做呢?

      ts
      type arr = [1, 2, 3]

      用它来匹配一个模式类型,提取第一个元素的类型到通过 infer 声明的局部变量里返回。

      ts
      type GetArrayFirstItem<T extends unknown[]> = T extends [
      +import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"模式匹配","description":"","frontmatter":{},"headers":[],"relativePath":"src/types/模式匹配.md","lastUpdated":1694419899000}'),p={name:"src/types/模式匹配.md"},o=l(`

      模式匹配

      Typescript 的类型也同样可以做模式匹配。

      比如这样一个 Promise 类型:

      ts
      type p = Promise<'value'>

      我们想提取 value 的类型,可以这样做:

      ts
      type GetPromiseValue<T> = T extends Promise<infer value> ? value : never

      通过 extends 对传入的类型参数 P 做模式匹配,其中值的类型是需要提取的,通过 infer 声明一个局部变量 Value 来保存,如果匹配,就返回匹配到的 Value,否则就返回 never 代表没匹配到。

      ts
      type result = GetPromiseValue<Promise<'name'>> // name

      数组类型

      数组类型想提取第一个元素的类型怎么做呢?

      ts
      type arr = [1, 2, 3]

      用它来匹配一个模式类型,提取第一个元素的类型到通过 infer 声明的局部变量里返回。

      ts
      type GetArrayFirstItem<T extends unknown[]> = T extends [
         infer value,
         ...unknown[],
       ]
      diff --git "a/assets/src_types_\346\250\241\345\274\217\345\214\271\351\205\215.md.78b179d7.lean.js" "b/assets/src_types_\346\250\241\345\274\217\345\214\271\351\205\215.md.c289dbd1.lean.js"
      similarity index 84%
      rename from "assets/src_types_\346\250\241\345\274\217\345\214\271\351\205\215.md.78b179d7.lean.js"
      rename to "assets/src_types_\346\250\241\345\274\217\345\214\271\351\205\215.md.c289dbd1.lean.js"
      index 3e3901689..9862a428f 100644
      --- "a/assets/src_types_\346\250\241\345\274\217\345\214\271\351\205\215.md.78b179d7.lean.js"
      +++ "b/assets/src_types_\346\250\241\345\274\217\345\214\271\351\205\215.md.c289dbd1.lean.js"
      @@ -1 +1 @@
      -import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"模式匹配","description":"","frontmatter":{},"headers":[],"relativePath":"src/types/模式匹配.md","lastUpdated":1694276611000}'),p={name:"src/types/模式匹配.md"},o=l("",79),e=[o];function t(r,c,B,y,F,D){return n(),a("div",null,e)}const E=s(p,[["render",t]]);export{A as __pageData,E as default};
      +import{_ as s,o as n,c as a,N as l}from"./chunks/framework.6fe2e870.js";const A=JSON.parse('{"title":"模式匹配","description":"","frontmatter":{},"headers":[],"relativePath":"src/types/模式匹配.md","lastUpdated":1694419899000}'),p={name:"src/types/模式匹配.md"},o=l("",79),e=[o];function t(r,c,B,y,F,D){return n(),a("div",null,e)}const E=s(p,[["render",t]]);export{A as __pageData,E as default};
      diff --git "a/assets/src_types_\347\261\273\345\236\213\350\277\220\347\256\227.md.78b341b5.js" "b/assets/src_types_\347\261\273\345\236\213\350\277\220\347\256\227.md.bb1f0e32.js"
      similarity index 99%
      rename from "assets/src_types_\347\261\273\345\236\213\350\277\220\347\256\227.md.78b341b5.js"
      rename to "assets/src_types_\347\261\273\345\236\213\350\277\220\347\256\227.md.bb1f0e32.js"
      index 72fe0d59e..3e0bae4b9 100644
      --- "a/assets/src_types_\347\261\273\345\236\213\350\277\220\347\256\227.md.78b341b5.js"
      +++ "b/assets/src_types_\347\261\273\345\236\213\350\277\220\347\256\227.md.bb1f0e32.js"
      @@ -1,4 +1,4 @@
      -import{_ as s,o as a,c as n,N as p}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"TypeScript 类型系统中的类型运算","description":"","frontmatter":{},"headers":[],"relativePath":"src/types/类型运算.md","lastUpdated":1694276611000}'),l={name:"src/types/类型运算.md"},o=p(`

      TypeScript 类型系统中的类型运算

      条件:extends ? :

      TypeScript 里的条件判断是 extends ? :,叫做条件类型(Conditional Type)比如:

      ts
      type isTwo<T> = T extends 2 ? true : false
      +import{_ as s,o as a,c as n,N as p}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"TypeScript 类型系统中的类型运算","description":"","frontmatter":{},"headers":[],"relativePath":"src/types/类型运算.md","lastUpdated":1694419899000}'),l={name:"src/types/类型运算.md"},o=p(`

      TypeScript 类型系统中的类型运算

      条件:extends ? :

      TypeScript 里的条件判断是 extends ? :,叫做条件类型(Conditional Type)比如:

      ts
      type isTwo<T> = T extends 2 ? true : false
       
       type res = isTwo<1> // true
       type res2 = isTwo<2> // false

      这种类型也叫做高级类型。

      高级类型的特点是传入类型参数,经过一系列类型运算逻辑后,返回新的类型。

      推导:infer

      如何提取类型的一部分呢?答案是 infer。

      比如提取元组类型的第一个元素:

      ts
      type FirstTupleItem<Tuple extends unknown[]> = Tuple extends [infer T, ...inter R] ? T : never;
      diff --git "a/assets/src_types_\347\261\273\345\236\213\350\277\220\347\256\227.md.78b341b5.lean.js" "b/assets/src_types_\347\261\273\345\236\213\350\277\220\347\256\227.md.bb1f0e32.lean.js"
      similarity index 70%
      rename from "assets/src_types_\347\261\273\345\236\213\350\277\220\347\256\227.md.78b341b5.lean.js"
      rename to "assets/src_types_\347\261\273\345\236\213\350\277\220\347\256\227.md.bb1f0e32.lean.js"
      index 4a010428d..9fae5e705 100644
      --- "a/assets/src_types_\347\261\273\345\236\213\350\277\220\347\256\227.md.78b341b5.lean.js"
      +++ "b/assets/src_types_\347\261\273\345\236\213\350\277\220\347\256\227.md.bb1f0e32.lean.js"
      @@ -1 +1 @@
      -import{_ as s,o as a,c as n,N as p}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"TypeScript 类型系统中的类型运算","description":"","frontmatter":{},"headers":[],"relativePath":"src/types/类型运算.md","lastUpdated":1694276611000}'),l={name:"src/types/类型运算.md"},o=p("",35),e=[o];function t(c,r,y,B,F,D){return a(),n("div",null,e)}const A=s(l,[["render",t]]);export{E as __pageData,A as default};
      +import{_ as s,o as a,c as n,N as p}from"./chunks/framework.6fe2e870.js";const E=JSON.parse('{"title":"TypeScript 类型系统中的类型运算","description":"","frontmatter":{},"headers":[],"relativePath":"src/types/类型运算.md","lastUpdated":1694419899000}'),l={name:"src/types/类型运算.md"},o=p("",35),e=[o];function t(c,r,y,B,F,D){return a(),n("div",null,e)}const A=s(l,[["render",t]]);export{E as __pageData,A as default};
      diff --git "a/assets/src_types_\351\253\230\347\272\247\347\261\273\345\236\213.md.1ffcb487.js" "b/assets/src_types_\351\253\230\347\272\247\347\261\273\345\236\213.md.3ad1299c.js"
      similarity index 98%
      rename from "assets/src_types_\351\253\230\347\272\247\347\261\273\345\236\213.md.1ffcb487.js"
      rename to "assets/src_types_\351\253\230\347\272\247\347\261\273\345\236\213.md.3ad1299c.js"
      index 8c33c7924..2688531f9 100644
      --- "a/assets/src_types_\351\253\230\347\272\247\347\261\273\345\236\213.md.1ffcb487.js"
      +++ "b/assets/src_types_\351\253\230\347\272\247\347\261\273\345\236\213.md.3ad1299c.js"
      @@ -1 +1 @@
      -import{_ as a,o as e,c as r,N as t}from"./chunks/framework.6fe2e870.js";const b=JSON.parse('{"title":"TypeScript 内置的高级类型","description":"","frontmatter":{},"headers":[],"relativePath":"src/types/高级类型.md","lastUpdated":1694276611000}'),i={name:"src/types/高级类型.md"},o=t('

      TypeScript 内置的高级类型

      Parameters

      Parameters 用于提取函数类型的参数类型。

      ReturnType

      ReturnType 用于提取函数类型的返回值类型。

      ConstructorParameters

      构造器类型和函数类型的区别就是可以被 new。

      Parameters 用于提取函数参数的类型,而 ConstructorParameters 用于提取构造器参数的类型。

      InstanceType

      提取了构造器参数的类型,自然也可以提取构造器返回值的类型,就是 InstanceType。

      ThisParameterType

      OmitThisParameter

      Partial

      Required

      Readonly

      Pick

      Record

      Exclude

      Extract

      Omit

      Awaited

      NonNullable

      Uppercase

      Lowercase

      Capitalize

      Uncapitalize

      总结

      比如用模式匹配可以实现:Parameters、ReturnType、ConstructorParameters、InstanceType、ThisParameterType。

      用模式匹配 + 重新构造可以实现:OmitThisParameter

      用重新构造可以实现:Partial、Required、Readonly、Pick、Record

      用模式匹配 + 递归可以实现: Awaited

      用联合类型在分布式条件类型的特性可以实现: Exclude

      此外还有 NonNullable 和四个编译器内部实现的类型:Uppercase、Lowercase、Capitalize、Uncapitalize。

      ',33),l=[o];function n(h,c,s,d,p,u){return e(),r("div",null,l)}const q=a(i,[["render",n]]);export{b as __pageData,q as default}; +import{_ as a,o as e,c as r,N as t}from"./chunks/framework.6fe2e870.js";const b=JSON.parse('{"title":"TypeScript 内置的高级类型","description":"","frontmatter":{},"headers":[],"relativePath":"src/types/高级类型.md","lastUpdated":1694419899000}'),i={name:"src/types/高级类型.md"},o=t('

      TypeScript 内置的高级类型

      Parameters

      Parameters 用于提取函数类型的参数类型。

      ReturnType

      ReturnType 用于提取函数类型的返回值类型。

      ConstructorParameters

      构造器类型和函数类型的区别就是可以被 new。

      Parameters 用于提取函数参数的类型,而 ConstructorParameters 用于提取构造器参数的类型。

      InstanceType

      提取了构造器参数的类型,自然也可以提取构造器返回值的类型,就是 InstanceType。

      ThisParameterType

      OmitThisParameter

      Partial

      Required

      Readonly

      Pick

      Record

      Exclude

      Extract

      Omit

      Awaited

      NonNullable

      Uppercase

      Lowercase

      Capitalize

      Uncapitalize

      总结

      比如用模式匹配可以实现:Parameters、ReturnType、ConstructorParameters、InstanceType、ThisParameterType。

      用模式匹配 + 重新构造可以实现:OmitThisParameter

      用重新构造可以实现:Partial、Required、Readonly、Pick、Record

      用模式匹配 + 递归可以实现: Awaited

      用联合类型在分布式条件类型的特性可以实现: Exclude

      此外还有 NonNullable 和四个编译器内部实现的类型:Uppercase、Lowercase、Capitalize、Uncapitalize。

      ',33),l=[o];function n(h,c,s,d,p,u){return e(),r("div",null,l)}const q=a(i,[["render",n]]);export{b as __pageData,q as default}; diff --git "a/assets/src_types_\351\253\230\347\272\247\347\261\273\345\236\213.md.1ffcb487.lean.js" "b/assets/src_types_\351\253\230\347\272\247\347\261\273\345\236\213.md.3ad1299c.lean.js" similarity index 85% rename from "assets/src_types_\351\253\230\347\272\247\347\261\273\345\236\213.md.1ffcb487.lean.js" rename to "assets/src_types_\351\253\230\347\272\247\347\261\273\345\236\213.md.3ad1299c.lean.js" index d86cc91a1..f73b30b10 100644 --- "a/assets/src_types_\351\253\230\347\272\247\347\261\273\345\236\213.md.1ffcb487.lean.js" +++ "b/assets/src_types_\351\253\230\347\272\247\347\261\273\345\236\213.md.3ad1299c.lean.js" @@ -1 +1 @@ -import{_ as a,o as e,c as r,N as t}from"./chunks/framework.6fe2e870.js";const b=JSON.parse('{"title":"TypeScript 内置的高级类型","description":"","frontmatter":{},"headers":[],"relativePath":"src/types/高级类型.md","lastUpdated":1694276611000}'),i={name:"src/types/高级类型.md"},o=t("",33),l=[o];function n(h,c,s,d,p,u){return e(),r("div",null,l)}const q=a(i,[["render",n]]);export{b as __pageData,q as default}; +import{_ as a,o as e,c as r,N as t}from"./chunks/framework.6fe2e870.js";const b=JSON.parse('{"title":"TypeScript 内置的高级类型","description":"","frontmatter":{},"headers":[],"relativePath":"src/types/高级类型.md","lastUpdated":1694419899000}'),i={name:"src/types/高级类型.md"},o=t("",33),l=[o];function n(h,c,s,d,p,u){return e(),r("div",null,l)}const q=a(i,[["render",n]]);export{b as __pageData,q as default}; diff --git a/hashmap.json b/hashmap.json index 290de0a89..492977447 100644 --- a/hashmap.json +++ b/hashmap.json @@ -1 +1 @@ -{"index.md":"0d318df1","src_article_bundle.md":"7a4db991","src_article_babel.md":"31e21b4d","src_article_astparse_tokenizer.md":"ccc361f6","src_article_typescript_index.md":"9450f83c","src_article_imagemin.md":"05c1ce1a","src_article_javascript_domload.md":"c8afd20d","src_article_typescript_calculate.md":"f31139e2","src_ranui_message_index.md":"fa827f88","src_article_designmode.md":"fdb686ab","src_ranuts_sort_insert_index.md":"de43fe03","src_ranuts_sort_quick_index.md":"9ea0bd8c","src_ranuts_sort_radix_index.md":"45ded274","src_ranuts_sort_select_index.md":"f91454eb","src_ranuts_sort_shell_index.md":"fb9ca14b","src_ranuts_utils_index.md":"0a4014cb","src_ranuts_utils_task.md":"71af1297","src_types_ts类型.md":"c98631f5","src_types_类型运算.md":"78b341b5","src_types_高级类型.md":"1ffcb487","src_article_typescript_reconstruction.md":"a186fc17","src_article_typescript_recursion.md":"9db97e45","src_article_typescript_uniontype.md":"0ba9cf91","src_ranui_button_index.md":"32a9d03f","src_ranui_icon_index.md":"11f7a3d7","src_ranui_image_index.md":"08e89593","src_ranui_index.md":"0d4c041d","src_ranui_input_index.md":"24d6061b","src_ranui_modal_index.md":"f410050d","src_ranui_preview_index.md":"9a6fa2f6","src_ranui_skeleton_index.md":"472eb512","src_ranui_tab_index.md":"087770cd","src_ranui_tabs_index.md":"eff91b6b","src_ranuts_binarytree_index.md":"9df1bc99","src_ranuts_bundler_index.md":"605ec91e","src_ranuts_file_index.md":"177e1adc","src_ranuts_index.md":"238fdd9e","src_ranuts_sort_bubble_index.md":"3b551a0c","src_ranuts_sort_bucket_index.md":"755536c3","src_ranuts_sort_count_index.md":"52dd4e7c","src_ranuts_sort_heap_index.md":"c3678584","src_ranuts_sort_index.md":"b7c48f70","src_types_模式匹配.md":"78b179d7","src_article_functionalprogramming.md":"e9f945b3","src_ranuts_sort_merge_index.md":"46e8a482","src_article_typescript_pattern.md":"e19bc8e4"} +{"src_article_babel.md":"90287ca6","src_article_astparse_tokenizer.md":"99a1983d","src_article_bundle.md":"1794ffc6","src_ranuts_sort_insert_index.md":"032011a9","src_article_javascript_domload.md":"f4dd6368","src_article_typescript_uniontype.md":"2b84a746","src_ranui_button_index.md":"eb788bcc","src_ranui_icon_index.md":"e1b014ce","src_ranui_image_index.md":"c0b5dda1","src_ranui_input_index.md":"755c9dc7","src_ranui_index.md":"8ed6a12e","src_ranui_message_index.md":"2e7373db","src_article_typescript_calculate.md":"9ee3c861","src_article_typescript_reconstruction.md":"21d449a5","src_ranuts_sort_heap_index.md":"ed19bcdb","src_ranuts_sort_merge_index.md":"d6dbf578","src_article_typescript_index.md":"8330b87a","src_article_typescript_pattern.md":"ed4c198d","src_ranuts_sort_radix_index.md":"55bb0018","src_ranuts_utils_index.md":"5d834957","src_ranuts_utils_task.md":"5c6e5a88","src_article_typescript_recursion.md":"061a1d67","src_ranui_preview_index.md":"fa3a8f12","src_ranui_skeleton_index.md":"51e3be48","src_ranui_tab_index.md":"ec0122dc","src_ranuts_index.md":"f4ae71e9","src_ranui_tabs_index.md":"301a2c3b","src_ranuts_sort_index.md":"fb0f8a4a","src_ranuts_binarytree_index.md":"493e0878","src_ranuts_file_index.md":"3ff8632d","src_ranuts_sort_bubble_index.md":"d2e4bc60","src_article_imagemin.md":"32ccabea","index.md":"4abc46fe","src_ranuts_sort_count_index.md":"bcf7daeb","src_ranuts_sort_quick_index.md":"3d358bda","src_ranuts_sort_select_index.md":"cb9012a3","src_ranuts_sort_shell_index.md":"11a9ac10","src_types_ts类型.md":"7ed2f3b0","src_types_类型运算.md":"bb1f0e32","src_types_高级类型.md":"3ad1299c","src_article_functionalprogramming.md":"0ef4df92","src_ranui_modal_index.md":"69c2268b","src_types_模式匹配.md":"c289dbd1","src_article_designmode.md":"c8355f94","src_ranuts_bundler_index.md":"bf6a07c5","src_ranuts_sort_bucket_index.md":"39a1b5ca"} diff --git a/index.html b/index.html index 31dc350ef..b523cf4d1 100644 --- a/index.html +++ b/index.html @@ -37,7 +37,7 @@ - + @@ -50,7 +50,7 @@
      Skip to content

      ran

      风起于青萍之末

      A ship in harbor is safe, but that is not what ships are built for.

      logo
      ⚡️

      记录

      每当遇到问题或者可以改进的事情的时候,会把想法先写下来,如果这是你遇到的问题,那么很可能有一群人也遇到同样的困难。

      🖖

      解决

      过一段时间后,再回来看看这些问题是否还有意义。然后再研究这个问题,确定是否存在解决方案。

      🛠️

      改进

      通常会发现一个工具是为了解决一个问题,我会去考虑如何改进或者简化这个工具。创造一个更好的轮子。

      Released under the MIT License.

      - diff --git a/src/article/astParse/tokenizer.html b/src/article/astParse/tokenizer.html index 8ad13c39e..d48972397 100644 --- a/src/article/astParse/tokenizer.html +++ b/src/article/astParse/tokenizer.html @@ -37,7 +37,7 @@ - + @@ -240,8 +240,8 @@ { type: 'RightParen', value: ')', start: 17, end: 18 }, { type: 'LeftCurly', value: '{', start: 19, end: 20 }, { type: 'RightCurly', value: '}', start: 20, end: 21 }, -]

      一个简易版本的分词器已经被我们开发出来了,不过目前的分词器还比较简陋,仅仅支持有限的语法,不过在明确了核心的开发步骤之后,后面继续完善的过程就比较简单了。

      四.编写语法分析器(Parser)

      在解析出词法 token 之后,我们就可以进入语法分析阶段了。在这个阶段,我们会依次遍历 token ,对代码进行语法结构层面的分析,最后的目标是生成 AST 数据结构。至于代码的 AST 结构到底是什么样子,你可以去 AST Explorer 网站进行在线预览:

      接下来,我们要做的就是将 token 数组转换为上图所示的 AST 数据。

      开发步骤主要分为:

      • 初始化类型声明

      Released under the MIT License.

      - diff --git a/src/article/babel.html b/src/article/babel.html index c8368f0b9..7907d7f7b 100644 --- a/src/article/babel.html +++ b/src/article/babel.html @@ -37,7 +37,7 @@ - + @@ -49,8 +49,8 @@ -
      Skip to content
      On this page

      Babel

      babel 核心库主要是:

      • @babel/parser 对源码进行 parse,可以通过 plugins、sourceType 等来指定 parse 语法,功能是把源码转成 AST。
      • @babel/traverse 通过 visitor 函数对遍历到的 ast 进行处理,分为 enter 和 exit 两个阶段,具体操作 AST 使用 path 的 api,还可以通过 state 来在遍历过程中传递一些数据
      • @babel/types 用于创建、判断 AST 节点,提供了 xxx、isXxx、assertXxx 的 api
      • @babel/template 当需要批量创建 AST 的时候可以使用 @babel/template 来简化 AST 创建逻辑。
      • @babel/code-frame 可以创建友好的报错信息
      • @babel/generator 打印 AST 成目标代码字符串,支持 comments、minified、sourceMaps 等选项。
      • @babel/core 基于上面的包来完成 babel 的编译流程,并应用 plugin 和 preset。

      Released under the MIT License.

      - diff --git a/src/article/bundle.html b/src/article/bundle.html index 3da765909..8fd75b53e 100644 --- a/src/article/bundle.html +++ b/src/article/bundle.html @@ -37,7 +37,7 @@ - + @@ -49,8 +49,8 @@ -
      Skip to content
      On this page

      Bundle

      Bundle 的本质就是输入,转换,输出。在机器上直接运行的代码,往往都难以维护和理解,我们需要将开发者方便理解和维护的代码,通过打包等工具转换成方便机器或者程序使用的代码。对于 web 前端来说,打包工具,至少需要以下功能:

      • 编译能力
      • 插件机制
      • HMR
      • cli 和命令行能力

      Released under the MIT License.

      - diff --git a/src/article/designMode.html b/src/article/designMode.html index a495686b2..3329969bb 100644 --- a/src/article/designMode.html +++ b/src/article/designMode.html @@ -37,7 +37,7 @@ - + @@ -800,8 +800,8 @@ Visitor.push(a,1,2,3,4); Visitor.push(a,4,5,6); Visitor.pop(a); -Visitor.splice(a,2);

      访问者模式解决了数据与数据的操作方法之间的耦合,让数据的操作方法独立于数据,使其可以自由演变。因此,访问者模式更适合于那些数据稳定、但数据的操作方法易变的环境下。

      优点:

      • 增加新的访问操作很方便。使用访问者模式,增加新的访问操作就意味着增加一个新的具体访问者类,实现简单,无须修改源代码,符合“开闭原则”。
      • 将有关元素对象的访问行为集中到一个访问者对象中,而不是分散在一个个的元素类中。类的职责更加清晰,有利于对象结构中元素对象的复用,相同的对象结构可以供多个不同的访问者访问。
      • 让用户能够在不修改现有元素类层次结构的情况下,定义作用于该层次结构的操作。

      缺点:

      • 增加新的元素类很困难。在访问者模式中,每增加一个新的元素类都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作,这违背了“开闭原则”的要求。
      • 破坏封装。访问者模式要求访问者对象访问并调用每一个元素对象的操作,这意味着元素对象有时候必须暴露一些自己的内部操作和内部状态,否则无法供访问者访问。

      总结

      系统地学习设计模式后,你可以在过往的开发经历中发现,设计模式是无处不在的。在学习设计模式之前的很多时候我们是凭借过往经验和智慧来完善系统的设计,而这些经验很多和某个设计模式的思想不谋而合。

      还有一些地方没有完全理解,文中有误之处还望不吝指出。

      参考资料

      Released under the MIT License.

      - diff --git a/src/article/functionalProgramming.html b/src/article/functionalProgramming.html index 139997cb2..33ba0408c 100644 --- a/src/article/functionalProgramming.html +++ b/src/article/functionalProgramming.html @@ -37,7 +37,7 @@ - + @@ -386,8 +386,8 @@ } let r = readFile('package.json') //这里可以用map去处理内容 .flatMap(print) - .join()

      参考资料

      Released under the MIT License.

      - diff --git a/src/article/imagemin.html b/src/article/imagemin.html index 413995eb0..26219a193 100644 --- a/src/article/imagemin.html +++ b/src/article/imagemin.html @@ -37,7 +37,7 @@ - + @@ -49,8 +49,8 @@ -
      Skip to content
      On this page

      imagemin 图片压缩源码分析

      Released under the MIT License.

      - diff --git a/src/article/javascript/domLoad.html b/src/article/javascript/domLoad.html index ee7be22c6..570873c7d 100644 --- a/src/article/javascript/domLoad.html +++ b/src/article/javascript/domLoad.html @@ -37,7 +37,7 @@ - + @@ -51,8 +51,8 @@
      Skip to content
      On this page

      页面加载完成后事件

      window.onload

      DOMContentLoaded

      js
      document.addEventListener('DOMContentLoaded', fun)

      <body onload="fun()">

      readyState

      js
      document.readyState
       
      -document.onreadystatechange

      一个文档的 readyState 可以是以下之一:

      • loading / 加载 。document 仍在加载。
      • interactive / 互动。文档已经完成加载,文档已被解析,但是诸如图像,样式表和框架之类的子资源仍在加载。
      • complete / 完成。T 文档和所有子资源已完成加载。状态表示 load 事件即将被触发。

      Released under the MIT License.

      - diff --git a/src/article/typescript/calculate.html b/src/article/typescript/calculate.html index c808ee114..d97b63708 100644 --- a/src/article/typescript/calculate.html +++ b/src/article/typescript/calculate.html @@ -37,7 +37,7 @@ - + @@ -108,8 +108,8 @@ Num > -type Fibonacci<Num extends number> = FibonacciLoop<[1], [], [], Num>

      类型参数 PrevArr 是代表之前的累加值的数组。类型参数 CurrentArr 是代表当前数值的数组。

      类型参数 IndexArr 用于记录 index,每次递归加一,默认值是 [],代表从 0 开始。

      类型参数 Num 代表求数列的第几个数。

      判断当前 index 也就是 IndexArr['length'] 是否到了 Num,到了就返回当前的数值 CurrentArr['length']。

      否则求出当前 index 对应的数值,用之前的数加上当前的数 [...PrevArr, ... CurrentArr]。

      然后继续递归,index + 1,也就是 [...IndexArr, unknown]。

      这就是递归计算 Fibinacci 数列的数的过程。

      可以正确的算出第 8 个数是 21:

      Released under the MIT License.

      - diff --git a/src/article/typescript/index.html b/src/article/typescript/index.html index 77a3aeca8..bd84e44b2 100644 --- a/src/article/typescript/index.html +++ b/src/article/typescript/index.html @@ -37,7 +37,7 @@ - + @@ -230,8 +230,8 @@ ? R : never

      类型参数 U 是要转换的联合类型。

      U extends U 是为了触发联合类型的 distributive 的性质,让每个类型单独传入做计算,最后合并。

      利用 U 做为参数构造个函数,通过模式匹配取参数的类型。

      结果就是交叉类型

      函数参数的逆变性质一般就联合类型转交叉类型会用,记住就行。

      GetOptional

      如何提取索引类型中的可选索引呢?

      这也要利用可选索引的特性:可选索引的值为 undefined 和值类型的联合类型。

      过滤可选索引,就要构造一个新的索引类型,过程中做过滤:

      ts
      type GetOptional<Obj extends Record<string, any>> = {
         [Key in keyof Obj as {} extends Pick<Obj, Key> ? Key : never]: Obj[Key]
      -}

      类型参数 Obj 为待处理的索引类型,类型约束为索引为 string、值为任意类型的索引类型 Record<string, any>。

      用映射类型的语法重新构造索引类型,索引是之前的索引也就是 Key in keyof Obj,但要做一些过滤,也就是 as 之后的部分。

      过滤的方式就是单独取出该索引之后,判断空对象是否是其子类型。

      这里的 Pick 是 ts 提供的内置高级类型,就是取出某个 Key 构造新的索引类型:

      ts
      type Pick<T, K extends keyof T> = { [P in K]: T[P] }

      比如单独取出 age 构造的新的索引类型是这样的:

      可选的意思是这个索引可能没有,没有的时候,那 Pick<Obj, Key> 就是空的,所以 {} extends Pick<Obj, Key> 就能过滤出可选索引。

      值的类型依然是之前的,也就是 Obj[Key]。

      这样,就能过滤出所有可选索引,构造成新的索引类型:

      总结

      • any 类型与任何类型的交叉都是 any,也就是 1 & any 结果是 any,可以用这个特性判断 any 类型。
      • 联合类型作为类型参数出现在条件类型左侧时,会分散成单个类型传入,最后合并。
      • never 作为类型参数出现在条件类型左侧时,会直接返回 never。
      • any 作为类型参数出现在条件类型左侧时,会直接返回 trueType 和 falseType 的联合类型。
      • 元组类型也是数组类型,但 length 是数字字面量,而数组的 length 是 number。可以用来判断元组类型。
      • 函数参数处会发生逆变,可以用来实现联合类型转交叉类型。
      • 可选索引的索引可能没有,那 Pick 出来的就可能是 {},可以用来过滤可选索引,反过来也可以过滤非可选索引。
      • 索引类型的索引为字符串字面量类型,而可索引签名不是,可以用这个特性过滤掉可索引签名。
      • keyof 只能拿到 class 的 public 的索引,可以用来过滤出 public 的属性。
      • 默认推导出来的不是字面量类型,加上 as const 可以推导出字面量类型,但带有 readonly 修饰,这样模式匹配的时候也得加上 readonly 才行。

      Released under the MIT License.

      - diff --git a/src/article/typescript/pattern.html b/src/article/typescript/pattern.html index 6c0a2f91e..0a74373b7 100644 --- a/src/article/typescript/pattern.html +++ b/src/article/typescript/pattern.html @@ -37,7 +37,7 @@ - + @@ -169,8 +169,8 @@ : never : never

      类型参数 Props 为待处理的类型。

      通过 keyof Props 取出 Props 的所有索引构成的联合类型,判断下 ref 是否在其中,也就是 'ref' extends keyof Props。

      为什么要做这个判断,上面注释里写了:

      在 ts3.0 里面如果没有对应的索引,Obj[Key] 返回的是 {} 而不是 never,所以这样做下兼容处理。

      如果有 ref 这个索引的话,就通过 infer 提取 Value 的类型返回,否则返回 never。

      ts
      type GetPropsRefResult = GetPropsRef<{ ref: 1; name: 'str' }>
       // type GetPropsRefResult = 1

      当 ref 为 undefined 时:

      ts
      type GetPropsRefResult = GetPropsRef<{ ref: undefined; name: 'str' }>
      -// type GetPropsRefResult = undefined

    Released under the MIT License.

- diff --git a/src/article/typescript/reconstruction.html b/src/article/typescript/reconstruction.html index ea08b8aec..b299dd6f7 100644 --- a/src/article/typescript/reconstruction.html +++ b/src/article/typescript/reconstruction.html @@ -37,7 +37,7 @@ - + @@ -109,8 +109,8 @@ [Key in keyof T]-?: T[Key] }

给索引类型 T 的索引去掉 ? 的修饰 ,其余保持不变。

FilterByValueType

可以在构造新索引类型的时候根据值的类型做下过滤:

ts
type FilterByValueType<Obj extends Record<string, any>, ValueType> = {
   [Key in keyof Obj as Obj[Key] extends ValueType ? Key : never]: Obj[Key]
-}

类型参数 Obj 为要处理的索引类型,通过 extends 约束为索引为 string,值为任意类型的索引类型 Record<string, any>。

类型参数 ValueType 为要过滤出的值的类型。

构造新的索引类型,索引为 Obj 的索引,也就是 Key in keyof Obj,但要做一些变换,也就是 as 之后的部分。

如果原来索引的值 Obj[Key] 是 ValueType 类型,索引依然为之前的索引 Key,否则索引设置为 never,never 的索引会在生成新的索引类型时被去掉。

值保持不变,依然为原来索引的值,也就是 Obj[Key]。

这样就达到了过滤索引类型的索引,产生新的索引类型的目的:

- diff --git a/src/article/typescript/recursion.html b/src/article/typescript/recursion.html index 3f26a4095..65362277b 100644 --- a/src/article/typescript/recursion.html +++ b/src/article/typescript/recursion.html @@ -37,7 +37,7 @@ - + @@ -145,8 +145,8 @@ : DeepReadonly<Obj[Key]> : Obj[Key] } - : never - diff --git a/src/article/typescript/unionType.html b/src/article/typescript/unionType.html index 052f2b3c6..1796d923b 100644 --- a/src/article/typescript/unionType.html +++ b/src/article/typescript/unionType.html @@ -37,7 +37,7 @@ - + @@ -78,8 +78,8 @@ | `${A}${B}` | `${B}${A}`

然后构造出来的字符串再和其他字符串组合。

所以全组合的高级类型就是这样:

ts
type AllCombinations<A extends string, B extends string = A> = A extends A
   ? Combination<A, AllCombinations<Exclude<B, A>>>
-  : never

类型参数 A、B 是待组合的两个联合类型,B 默认是 A 也就是同一个。

A extends A 的意义就是让联合类型每个类型单独传入做处理,上面我们刚学会。

A 的处理就是 A 和 B 中去掉 A 以后的所有类型组合,也就是 Combination<A, B 去掉 A 以后的所有组合>。

而 B 去掉 A 以后的所有组合就是 AllCombinations<Exclude<B, A>>,所以全组合就是 Combination<A, AllCombinations<Exclude<B, A>>>。

总结

联合类型中的每个类型都是相互独立的,TypeScript 对它做了特殊处理,也就是遇到字符串类型、条件类型的时候会把每个类型单独传入做计算,最后把每个类型的计算结果合并成联合类型。

条件类型左边是联合类型的时候就会触法这种处理,叫做分布式条件类型。

有两点特别要注意:

我们后面做了一些案例,发现联合类型的这种 distributive 的特性确实能简化类型编程,但是也增加了认知成本,不过这也是不可避免的事。

- diff --git a/src/ranui/button/index.html b/src/ranui/button/index.html index 0f3c104d0..45eecc4e4 100644 --- a/src/ranui/button/index.html +++ b/src/ranui/button/index.html @@ -37,7 +37,7 @@ - + @@ -57,8 +57,8 @@ <r-button type="text" disabled>文本按钮</r-button> <r-button disabled>默认按钮</r-button>

图标icon

当需要在 Button 内嵌入 Icon 时,可以设置 icon 属性,或者直接在 Button 内使用 Icon 组件。

如果想控制 Icon 具体的位置,只能直接使用 Icon 组件,而非 icon 属性。

默认按钮
主要按钮
xml
<r-button type="default" icon="user">默认按钮</r-button>
 <r-button type="primary" icon="home">主要按钮</r-button>

特效 effect

如果需要纯净的 Button ,可以加上 effect = false ,屏蔽点击时候的水波纹特效

默认按钮主要按钮
xml
<r-button type="default" icon="user">默认按钮</r-button>
-<r-button type="primary" icon="home">主要按钮</r-button>
- diff --git a/src/ranui/icon/index.html b/src/ranui/icon/index.html index 745869f11..ff89f6d80 100644 --- a/src/ranui/icon/index.html +++ b/src/ranui/icon/index.html @@ -37,7 +37,7 @@ - + @@ -60,8 +60,8 @@ <r-icon name="lock" size="50" color="#F44336"></r-icon> <r-icon name="lock" size="50" color="#3F51B5"></r-icon>

旋转spin

设置 spin 开启旋转,传入数字控制旋转的速度,数字越小旋转越快

html
<r-icon name="loading" size="50" color="#1E90FF" spin="0.7"></r-icon>
 <r-icon name="loading" size="50" color="#1E90FF" spin></r-icon>
-<r-icon name="loading" size="50" color="#1E90FF" spin="5"></r-icon>

图标列表

- diff --git a/src/ranui/image/index.html b/src/ranui/image/index.html index f5b339678..77f0f28fd 100644 --- a/src/ranui/image/index.html +++ b/src/ranui/image/index.html @@ -37,7 +37,7 @@ - + @@ -49,8 +49,8 @@ -
Skip to content
On this page

Image 图片

代码演示

xml
<r-img src="" fallback=""></r-img>

属性

图片加载地址src

图片的地址

图片加载失败fallback

src配置的图片加载失败,兜底的图片地址,下面是默认加载失败图片

Released under the MIT License.

- diff --git a/src/ranui/index.html b/src/ranui/index.html index 0932410ee..afc54a44f 100644 --- a/src/ranui/index.html +++ b/src/ranui/index.html @@ -37,7 +37,7 @@ - + @@ -139,8 +139,8 @@ function change(e) { console.log('e--->', e) } -</script>

请注意,使用on属性来定义事件处理程序有一些限制和缺点。例如,你不能使用事件捕获或事件委托,而且每个事件类型都需要一个单独的属性。这也是为什么现代的web开发推荐使用addEventListener方法的原因。

Compatibility 兼容性

Contributors 贡献者

Other 相关资源

  1. 优秀的组件设计
  2. 在线生成 CSS 渐变色
  3. 优秀设计作品,有 psd 和 sketch
  4. 3D UI 设计,类似于 3D 版的 figma
  5. 设计规范
  6. 优秀设计作品
  7. element UI 中文网
  8. Ant design 中文网
  9. 在线绘制 CSS 动画
  10. tailwindcss 组件库
  11. animate css 非常优秀的 css 动画
  12. can i use 检测兼容性 API 网站
  13. figma

协议和标准

  1. RFCs
  2. ECMA
  3. w3c
- diff --git a/src/ranui/input/index.html b/src/ranui/input/index.html index aae8ba1bb..02612124c 100644 --- a/src/ranui/input/index.html +++ b/src/ranui/input/index.html @@ -37,7 +37,7 @@ - + @@ -59,8 +59,8 @@ const func = (e) => { console.log(e) } -input.addEventListener('input', func)

事件的e参数结构 input方法

- diff --git a/src/ranui/message/index.html b/src/ranui/message/index.html index bd9e9c7f6..793c17547 100644 --- a/src/ranui/message/index.html +++ b/src/ranui/message/index.html @@ -37,7 +37,7 @@ - + @@ -53,8 +53,8 @@ <r-button onclick="message.warning('这是一条提示')">警告提示</r-button> <r-button onclick="message.error('这是一条提示')">错误提示</r-button> <r-button onclick="message.success('这是一条提示')">成功提示</r-button> -<r-button onclick="message.toast('这是一条提示')">toast提示</r-button>

方法

组件提供了一些静态方法,使用方式和参数如下:

  1. 可以只传一个参数,提示的内容,默认提示 3000 毫秒

message.info('这是一条提示')

message.warning('这是一条提示')

message.error('这是一条提示')

message.success('这是一条提示')

message.toast('这是一条提示')"

  1. 也可以传一个对象,设置提示内容,关闭延时,关闭时触发的回调函数

message.info({content:'这是一条提示', duration: 2000, close: () => {}})

message.warning({content:'这是一条提示', duration: 2000, close: () => {}})

message.error({content:'这是一条提示', duration: 2000, close: () => {}})

message.success({content:'这是一条提示', duration: 2000, close: () => {}})

message.toast({content:'这是一条提示', duration: 2000, close: () => {}})

参数说明类型
content提示内容string
duration自动关闭的延时,单位毫秒。默认 3000 毫秒number
close关闭时触发的回调函数() => void
- diff --git a/src/ranui/modal/index.html b/src/ranui/modal/index.html index 4f2c90d82..ae69da6af 100644 --- a/src/ranui/modal/index.html +++ b/src/ranui/modal/index.html @@ -37,7 +37,7 @@ - + @@ -49,8 +49,8 @@ -
Skip to content
On this page

Released under the MIT License.

- diff --git a/src/ranui/preview/index.html b/src/ranui/preview/index.html index f948b0cb5..8c1620f63 100644 --- a/src/ranui/preview/index.html +++ b/src/ranui/preview/index.html @@ -37,7 +37,7 @@ - + @@ -70,8 +70,8 @@ } } } -</script>

属性

资源地址src

src 地址即可打开弹窗,没有src就不展示

html
<r-preview src=""></r-preview>

是否可关闭closeable

closeable 默认为 true ,可以关闭,设置成 false 时, 表示不可关闭,将不会展示右上角的关闭按钮

html
<r-preview closeable="false"></r-preview>
- diff --git a/src/ranui/skeleton/index.html b/src/ranui/skeleton/index.html index 0d362caa9..fbf51e6bf 100644 --- a/src/ranui/skeleton/index.html +++ b/src/ranui/skeleton/index.html @@ -37,7 +37,7 @@ - + @@ -49,8 +49,8 @@ -
Skip to content
On this page

skeleton 骨架屏

在需要等待加载内容的位置提供一个占位图形组合。

代码演示

骨架长度跟随父级元素的长度

xml
<r-skeleton ></r-skeleton>

Released under the MIT License.

- diff --git a/src/ranui/tab/index.html b/src/ranui/tab/index.html index 7714e3537..de2640777 100644 --- a/src/ranui/tab/index.html +++ b/src/ranui/tab/index.html @@ -37,7 +37,7 @@ - + @@ -91,8 +91,8 @@ <r-tab label="tab1">11111</r-tab> <r-tab label="tab2">22222</r-tab> <r-tab label="tab3">33333</r-tab> - </r-tabs> - diff --git a/src/ranui/tabs/index.html b/src/ranui/tabs/index.html index c61282dd1..8468d293f 100644 --- a/src/ranui/tabs/index.html +++ b/src/ranui/tabs/index.html @@ -37,7 +37,7 @@ - + @@ -73,8 +73,8 @@ <r-tab icon="home" iconSize="22">tab1</r-tab> <r-tab icon="message" iconSize="22">tab2</r-tab> <r-tab icon="user" iconSize="22">tab3</r-tab> -</r-tabs>

风格type

风格有 text,clean,

对齐align

事件event

onchange

切换完成时触发。

- diff --git a/src/ranuts/binaryTree/index.html b/src/ranuts/binaryTree/index.html index c80407d2b..264fcc7b5 100644 --- a/src/ranuts/binaryTree/index.html +++ b/src/ranuts/binaryTree/index.html @@ -37,7 +37,7 @@ - + @@ -49,8 +49,8 @@ -
Skip to content
On this page

二叉树的定义

在计算机科学中,二叉树(Binary tree)是每个节点最多只有两个分支(即不存在分支度大于 2 的节点)的树结构。通常分支被称作“左子树”或“右子树”。二叉树的分支具有左右次序,不能随意颠倒[1]。。

二叉树的性质

  • 在二叉树的第 i 层上最多有 2^(i-1)个结点(i>=1)
  • 深度为 h 的二叉树,最多有 2^h-1 个结点,最少有 h 个结点(h>=1)
  • 包含 n 个结点的二叉树的高度至少为(log2n)+1
  • 非空的二叉树,分支度为 0 的总数为 n0,分支度为 2 的总数为 n2,则 n0=n2+1
  • 二叉树的总结点数 n = n1 + n2 + n0
  • 总连线数等于总节点数减一(B = n - 1)
  • 总连线数等于分支度为 2 的节点的两倍加上分支度为 1 的节点(B = n2 _ 2 + n1 _ 1)

二叉树的类型

满二叉树

一棵深度为 k 且有 2k-1 个节点的二叉树称为满二叉树。 除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树[2]

完全二叉树

一棵深度为 k 的有 n 个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为 i(1≤i≤n)的结点与满二叉树中编号为 i 的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。

二叉搜索树

二叉搜索树(BST)又称二叉查找树或二叉排序树。它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。

平衡二叉树

平衡二叉树(AVL)一定是二叉搜索树,且左子树和右子树的高度差的绝对值不超过 1。 平衡二叉树

B 树

B 树属于多叉树又名平衡多路查找树(查找路径不只两个)

B+树

B+树是 B 树的变体,也是一种多路搜索树。

B*树

B* 树是 B+树的变体,在 B+树的非根和非叶子结点再增加指向兄弟的指针;B* 树定义了非叶子结点关键字个数至少为(2/3)M,即块的最低使用率为 2/3(代替 B+树的 1/2)。B 树分配新结点的概率比 B+树要低,空间使用率更高;

红黑树

红黑树是一种平衡二叉查找树的变体,它的左右子树高差有可能大于 1,所以红黑树不是严格意义上的平衡二叉树(AVL),但对它进行平衡的代价较低, 其平均统计性能要强于 AVL 。

遍历

前序遍历

后序遍历

中序遍历

层序遍历

常见算法题

镜像二叉树

重建二叉树

二叉树深度

二叉树节点总数

判断二叉树子结构

输入两棵二叉树 A 和 B,判断 B 是不是 A 的子结构。(ps:约定空树不是任意一个树的子结构)

参考文档

  1. 维基百科二叉树
  2. 百度百科满二叉树

Released under the MIT License.

- diff --git a/src/ranuts/bundler/index.html b/src/ranuts/bundler/index.html index 3b30f5ab5..93243b08d 100644 --- a/src/ranuts/bundler/index.html +++ b/src/ranuts/bundler/index.html @@ -37,7 +37,7 @@ - + @@ -58,8 +58,8 @@ generate: () => bundle.render() }; }); -}

架构图

- diff --git a/src/ranuts/file/index.html b/src/ranuts/file/index.html index 52e57774f..cf4230f98 100644 --- a/src/ranuts/file/index.html +++ b/src/ranuts/file/index.html @@ -37,7 +37,7 @@ - + @@ -49,8 +49,8 @@ -
Skip to content
On this page

文件操作函数

watchFile

观察一个文件是否改变

API

Return

  • Promise
参数说明类型描述
status文件是否被改变booleantrue 文件改变 false 文件没变

Options

参数说明类型默认值
path文件路径,需要监听的文件stringundefined
interval监听文件改变的时间,单位毫秒。number20

Released under the MIT License.

- diff --git a/src/ranuts/index.html b/src/ranuts/index.html index 02d21b6ad..e8a1ecfce 100644 --- a/src/ranuts/index.html +++ b/src/ranuts/index.html @@ -37,7 +37,7 @@ - + @@ -49,8 +49,8 @@ -
Skip to content
On this page

Released under the MIT License.

- diff --git a/src/ranuts/sort/bubble/index.html b/src/ranuts/sort/bubble/index.html index f0e7c9bd6..89b562e84 100644 --- a/src/ranuts/sort/bubble/index.html +++ b/src/ranuts/sort/bubble/index.html @@ -37,7 +37,7 @@ - + @@ -62,8 +62,8 @@ } } return arr -} - diff --git a/src/ranuts/sort/bucket/index.html b/src/ranuts/sort/bucket/index.html index f9841f9f7..c4d0cef8f 100644 --- a/src/ranuts/sort/bucket/index.html +++ b/src/ranuts/sort/bucket/index.html @@ -37,7 +37,7 @@ - + @@ -110,8 +110,8 @@ list = list.concat(count(buckets[i])) } return list -}

算法分析

桶排序最好情况下使用线性时间 O(n),桶排序的时间复杂度,取决与对各个桶之间数据进行排序的时间复杂度,因为其它部分的时间复杂度都为 O(n)。很显然,桶划分的越小,各个桶之间的数据越少,排序所用的时间也会越少。但相应的空间消耗就会增大。

- diff --git a/src/ranuts/sort/count/index.html b/src/ranuts/sort/count/index.html index 8ac6b6059..14391cbe9 100644 --- a/src/ranuts/sort/count/index.html +++ b/src/ranuts/sort/count/index.html @@ -37,7 +37,7 @@ - + @@ -81,8 +81,8 @@ } } return list -}

算法分析

计数排序是一个稳定的排序算法。当输入的元素是 n 个 0 到 k 之间的整数时,时间复杂度是 O(n+k),空间复杂度也是 O(n+k),其排序速度快于任何比较排序算法。当 k 不是很大并且序列比较集中时,计数排序是一个很有效的排序算法。

- diff --git a/src/ranuts/sort/heap/index.html b/src/ranuts/sort/heap/index.html index d13d850cc..03e6bb1c3 100644 --- a/src/ranuts/sort/heap/index.html +++ b/src/ranuts/sort/heap/index.html @@ -37,7 +37,7 @@ - + @@ -97,8 +97,8 @@ const heap = (list: Array<number>): Array<number> => { const { arr } = new Heap(list) return arr -} - diff --git a/src/ranuts/sort/index.html b/src/ranuts/sort/index.html index 3265de39e..d02a21a38 100644 --- a/src/ranuts/sort/index.html +++ b/src/ranuts/sort/index.html @@ -37,7 +37,7 @@ - + @@ -49,8 +49,8 @@ -
Skip to content
On this page

十大经典排序

十种常见排序算法可以分为两大类:

  • 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破 O(nlogn),因此也称为非线性时间比较类排序。
  • 非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。 排序分类 0.2 算法复杂度

算法复杂度 0.3 相关概念

  • 稳定:如果 a 原本在 b 前面,而 a=b,排序之后 a 仍然在 b 的前面。
  • 不稳定:如果 a 原本在 b 的前面,而 a=b,排序之后 a 可能会出现在 b 的后面。
  • 时间复杂度:对排序数据的总的操作次数。反映当 n 变化时,操作次数呈现什么规律。
  • 空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模 n 的函数。

Released under the MIT License.

- diff --git a/src/ranuts/sort/insert/index.html b/src/ranuts/sort/insert/index.html index 9ebb2b031..affca068b 100644 --- a/src/ranuts/sort/insert/index.html +++ b/src/ranuts/sort/insert/index.html @@ -37,7 +37,7 @@ - + @@ -61,8 +61,8 @@ list[preIndex + 1] = current } return list -}

算法分析

插入排序在实现上,通常采用 in-place 排序(即只需用到 O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

- diff --git a/src/ranuts/sort/merge/index.html b/src/ranuts/sort/merge/index.html index f45891be6..11e03137d 100644 --- a/src/ranuts/sort/merge/index.html +++ b/src/ranuts/sort/merge/index.html @@ -37,7 +37,7 @@ - + @@ -81,8 +81,8 @@ const left = list.slice(0, middle) const right = list.slice(middle) return combine(merge(left), merge(right)) -}

算法分析

归并排序是一种稳定的排序方法。和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是 O(nlogn)的时间复杂度。代价是需要额外的内存空间。

- diff --git a/src/ranuts/sort/quick/index.html b/src/ranuts/sort/quick/index.html index 507efc15b..1eebee087 100644 --- a/src/ranuts/sort/quick/index.html +++ b/src/ranuts/sort/quick/index.html @@ -37,7 +37,7 @@ - + @@ -96,8 +96,8 @@ const quick = (list: Array<number>): Array<number> => { const { length } = list return combine(list, 0, length - 1) -} - diff --git a/src/ranuts/sort/radix/index.html b/src/ranuts/sort/radix/index.html index 003a55824..670cc28dd 100644 --- a/src/ranuts/sort/radix/index.html +++ b/src/ranuts/sort/radix/index.html @@ -37,7 +37,7 @@ - + @@ -84,8 +84,8 @@ list = list.concat(count(buckets[i])) } return list -}

算法分析

基数排序基于分配排序,所以是稳定的。但基数排序的性能比桶排序要略差,每一次关键字的桶分配都需要 O(n)的时间复杂度,而且分配之后得到新的关键字序列又需要 O(n)的时间复杂度。假如待排数据可以分为 d 个关键字,则基数排序的时间复杂度将是 O(d*2n) ,当然 d 要远远小于 n,因此基本上还是线性级别的。

基数排序的空间复杂度为 O(n+k),其中 k 为桶的数量。一般来说 n>>k,因此额外空间需要大概 n 个左右。

- diff --git a/src/ranuts/sort/select/index.html b/src/ranuts/sort/select/index.html index f54b1f19e..05628993a 100644 --- a/src/ranuts/sort/select/index.html +++ b/src/ranuts/sort/select/index.html @@ -37,7 +37,7 @@ - + @@ -65,8 +65,8 @@ arr[minIndex] = temp } return arr -}

算法分析

表现最稳定的排序算法之一,因为无论什么数据进去都是 O(n2)的时间复杂度,所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。理论上讲,选择排序可能也是平时排序一般人想到的最多的排序方法了吧。

- diff --git a/src/ranuts/sort/shell/index.html b/src/ranuts/sort/shell/index.html index 939183bbd..6084aeb7c 100644 --- a/src/ranuts/sort/shell/index.html +++ b/src/ranuts/sort/shell/index.html @@ -37,7 +37,7 @@ - + @@ -68,8 +68,8 @@ } } return list -}

算法分析

希尔排序的核心在于间隔序列的设定。既可以提前设定好间隔序列,也可以动态的定义间隔序列。动态定义间隔序列的算法是《算法(第 4 版)》的合著者 Robert Sedgewick 提出的。

- diff --git a/src/ranuts/utils/index.html b/src/ranuts/utils/index.html index 08a55ad56..4503edf1c 100644 --- a/src/ranuts/utils/index.html +++ b/src/ranuts/utils/index.html @@ -37,7 +37,7 @@ - + @@ -49,8 +49,8 @@ -
Skip to content
On this page

通用函数

filterObj

过滤对象的属性,去除对象中在 list 数组里面有的属性,返回一个新对象,一般是用于去除空字符和 null

API

Return

参数说明类型
run启动轮询(...params: TParams) => void
runAsync启动轮询(...params: TParams) => Promise<TData>
cancel停止轮询() => void

Options

参数说明类型默认值
pollingInterval轮询间隔,单位为毫秒。如果值大于 0,则启动轮询模式。number0
pollingWhenHidden在页面隐藏时,是否继续轮询。如果设置为 false,在页面隐藏时会暂时停止轮询,页面重新显示时继续上次轮询。booleantrue
pollingErrorRetryCount轮询错误重试次数。如果设置为 -1,则无限次number-1

Released under the MIT License.

- diff --git a/src/ranuts/utils/task.html b/src/ranuts/utils/task.html index 79d9ef9aa..779165a68 100644 --- a/src/ranuts/utils/task.html +++ b/src/ranuts/utils/task.html @@ -37,7 +37,7 @@ - + @@ -55,8 +55,8 @@ const time = taskEnd(taskId) -console.log('task 执行花费的时间', time)

二.new Date().getTime()

new Date().getTime() 返回一个数值,表示从 1970 年 1 月 1 日 0 时 0 分 0 秒(UTC,即协调世界时)距离该日期对象所代表时间的毫秒数。用来计算 JS 执行时间会有两个问题:

  1. 某些情况下,毫秒级精度可能不够。
  2. new Date() 解析的时间在不同浏览器,或者不同设备上可能并不一致。MDN 说明

    由于浏览器之间的差异与不一致性,强烈不推荐使用 Date 构造函数来解析日期字符串 (或使用与其等价的 Date.parse)。对 RFC 2822 格式的日期仅有约定俗成的支持。对 ISO 8601 格式的支持中,仅有日期的串 (例如 "1970-01-01") 会被处理为 UTC 而不是本地时间,与其他格式的串的处理不同。

三.console.time(), console.timeEnd()

启动一个计时器来跟踪某一个操作的占用时长。每一个计时器必须拥有唯一的名字,页面中最多能同时运行 10,000 个计时器。当以此计时器名字为参数调用 console.timeEnd() 时,浏览器将以毫秒为单位,输出对应计时器所经过的时间。比起new Date().getTime(),统计时间更加精确,可以统计到 0.001 毫秒(比如:0.134ms)

四.performance.now()

performance.now()返回的时间精度最高可达微秒级,且不会受到系统时间的影响(系统时钟可能会被手动调整或被 NTP 等软件篡改)。另外,performance.timing.navigationStart + performance.now() 约等于 Date.now()。因此对于统计 JS 执行耗时方面,更推荐使用performance.now()

注意:为了提供对定时攻击和指纹的保护,performance.now() 的精度可能会根据浏览器的设置而被舍弃。 在 Firefox 中,privacy.reduceTimerPrecision 偏好是默认启用的,默认值为 1ms。可以启用 privacy.resistFingerprinting 这将精度改为 100ms 或privacy.resistFingerprinting.reduceTimerPrecision.microseconds 的值,以较大者为准。

- diff --git "a/src/types/TS\347\261\273\345\236\213.html" "b/src/types/TS\347\261\273\345\236\213.html" index 42000a088..a3f53a37c 100644 --- "a/src/types/TS\347\261\273\345\236\213.html" +++ "b/src/types/TS\347\261\273\345\236\213.html" @@ -37,7 +37,7 @@ - + @@ -96,8 +96,8 @@ age?: number } -type tuple = [string, number?] - diff --git "a/src/types/\346\250\241\345\274\217\345\214\271\351\205\215.html" "b/src/types/\346\250\241\345\274\217\345\214\271\351\205\215.html" index af09b36b1..f1d911ad6 100644 --- "a/src/types/\346\250\241\345\274\217\345\214\271\351\205\215.html" +++ "b/src/types/\346\250\241\345\274\217\345\214\271\351\205\215.html" @@ -37,7 +37,7 @@ - + @@ -90,8 +90,8 @@ interface PersonConstructor { new (name: string): Person }

这里的 PersonConstructor 返回的是 Person 类型的实例对象,这个也可以通过模式匹配取出来。

ts
type GetInstanceType<C extends new (...args: unknown[]) => unknown> =
-  C extends new (...args: unknown[]) => infer T ? T : unknown
- diff --git "a/src/types/\347\261\273\345\236\213\350\277\220\347\256\227.html" "b/src/types/\347\261\273\345\236\213\350\277\220\347\256\227.html" index 08c9497c2..4151fe26e 100644 --- "a/src/types/\347\261\273\345\236\213\350\277\220\347\256\227.html" +++ "b/src/types/\347\261\273\345\236\213\350\277\220\347\256\227.html" @@ -37,7 +37,7 @@ - + @@ -79,8 +79,8 @@ // type res = { // aaa:[1,1,1] // bbb:[2,2,2] -// }

这里的 & string 可能大家会迷惑,解释一下:

因为索引类型(对象、class 等)可以用 string、number 和 symbol 作为 key,这里 keyof T 取出的索引就是 string | number | symbol 的联合类型,和 string 取交叉部分就只剩下 string 了。就像前面所说,交叉类型会把同一类型做合并,不同类型舍弃。

因为 js 处理对象比较多,所以索引类型的映射比较重要。

- diff --git "a/src/types/\351\253\230\347\272\247\347\261\273\345\236\213.html" "b/src/types/\351\253\230\347\272\247\347\261\273\345\236\213.html" index 0a7122325..23f69e2b4 100644 --- "a/src/types/\351\253\230\347\272\247\347\261\273\345\236\213.html" +++ "b/src/types/\351\253\230\347\272\247\347\261\273\345\236\213.html" @@ -37,7 +37,7 @@ - + @@ -49,8 +49,8 @@ -
Skip to content
On this page

TypeScript 内置的高级类型

Parameters

Parameters 用于提取函数类型的参数类型。

ReturnType

ReturnType 用于提取函数类型的返回值类型。

ConstructorParameters

构造器类型和函数类型的区别就是可以被 new。

Parameters 用于提取函数参数的类型,而 ConstructorParameters 用于提取构造器参数的类型。

InstanceType

提取了构造器参数的类型,自然也可以提取构造器返回值的类型,就是 InstanceType。

ThisParameterType

OmitThisParameter

Partial

Required

Readonly

Pick

Record

Exclude

Extract

Omit

Awaited

NonNullable

Uppercase

Lowercase

Capitalize

Uncapitalize

总结

比如用模式匹配可以实现:Parameters、ReturnType、ConstructorParameters、InstanceType、ThisParameterType。

用模式匹配 + 重新构造可以实现:OmitThisParameter

用重新构造可以实现:Partial、Required、Readonly、Pick、Record

用模式匹配 + 递归可以实现: Awaited

用联合类型在分布式条件类型的特性可以实现: Exclude

此外还有 NonNullable 和四个编译器内部实现的类型:Uppercase、Lowercase、Capitalize、Uncapitalize。

Last updated:

Released under the MIT License.

-