<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>会飞的猪9527</title>
  
  
  <link href="https://blogwxb.cn/atom.xml" rel="self"/>
  
  <link href="https://blogwxb.cn/"/>
  <updated>2024-05-09T09:24:37.784Z</updated>
  <id>https://blogwxb.cn/</id>
  
  <author>
    <name>wxb</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>前端无障碍模式</title>
    <link href="https://blogwxb.cn/%E5%89%8D%E7%AB%AF%E6%97%A0%E9%9A%9C%E7%A2%8D%E6%A8%A1%E5%BC%8F/"/>
    <id>https://blogwxb.cn/%E5%89%8D%E7%AB%AF%E6%97%A0%E9%9A%9C%E7%A2%8D%E6%A8%A1%E5%BC%8F/</id>
    <published>2024-01-03T10:44:38.000Z</published>
    <updated>2024-05-09T09:24:37.784Z</updated>
    
    <content type="html"><![CDATA[<h1 id="前端无障碍模式"><a href="#前端无障碍模式" class="headerlink" title="前端无障碍模式"></a>前端无障碍模式</h1><h1 id="无障碍模式的服务人群"><a href="#无障碍模式的服务人群" class="headerlink" title="无障碍模式的服务人群"></a>无障碍模式的服务人群</h1><p>服务的人群有很多，如：<strong>视障人群、听障人群、肢体障碍、认知障碍、老年人。</strong></p><p>今天讲的无障碍主要针对 <strong>视障人群。</strong></p><span id="more"></span><p>Web的无障碍开发是遵循 <a href="https://www.w3.org/Translations/WCAG21-zh/">WCAG标准</a>，又叫 网页内容无障碍指南。里面规定了字体、颜色、布局等等。</p><h1 id="标签语义化"><a href="#标签语义化" class="headerlink" title="标签语义化"></a>标签语义化</h1><p>良好的标签语义化开发无障碍，会让屏幕阅读器可以更好的适配。屏幕阅读器会更具标签的语义化去阅读网页中的内容，让视障人群能够清晰的了解。如何：</p><ul><li>列表使用 <code>ul</code> <code>li</code> 标签</li><li>底部使用 <code>footer</code> 标签</li><li>按钮使用 <code>button</code> 标签</li><li>标题使用 <code>h1</code> <code>h2</code> <code>h3</code> 等标签</li><li><code>img</code> 标签中的 <code>alt</code> 属性（屏幕阅读器可以阅读alt的值，也用于SEO优化）</li></ul><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">ul</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">li</span>&gt;</span>风风萧兮易水寒<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">li</span>&gt;</span>壮士一去不复返<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">&quot;&quot;</span> <span class="attr">alt</span>=<span class="string">&quot;蒙娜丽莎图片&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">button</span>&gt;</span>这是一个按钮<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">footer</span>&gt;</span>这里是底部<span class="tag">&lt;/<span class="name">footer</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><h1 id="可聚焦元素"><a href="#可聚焦元素" class="headerlink" title="可聚焦元素"></a>可聚焦元素</h1><p>什么是可聚焦元素？</p><p>在页面中最常见的聚焦元素有： <code>button</code> 、 <code>input</code> 、 <code>select</code> 等等。可聚焦元素聚焦状态通常是通过鼠标点击事件触发，也可以使用键盘 <code>tab</code> 键触发。当为聚焦状态的时候会触发元素的 <code>focus</code> 事件，失去焦点的时候触发元素的 <code>blur</code> 事件。</p><h2 id="tabindex"><a href="#tabindex" class="headerlink" title="tabindex"></a><strong>tabindex</strong></h2><blockquote><p><a href="https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/tabindex">MDN文档链接</a></p></blockquote><p>作用：元素是否为可聚焦元素。</p><p>值：</p><ul><li><code>tabindex=负值</code> (通常是 tabindex&#x3D;“-1”)，可聚焦但是不能通过 <code>tab</code> 键聚焦</li><li><code>tabindex&gt;=0</code>， <code>tab</code> 键可聚焦，如果多个元素的tabindex值不同， <code>tab</code> 键聚焦按照从小到大顺序，如果值相同按照DOM顺序聚焦。最大值不能超过 <code>32767</code> 。</li></ul><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">ul</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">li</span> <span class="attr">tabIndex</span>=<span class="string">&#123;0&#125;</span>&gt;</span>风风萧兮易水寒<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">li</span> <span class="attr">tabIndex</span>=<span class="string">&#123;0&#125;</span>&gt;</span>壮士一去不复返<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">tabIndex</span>=<span class="string">&#123;0&#125;</span>&gt;</span></span><br><span class="line">  可聚焦</span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="role"><a href="#role" class="headerlink" title="role"></a>role</h3><p>作用： 用于描述元素的角色或作用。</p><p>常见的值如下：</p><ul><li><code>button</code> ：表示一个可点击的按钮</li><li><code>link</code> ：表示一个可点击的链接</li><li><code>article</code>：表示一个独立的、完整的、可独立分配或可重复使用的内容块，如博客文章、新闻故事或论坛帖子。</li><li><code>search</code>：表示一个搜索框或搜索功能区域</li></ul><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&lt;div tabIndex=&#123;<span class="number">0</span>&#125; role=<span class="string">&quot;button&quot;</span>&gt;</span><br><span class="line">这是一个按钮</span><br><span class="line">&lt;/div&gt;</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">role</span>=<span class="string">&quot;link&quot;</span>&gt;</span>这是一个链接<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br></pre></td></tr></table></figure><h3 id="aria-属性"><a href="#aria-属性" class="headerlink" title="aria-*属性"></a>aria-*属性</h3><p><a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques">MDN文档链接</a></p><p>列举些常用的属性</p><ul><li>aria-label：阅读的内容，修复不准确的文本标签</li><li>aria-labelledby&#x3D;#id：阅读指定元素的内容，值为指定元素的 id。优先级高于 aria-label</li><li>aria-hidden&#x3D;”true”：对屏幕阅读器不可见，即跳过。默认为 false</li><li>aria-checked&#x3D;”true”：按钮已选中，与 role&#x3D;”checkbox&#x2F;raido”搭配使用</li><li>aria-selected&#x3D;”true”：选项已选中</li><li>aria-disabled&#x3D;”true”：按钮不可用</li><li>aria-haspopup&#x3D;”true”：当前元素会触发弹出式 UI 组件，与 aria-expanded 搭配使用。默认 false</li><li>aria-expanded&#x3D;”true”：当前元素的弹出式 UI 组已弹出，默认 false</li><li>进度条&#x2F;滑块相关<ul><li>aria-valuemin：最小值</li><li>aria-valuemax：最大值</li><li>aria-valuenow：当前值</li><li>aria-valuetext：阅读内容</li></ul></li></ul><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">// 阅读 吃饭了吗</span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">aria-label</span>=<span class="string">&quot;吃饭了吗&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">// 阅读天天嘻嘻哈哈</span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">aria-label</span>=<span class="string">&quot;吃饭了吗&quot;</span>&gt;</span>天天嘻嘻哈哈<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="focus-visible"><a href="#focus-visible" class="headerlink" title="focus-visible"></a>focus-visible</h3><p>键盘 <code>tab</code> 键聚集的元素会默认有黑框，这是**<code>focus-visible</code>** 去实现的样式。</p><ul><li><strong><code>focus-visible</code></strong> 是一个 CSS 伪类，用于在用户通过键盘或鼠标聚焦到一个元素时，为该元素添加样式。它的作用是提供一个可见的焦点提示。</li><li><strong><code>focus-visible</code></strong> 伪类的作用就是解决这个问题。它只会在用户通过键盘操作聚焦到一个元素时为其添加样式，而不会在鼠标点击或触摸屏操作时添加样式。</li><li><strong><code>focus-visible</code></strong> 伪类可以改善可访问性，帮助有视觉障碍的用户更好地导航和交互网页。它也可以提供更好的用户体验，让用户能够更容易地理解页面结构和交互行为。</li></ul><h1 id="tabindex-知识点扩展"><a href="#tabindex-知识点扩展" class="headerlink" title="tabindex 知识点扩展"></a>tabindex 知识点扩展</h1><p>根据 <code>tabindex</code> 特性，实现一个简易的 <code>Select</code> 组件。</p><p>当设置了 <code>tabindex</code> 之后该元素就可以聚焦了，当该元素聚焦时可以触发 <code>focus</code> 事件，失去焦点触发 <code>blur</code> 事件。 </p><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">function</span> <span class="title function_">Home</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">const</span> [value, setValue] = <span class="title function_">useState</span>(<span class="string">&#x27;&#x27;</span>);</span><br><span class="line">  <span class="keyword">const</span> [show, setShow] = <span class="title function_">useState</span>(<span class="literal">false</span>);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> (</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">div</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">className</span>=<span class="string">&quot;wrapper&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">tabIndex</span>=<span class="string">&#123;0&#125;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">onFocus</span>=<span class="string">&#123;()</span> =&gt;</span> &#123;</span></span><br><span class="line"><span class="language-xml">          setShow(true);</span></span><br><span class="line"><span class="language-xml">        &#125;&#125;</span></span><br><span class="line"><span class="language-xml">        onBlur=&#123;() =&gt; &#123;</span></span><br><span class="line"><span class="language-xml">          setShow(false);</span></span><br><span class="line"><span class="language-xml">        &#125;&#125;</span></span><br><span class="line"><span class="language-xml">      &gt;</span></span><br><span class="line"><span class="language-xml">        &#123;value || &#x27;请选择&#x27;&#125;</span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">ul</span> <span class="attr">style</span>=<span class="string">&#123;&#123;</span> <span class="attr">display:</span> <span class="attr">show</span> ? &#x27;<span class="attr">block</span>&#x27; <span class="attr">:</span> &#x27;<span class="attr">none</span>&#x27; &#125;&#125;&gt;</span></span></span><br><span class="line"><span class="language-xml">          &#123;[1, 2, 3].map((item) =&gt; (</span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">li</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">              <span class="attr">key</span>=<span class="string">&#123;item&#125;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">              <span class="attr">onClick</span>=<span class="string">&#123;()</span> =&gt;</span> &#123;</span></span><br><span class="line"><span class="language-xml">                setValue(item.toString());</span></span><br><span class="line"><span class="language-xml">                setShow(false);</span></span><br><span class="line"><span class="language-xml">              &#125;&#125;</span></span><br><span class="line"><span class="language-xml">            &gt;</span></span><br><span class="line"><span class="language-xml">              选项&#123;item&#125;</span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          ))&#125;</span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">  );</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="无障碍模式的多样性"><a href="#无障碍模式的多样性" class="headerlink" title="无障碍模式的多样性"></a>无障碍模式的多样性</h1><p>网页的无障碍可以是多种形式的，除了上述的<a href="https://www.w3.org/Translations/WCAG21-zh/">WCAG标准</a>，还有很多种，还有像语音播报这种。</p><p>平时常见的无障碍的产品：</p><ul><li><a href="https://www.zj.gov.cn/art/2022/3/22/art_1229530749_59685240.html">浙江省人民政府</a></li><li>Antd</li><li>知乎</li></ul>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;前端无障碍模式&quot;&gt;&lt;a href=&quot;#前端无障碍模式&quot; class=&quot;headerlink&quot; title=&quot;前端无障碍模式&quot;&gt;&lt;/a&gt;前端无障碍模式&lt;/h1&gt;&lt;h1 id=&quot;无障碍模式的服务人群&quot;&gt;&lt;a href=&quot;#无障碍模式的服务人群&quot; class=&quot;headerlink&quot; title=&quot;无障碍模式的服务人群&quot;&gt;&lt;/a&gt;无障碍模式的服务人群&lt;/h1&gt;&lt;p&gt;服务的人群有很多，如：&lt;strong&gt;视障人群、听障人群、肢体障碍、认知障碍、老年人。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;今天讲的无障碍主要针对 &lt;strong&gt;视障人群。&lt;/strong&gt;&lt;/p&gt;</summary>
    
    
    
    <category term="前端" scheme="https://blogwxb.cn/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="JavaScript" scheme="https://blogwxb.cn/tags/JavaScript/"/>
    
    <category term="HTML" scheme="https://blogwxb.cn/tags/HTML/"/>
    
  </entry>
  
  <entry>
    <title>ES2022精讲</title>
    <link href="https://blogwxb.cn/ES2022%E7%B2%BE%E8%AE%B2/"/>
    <id>https://blogwxb.cn/ES2022%E7%B2%BE%E8%AE%B2/</id>
    <published>2023-09-20T10:43:11.000Z</published>
    <updated>2024-05-09T09:24:37.692Z</updated>
    
    <content type="html"><![CDATA[<h1 id="ECMAScript的渊源"><a href="#ECMAScript的渊源" class="headerlink" title="ECMAScript的渊源"></a><strong><strong>ECMAScript的渊源</strong></strong></h1><p>ECMAScript是一种<code>语言规范</code>：ECMAScript定义了一种脚本语言的标准，规定了语法、类型、语句、关键字等等。它由ECMA国际组织制定，旨在为各种脚本语言提供一个通用的标准。平时常说的<code>ES6</code>，全称就是<code>ECMAScript2015</code>，2015年发布的第六个版本规范。</p><p>JavaScript是一种编程语言：<code>JavaScript是一种基于ECMAScript规范的编程语言</code>，它实现了ECMAScript规范并添加了一些额外的功能，例如DOM操作、事件处理等。</p><span id="more"></span><p>TC39（Technical Committee 39）是负责制定ECMAScript规范的技术委员会。</p><p><a href="https://github.com/tc39/ecma262">https://github.com/tc39/ecma262</a></p><p><img data-src="https://blogwxb.oss-cn-hangzhou.aliyuncs.com/blogResources/20230901170622433-1.png" alt="image-20230901170622433.png"></p><h1 id="顶层设计-await（Top-level-await）"><a href="#顶层设计-await（Top-level-await）" class="headerlink" title="顶层设计 await（Top-level await）"></a><strong><strong>顶层设计 await（Top-level await）</strong></strong></h1><p><strong>作用：</strong>await可以脱离async函数，单独使用</p><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> message = <span class="keyword">await</span> <span class="string">&#x27;hello world&#x27;</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(message);  <span class="comment">// hello world</span></span><br></pre></td></tr></table></figure><p>注意</p><blockquote><p>谨慎使用，当心阻塞后续操作</p></blockquote><h1 id="at"><a href="#at" class="headerlink" title=".at()"></a>.at()</h1><p><strong>作用：</strong>可以获取索引对应的值，可支持 <code>负数</code>  。如下</p><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> arr = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>];</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr.<span class="title function_">at</span>(<span class="number">0</span>)); <span class="comment">// 1</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr.<span class="title function_">at</span>(-<span class="number">1</span>)); <span class="comment">// 3</span></span><br></pre></td></tr></table></figure><p>支持的类型</p><ul><li><code>Array</code> 数组</li><li><code>String</code> 字符串</li><li><code>TypedArray</code> 类型化数组，如： <code>Uint8Array</code> 等等</li></ul><p><strong>为什么 在之前的 <code>[]</code> 方法扩展，而是要用 <code>at</code> 方法？</strong></p><p><code>[]</code> 并非只有数组和字符串特有的方法。所有对象（引用类型的数据，如 <code>Object</code> 、<code>Array</code> 、        <code>Function</code> 等等 ）都有。而且 <code>[]</code> 是本来就可以用 负数的，只不过是相当于负数是对象的key值，来获取Value值的意思。</p><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> arr = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>];</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr[-<span class="number">1</span>]);  <span class="comment">// 提问</span></span><br></pre></td></tr></table></figure><h1 id="Object-hasOwn"><a href="#Object-hasOwn" class="headerlink" title="Object.hasOwn"></a>Object.hasOwn</h1><p>作用：判断对象是否有指定的属性，用来取代 <code>Object.prototype.hasOwnProperty</code> 。</p><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj = &#123; <span class="attr">a</span>: <span class="number">1</span> &#125;;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">hasOwn</span>(obj, <span class="string">&#x27;a&#x27;</span>));  <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">hasOwn</span>(obj, <span class="string">&#x27;b&#x27;</span>));  <span class="comment">// false</span></span><br></pre></td></tr></table></figure><p><code>**Object.prototype.hasOwnProperty</code> 和 <code>in</code> 的区别**</p><p><code>in</code>运算符可以检查继承的属性，而<code>hasOwnProperty</code>方法只检查对象自身的属性</p><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj =&#123;<span class="attr">a</span>:<span class="number">1</span>,<span class="attr">b</span>:<span class="number">2</span>&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;toString&#x27;</span> <span class="keyword">in</span> obj) <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">hasOwnProperty</span>.<span class="title function_">call</span>(obj,<span class="string">&#x27;toString&#x27;</span>)) <span class="comment">// false</span></span><br></pre></td></tr></table></figure><p><strong>现有的<code>Object.prototype.hasOwnProperty</code>的问题有哪些？</strong></p><ol><li>写法繁琐</li></ol><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj = &#123; <span class="attr">a</span>: <span class="number">1</span> &#125;;</span><br><span class="line"><span class="keyword">let</span> hasOwnProperty = <span class="title class_">Object</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">hasOwnProperty</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(hasOwnProperty.<span class="title function_">call</span>(obj, <span class="string">&#x27;a&#x27;</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(hasOwnProperty.<span class="title function_">call</span>(obj, <span class="string">&#x27;b&#x27;</span>));</span><br></pre></td></tr></table></figure><ol><li><code>Object.create(null)</code> 使用 hasOwnProperty  会报错</li></ol><p><code>Object.create(null)</code> 创建的对象不会继承 <code>Object.prototype</code> ，将会丢失 <code>hasOwnProperty</code> 方法。用 <code>Object.prototype.hasOwnProperty</code> ****并不会出现这样情况。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">let obj = Object.create(null);</span><br><span class="line">console.log(Object.prototype.hasOwnProperty.call(obj, &#x27;a&#x27;));  // false</span><br><span class="line"></span><br><span class="line">console.log(obj.hasOwnProperty(&#x27;a&#x27;));</span><br><span class="line">// Uncaught TypeError: Object.create(...).hasOwnProperty is not a function</span><br></pre></td></tr></table></figure><p><strong>为什么上诉例子使用 <code>hasOwnProperty</code> 要从原型上使用（<code>Object.prototype.hasOwnProperty</code>）而不是直接使用 ?</strong></p><p>在上诉代码中，<code>hasOwnProperty</code> 可以直接使用，效果是一样的，如下：</p><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj = &#123; <span class="attr">a</span>: <span class="number">1</span> &#125;;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">hasOwnProperty</span>.<span class="title function_">call</span>(obj, <span class="string">&#x27;a&#x27;</span>));  <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj.<span class="title function_">hasOwnProperty</span>(<span class="string">&#x27;a&#x27;</span>));   <span class="comment">// true</span></span><br></pre></td></tr></table></figure><p><strong>原因：</strong></p><p>为了降低<code>hasOwnProperty</code> 被修改的可能性，防止不必要的bug。</p><p>由于 <code>obj.hasOwnProperty</code> 的 <code>hasOwnProperty</code> 本质上是obj的一个属性，不受到保护，可以被人为修改，可能会出现给对象定义属性名的时候为&#96;&#96;hasOwnProperty&#96; 。</p><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj = &#123; <span class="attr">a</span>: <span class="number">1</span>, <span class="attr">hasOwnProperty</span>: <span class="number">2</span> &#125;;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj.<span class="title function_">hasOwnProperty</span>(<span class="string">&#x27;a&#x27;</span>));</span><br><span class="line"><span class="comment">// Uncaught TypeError: obj.hasOwnProperty is not a function</span></span><br></pre></td></tr></table></figure><p>可以查看<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty#using_hasownproperty_as_a_property_name">MDN详情</a></p><p><strong>为什么不直接在<code>Object.hasOwnProperty(object, property)</code> 中直接修改使用？</strong></p><ul><li><p>答案</p><p>  因为<code>Object</code> 本质上是个<code>函数</code>，<code>Object()</code> 是空对象。并没有直接挂载 <code>hasOwnProperty</code> 属性 ，是通过原型链向上找到的。所以<code>Object.hasOwnProperty</code> 等同于<code>Object.prototype.hasOwnProperty</code> </p>  <figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Object</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">hasOwnProperty</span> = <span class="number">123</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">hasOwnProperty</span>);  <span class="comment">// 123</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="property">hasOwnProperty</span>); <span class="comment">// 123</span></span><br></pre></td></tr></table></figure></li></ul><p><strong>为什么不用 <code>Map</code>替换 <code>Object</code>？</strong></p><ol><li><code>Object</code> 操作上相对于 <code>Map</code> 方便一些</li><li>请求发送数据需要 序列化数据 <code>JSON</code> 格式，Map的话需要转成Object才行，而且有些数据 <code>（key值为引用类型）</code>会丢失。 <figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> map = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line">map.<span class="title function_">set</span>(&#123;<span class="attr">a</span>:<span class="number">1</span>&#125;,<span class="number">1</span>);</span><br><span class="line">map.<span class="title function_">set</span>(<span class="string">&#x27;b&#x27;</span>,<span class="number">2</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">fromEntries</span>(map)) <span class="comment">// &#123;[object Object]: 1, b: 2&#125;</span></span><br></pre></td></tr></table></figure> key值 <code>&#123;a:1&#125;</code> 变成了 <code>[object Object]</code> ，进行了隐式类型转换（ <code>toString</code> ），因为 <code>Object</code>的 <code>key</code>值只能是 <code>string</code>类型。 <figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>((&#123;<span class="attr">a</span>:<span class="number">1</span>&#125;).<span class="title function_">toString</span>()); <span class="comment">// &#x27;[object Object]&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> obj =&#123;<span class="attr">a</span>:<span class="number">1</span>,<span class="attr">b</span>:<span class="number">2</span>&#125;</span><br><span class="line">obj[&#123;<span class="attr">c</span>:<span class="number">3</span>&#125;] = <span class="number">3</span></span><br><span class="line">obj[<span class="number">3</span>] = <span class="number">3333</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> key <span class="keyword">in</span> obj)&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(key,<span class="keyword">typeof</span> key)</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 3 string</span></span><br><span class="line"><span class="comment">// a string</span></span><br><span class="line"><span class="comment">// b string</span></span><br><span class="line"><span class="comment">// [object Object] string</span></span><br></pre></td></tr></table></figure></li></ol><h1 id="Error-Cause"><a href="#Error-Cause" class="headerlink" title="Error Cause"></a><strong>Error Cause</strong></h1><p><strong>作用：</strong>在 <code>Error</code> 类中添加了 <code>cause</code> 属性，用于传递错误信息。方便与错误的处理，对深层次的传递错误提供了良好的便利。</p><p>在以往的错误传递常用的有三种方式：</p><ol><li><p><code>Error</code> 字符串拼接错误信息</p> <figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">queryHandlers</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="title class_">JSON</span>.<span class="title function_">parse</span>(<span class="string">&#x27;&lt;&#x27;</span>)</span><br><span class="line">    &#125; <span class="keyword">catch</span> (err) &#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Error</span>(<span class="string">`parse fail: <span class="subst">$&#123;err&#125;</span>`</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="keyword">await</span> <span class="title function_">queryHandlers</span>();</span><br><span class="line">&#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(e);</span><br><span class="line"><span class="comment">// Error: parse fail: SyntaxError: Unexpected token &#x27;&lt;&#x27;, &quot;&lt;&quot; is not valid JSON</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p>手动为 <code>Error</code> 实例添加 <code>cause</code> 属性</p> <figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">queryHandlers</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="title class_">JSON</span>.<span class="title function_">parse</span>(<span class="string">&#x27;&lt;&#x27;</span>)</span><br><span class="line">    &#125; <span class="keyword">catch</span> (err) &#123;</span><br><span class="line">        <span class="keyword">const</span> customError = <span class="keyword">new</span>  <span class="title class_">Error</span>(<span class="string">`parse fail:`</span>)</span><br><span class="line">        customError.<span class="property">cause</span> = err;</span><br><span class="line">        <span class="keyword">throw</span> customError</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="keyword">await</span> <span class="title function_">queryHandlers</span>();</span><br><span class="line">&#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(e);</span><br><span class="line"><span class="comment">// Error: parse fail:</span></span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(e.<span class="property">cause</span>);</span><br><span class="line"><span class="comment">// SyntaxError: Unexpected token &#x27;&lt;&#x27;, &quot;&lt;&quot; is not valid JSON</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p>通过继承 <code>Error</code> 类来实现自定义的 <code>error</code> 类型</p> <figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">CustomError</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Error</span> &#123;</span><br><span class="line">    <span class="title function_">constructor</span>(<span class="params">msg, cause</span>) &#123;</span><br><span class="line">        <span class="variable language_">super</span>(msg);</span><br><span class="line">        <span class="variable language_">this</span>.<span class="property">cause</span> = cause;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">queryHandlers</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="title class_">JSON</span>.<span class="title function_">parse</span>(<span class="string">&#x27;&lt;&#x27;</span>)</span><br><span class="line">    &#125; <span class="keyword">catch</span> (err) &#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">CustomError</span>(<span class="string">&#x27;parse fail:&#x27;</span>, err);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="keyword">await</span> <span class="title function_">queryHandlers</span>();</span><br><span class="line">&#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(e);</span><br><span class="line"><span class="comment">// Error: parse fail:</span></span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(e.<span class="property">cause</span>);</span><br><span class="line"><span class="comment">// SyntaxError: Unexpected token &#x27;&lt;&#x27;, &quot;&lt;&quot; is not valid JSON</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ol><p>现在的 <code>Error</code> 中实例化的时候可以传入第二个参数，类型是对象，里面为 <code>cause</code> 属性赋值进行传递。</p><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">queryHandlers</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="title class_">JSON</span>.<span class="title function_">parse</span>(<span class="string">&#x27;&lt;&#x27;</span>)</span><br><span class="line">    &#125; <span class="keyword">catch</span> (err) &#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Error</span>(<span class="string">&#x27;parse fail:&#x27;</span>, &#123; <span class="attr">cause</span>: err &#125;);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="keyword">await</span> <span class="title function_">queryHandlers</span>();</span><br><span class="line">&#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(e);</span><br><span class="line"><span class="comment">// Error: parse fail:</span></span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(e.<span class="property">cause</span>);</span><br><span class="line"><span class="comment">// SyntaxError: Unexpected token &#x27;&lt;&#x27;, &quot;&lt;&quot; is not valid JSON</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="Class-Public-Instance-Fields"><a href="#Class-Public-Instance-Fields" class="headerlink" title="Class Public Instance Fields"></a>Class Public Instance Fields</h1><p><strong>作用：</strong>之前要初始化公共的属性需要在 <code>constructor</code> 中进行初始化，现在可以在 <code>constructor</code> 之外去初始化公共属性。</p><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line">    <span class="comment">// 现在的方式</span></span><br><span class="line">    age = <span class="number">18</span>;</span><br><span class="line">    <span class="comment">// 之前的方式</span></span><br><span class="line">    <span class="title function_">constructor</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="variable language_">this</span>.<span class="property">name</span> = <span class="string">&#x27;wxb&#x27;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="Private-Instance-Fields"><a href="#Private-Instance-Fields" class="headerlink" title="Private Instance Fields"></a><strong>Private Instance Fields</strong></h1><p><strong>作用：</strong>私有字段，可以使用 <code>#</code> 声明变量或方法为私有的，实例化之后无法直接访问的。</p><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line">    #age = <span class="number">100</span></span><br><span class="line">    </span><br><span class="line">    <span class="title function_">getAge</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="variable language_">this</span>.#age</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    #<span class="title function_">privateGetAge</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="variable language_">this</span>.#age</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="keyword">new</span> <span class="title class_">Person</span>().<span class="title function_">getAge</span>()); <span class="comment">// 100</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="keyword">new</span> <span class="title class_">Person</span>().#age);</span><br><span class="line"><span class="comment">// Uncaught SyntaxError: Private field &#x27;#age1&#x27; must be declared in an enclosing class</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="keyword">new</span> <span class="title class_">Person</span>().#<span class="title function_">privateGetAge</span>());</span><br><span class="line"><span class="comment">// Uncaught SyntaxError: Private field &#x27;#privateGetAge&#x27; must be declared in an enclosing class</span></span><br></pre></td></tr></table></figure><h1 id="Class-Static-Block"><a href="#Class-Static-Block" class="headerlink" title="Class Static Block"></a>Class Static Block</h1><p><strong>作用：</strong>提供了在未实例类中 关键字<code>static</code> 拥有计算的能力，不只是仅仅声明和赋值变量的能力。</p><p>先介绍一下Class 的 关键字 <code>static</code> ： <code>只能在类型静态状态下访问，不可以实例化之后访问。可以定义变量或者方法。</code> </p><p>使用场景： <code>工具函数</code> 、 <code>常量定义</code> 等等。</p><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 工具函数</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Utils</span> &#123;</span><br><span class="line">    <span class="keyword">static</span> <span class="title function_">parseData</span>(<span class="params">str</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="title class_">JSON</span>.<span class="title function_">parse</span>(str)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Utils</span>.<span class="title function_">parseData</span>(<span class="string">&#x27;&#123;&#125;&#x27;</span>));  <span class="comment">// &#123;&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 常量定义</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Constants</span> &#123;</span><br><span class="line">    <span class="keyword">static</span> <span class="variable constant_">AGE</span> = <span class="number">18</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Constants</span>.<span class="property">AGE</span>);  <span class="comment">// 18</span></span><br></pre></td></tr></table></figure><p>之前如果需要对static进行计算需要再外部去修改，如：</p><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line">    <span class="keyword">static</span> height = <span class="number">180</span>;</span><br><span class="line">    <span class="keyword">static</span> weight = <span class="number">90</span>;</span><br><span class="line">    <span class="keyword">static</span> bmi = <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title class_">Person</span>.<span class="property">bmi</span> = <span class="title class_">Person</span>.<span class="property">height</span> / <span class="title class_">Math</span>.<span class="title function_">pow</span>((<span class="title class_">Person</span>.<span class="property">weight</span>) / <span class="number">100</span>, <span class="number">2</span>)</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Person</span>.<span class="property">bmi</span>); <span class="comment">// 22.5</span></span><br></pre></td></tr></table></figure><p>现在有了类静态代码块的功能，写法如下:</p><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line">    <span class="keyword">static</span> height = <span class="number">200</span>;</span><br><span class="line">    <span class="keyword">static</span> weight = <span class="number">90</span>;</span><br><span class="line">    <span class="keyword">static</span> bmi = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">static</span> &#123;</span><br><span class="line">        <span class="variable language_">this</span>.<span class="property">bmi</span> = <span class="variable language_">this</span>.<span class="property">weight</span> / <span class="title class_">Math</span>.<span class="title function_">pow</span>((<span class="variable language_">this</span>.<span class="property">height</span>) / <span class="number">100</span>, <span class="number">2</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Person</span>.<span class="property">bmi</span>); <span class="comment">// 22.5</span></span><br></pre></td></tr></table></figure><h1 id="RegExp-Match-Indices"><a href="#RegExp-Match-Indices" class="headerlink" title="RegExp Match Indices"></a>RegExp Match Indices</h1><p><strong>作用：</strong>通过正则匹配字符串，输出匹配到的字符串的 <code>开始索引位置</code>和 <code>结束索引位置</code>。</p><p>处于性能的考虑，在已有的匹配模式上新增了 <code>d</code> 模式。之前的匹配模式有以下几种：</p><ul><li><code>i</code> 忽略大小写</li><li><code>g</code> 全局匹配</li><li><code>m</code> 多行匹配</li></ul><p> <code>exec</code> 新增 <code>indices</code> 属性，表示匹配到的字符串的 <code>开始索引位置</code>和 <code>结束索引位置</code> 。</p><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> reg = <span class="regexp">/(\d+)\.\d+/</span>d;  <span class="comment">// 匹配数字加小数点加数字</span></span><br><span class="line"><span class="keyword">const</span> str = <span class="string">&#x27;a12.3a&#x27;</span>;</span><br><span class="line"><span class="keyword">const</span> result = reg.<span class="title function_">exec</span>(str);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(result);</span><br><span class="line"><span class="comment">// [&#x27;12.3&#x27;, &#x27;12&#x27;, index: 1, input: &#x27;a12.3a&#x27;, groups: undefined, indices: Array(2)]</span></span><br></pre></td></tr></table></figure><p>输出的结果 <code>12.3</code> 代表匹配到的结果， <code>12</code> 是正则中 <code>(\d+)</code> 捕获组的结果。</p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;ECMAScript的渊源&quot;&gt;&lt;a href=&quot;#ECMAScript的渊源&quot; class=&quot;headerlink&quot; title=&quot;ECMAScript的渊源&quot;&gt;&lt;/a&gt;&lt;strong&gt;&lt;strong&gt;ECMAScript的渊源&lt;/strong&gt;&lt;/strong&gt;&lt;/h1&gt;&lt;p&gt;ECMAScript是一种&lt;code&gt;语言规范&lt;/code&gt;：ECMAScript定义了一种脚本语言的标准，规定了语法、类型、语句、关键字等等。它由ECMA国际组织制定，旨在为各种脚本语言提供一个通用的标准。平时常说的&lt;code&gt;ES6&lt;/code&gt;，全称就是&lt;code&gt;ECMAScript2015&lt;/code&gt;，2015年发布的第六个版本规范。&lt;/p&gt;
&lt;p&gt;JavaScript是一种编程语言：&lt;code&gt;JavaScript是一种基于ECMAScript规范的编程语言&lt;/code&gt;，它实现了ECMAScript规范并添加了一些额外的功能，例如DOM操作、事件处理等。&lt;/p&gt;</summary>
    
    
    
    <category term="前端" scheme="https://blogwxb.cn/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="Javascript" scheme="https://blogwxb.cn/tags/Javascript/"/>
    
  </entry>
  
  <entry>
    <title>docker部署node项目如何优化镜像体积</title>
    <link href="https://blogwxb.cn/docker%E9%83%A8%E7%BD%B2node%E9%A1%B9%E7%9B%AE%E5%A6%82%E4%BD%95%E4%BC%98%E5%8C%96%E9%95%9C%E5%83%8F%E4%BD%93%E7%A7%AF/"/>
    <id>https://blogwxb.cn/docker%E9%83%A8%E7%BD%B2node%E9%A1%B9%E7%9B%AE%E5%A6%82%E4%BD%95%E4%BC%98%E5%8C%96%E9%95%9C%E5%83%8F%E4%BD%93%E7%A7%AF/</id>
    <published>2023-05-12T00:23:59.000Z</published>
    <updated>2024-05-09T09:24:37.704Z</updated>
    
    <content type="html"><![CDATA[<h1 id="起因"><a href="#起因" class="headerlink" title="起因"></a>起因</h1><p>刚开始docker部署node项目，感觉部署完了就可以了，之后和后端朋友聊起天说我的node镜像有<code>1.02G</code>。后端的朋友直接人傻了，让我看他平时部署的JAVA项目，不看不知道，一看吓一跳居然只有90多M。看来我的node项目镜像确实部署有问题，开始解决镜像过大的问题。开整。。。</p><span id="more"></span><h1 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h1><p>最开始node项目的dockerfile是这样写的：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">FROM node:16                                                                                                                                                                                                                                                                                                                        </span><br><span class="line"></span><br><span class="line">WORKDIR /app                                                                                                                                                                                                                                                                                                     </span><br><span class="line"></span><br><span class="line">COPY package*.json ./                                                                                                                                                                            </span><br><span class="line"></span><br><span class="line">RUN npm install -g cnpm -registry=https://registry.npm.taobao.org \                                                                                                                                                                                                                                                                                      </span><br><span class="line"></span><br><span class="line">&amp;&amp; cnpm install                                                                                                                                                                   </span><br><span class="line"></span><br><span class="line">COPY . .</span><br><span class="line"></span><br><span class="line">RUN cnpm run build </span><br><span class="line"></span><br><span class="line">EXPOSE 9527                                                                                                                                                                                                                                                                                                                                               </span><br><span class="line"></span><br><span class="line">CMD [<span class="string">&quot;npm&quot;</span>,<span class="string">&quot;run&quot;</span>,<span class="string">&quot;docker-start&quot;</span>]  </span><br><span class="line"></span><br></pre></td></tr></table></figure><p>这样子一开始只是只把<code>package.json</code>和<code>package.lock.json</code>文件copy到镜像中，后面进行依赖安装，之后再把其余文件copy到镜像中。 </p><p>这样有个好处是之后的部署只要没有修改package.json中的依赖，每次部署遇到<code>cnpm install</code>就会走到<code>docker layer中缓存中</code>，不用再重新安装依赖了。可以加快部署的速度。  </p><p>但是这样子没有解决node项目镜像的体积。</p><h1 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h1><p>使用docker 的<code>分级构建</code>解决问题，镜像的生成规则是：<code>选择最后一个镜像作为生成镜像</code>，所以前面的镜像体积就会跟最终镜像没有关系。</p><ul><li>第一层镜像：使用的node镜像选择功能全面的镜像进行依赖下载以及打包。</li><li>第二层镜像：选择体积比较小的node镜像来当做基础镜像，将第一层镜像中的运行文件copy到第二层镜像中去。这样就会大大减小node项目的镜像体积。</li></ul><p>修改后的dockerfile文件： </p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 第一层镜像用于安装依赖和打包</span></span><br><span class="line">FROM node:16  AS builder                                                                                                                                                                                                                                                                                                                           </span><br><span class="line"></span><br><span class="line">WORKDIR /app                                                                                                                                                                                                                                                                                                     </span><br><span class="line"></span><br><span class="line">COPY package*.json ./                                                                                                                                                                            </span><br><span class="line"></span><br><span class="line">RUN npm install -g cnpm -registry=https://registry.npm.taobao.org \ </span><br><span class="line">                                                                                                                                                                                                                                                                                    &amp;&amp; cnpm install                                                                                                                                                                   </span><br><span class="line"></span><br><span class="line">COPY . .</span><br><span class="line"></span><br><span class="line">RUN cnpm run build </span><br><span class="line"></span><br><span class="line"><span class="comment"># 第二层镜像选择体积更小的node镜像来作为基础镜像，用来生产</span></span><br><span class="line">FROM node:16.17.0-alpine3.16  as production</span><br><span class="line"></span><br><span class="line">WORKDIR /app</span><br><span class="line"></span><br><span class="line"><span class="comment"># 将实际生成用到的文件从第一层镜像中copy过来</span></span><br><span class="line">COPY --from=builder /app/dist ./dist</span><br><span class="line">COPY --from=builder /app/package.json ./package.json</span><br><span class="line">COPY --from=builder /app/node_modules ./node_modules</span><br><span class="line"></span><br><span class="line">EXPOSE 9527                                                                                                                                                                                                                                                                                                                                               </span><br><span class="line"></span><br><span class="line">CMD [<span class="string">&quot;npm&quot;</span>,<span class="string">&quot;run&quot;</span>,<span class="string">&quot;docker-start&quot;</span>]   </span><br></pre></td></tr></table></figure><p>现在的node项目的镜像大小降低到了<code>200多M</code>。<br>这里还是有优化空间的，如果平时npm安装依赖的时候比较严谨，将<code>eslint</code>这种生成用不到的包安装到<code>devDependencies</code>中，在<code>cnpm install</code>这一步可以改为<code>cnpm install --production</code>，这样就不会安装开发环境所需要的依赖，也就是<code>devDependencies</code>下的依赖都不会安装，从而降低最终node项目镜像的体积。</p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;起因&quot;&gt;&lt;a href=&quot;#起因&quot; class=&quot;headerlink&quot; title=&quot;起因&quot;&gt;&lt;/a&gt;起因&lt;/h1&gt;&lt;p&gt;刚开始docker部署node项目，感觉部署完了就可以了，之后和后端朋友聊起天说我的node镜像有&lt;code&gt;1.02G&lt;/code&gt;。后端的朋友直接人傻了，让我看他平时部署的JAVA项目，不看不知道，一看吓一跳居然只有90多M。看来我的node项目镜像确实部署有问题，开始解决镜像过大的问题。开整。。。&lt;/p&gt;</summary>
    
    
    
    <category term="后端" scheme="https://blogwxb.cn/categories/%E5%90%8E%E7%AB%AF/"/>
    
    
    <category term="Node" scheme="https://blogwxb.cn/tags/Node/"/>
    
    <category term="Docker" scheme="https://blogwxb.cn/tags/Docker/"/>
    
  </entry>
  
  <entry>
    <title>docker匹配镜像并批量删除</title>
    <link href="https://blogwxb.cn/docker%E5%8C%B9%E9%85%8D%E9%95%9C%E5%83%8F%E5%B9%B6%E6%89%B9%E9%87%8F%E5%88%A0%E9%99%A4/"/>
    <id>https://blogwxb.cn/docker%E5%8C%B9%E9%85%8D%E9%95%9C%E5%83%8F%E5%B9%B6%E6%89%B9%E9%87%8F%E5%88%A0%E9%99%A4/</id>
    <published>2023-03-08T17:26:21.000Z</published>
    <updated>2024-05-09T09:24:37.704Z</updated>
    
    <content type="html"><![CDATA[<h1 id="场景"><a href="#场景" class="headerlink" title="场景"></a>场景</h1><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE</span><br><span class="line">node                      dev                 f22e6969a040        11 seconds ago      614MB</span><br><span class="line"><span class="built_in">test</span>                      3.0.0               4db779627117        46 hours ago        614MB</span><br><span class="line"><span class="built_in">test</span>                      2.0.0               4db739647555        46 hours ago        614MB</span><br><span class="line"><span class="built_in">test</span>                      1.0.0               4db779627133        46 hours ago        614MB</span><br><span class="line">test1                     2.0.0               4db779123344        46 hours ago        614MB</span><br><span class="line">test1                     1.0.0               4db779622371        46 hours ago        614MB</span><br><span class="line">test2                     1.0.0               4db779627477        46 hours ago        614MB</span><br><span class="line">&lt;none&gt;                    &lt;none&gt;              92e01ab212ce        13 days ago         263MB</span><br><span class="line">&lt;none&gt;                    &lt;none&gt;              abc55744f08a        13 days ago         263MB</span><br></pre></td></tr></table></figure><p>现在想要删除 所有的<code>test1</code>镜像，可以把所有的镜像id复制粘贴删除，比如：</p><span id="more"></span><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker rmi 4db779627117 4db739647555 4db779627133</span><br></pre></td></tr></table></figure><p>但是这样如果镜像多起来，就会可能复制错镜像id并且繁琐。</p><h1 id="方案"><a href="#方案" class="headerlink" title="方案"></a>方案</h1><p>可以使用<code>grep</code>函数找出所有<code>test1</code>镜像，然后用<code>awk</code>函数找出所有的镜像<code>ID</code>，并将它们作为参数使用 <code>docker rmi</code>命令进行删除所有<code>test1</code>的镜像。 </p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查询所有的包含test1的镜像</span></span><br><span class="line">$ docker images | grep test1 | awk <span class="string">&#x27;&#123;print $3&#125;&#x27;</span></span><br><span class="line">4db779123344</span><br><span class="line">4db779622371</span><br><span class="line"></span><br><span class="line"><span class="comment"># 删除所有的包含test1的镜像</span></span><br><span class="line">$ docker rmi `docker images | grep test1 | awk <span class="string">&#x27;&#123;print $3&#125;&#x27;</span>`</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看所有镜像</span></span><br><span class="line">$ docker images</span><br><span class="line"></span><br><span class="line">REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE</span><br><span class="line">node                      dev                 f22e6969a040        11 seconds ago      614MB</span><br><span class="line"><span class="built_in">test</span>                      3.0.0               4db779627117        46 hours ago        614MB</span><br><span class="line"><span class="built_in">test</span>                      2.0.0               4db739647555        46 hours ago        614MB</span><br><span class="line"><span class="built_in">test</span>                      1.0.0               4db779627133        46 hours ago        614MB</span><br><span class="line">test2                     1.0.0               4db779627477        46 hours ago        614MB</span><br><span class="line">&lt;none&gt;                    &lt;none&gt;              92e01ab212ce        13 days ago         263MB</span><br><span class="line">&lt;none&gt;                    &lt;none&gt;              abc55744f08a        13 days ago         263MB</span><br></pre></td></tr></table></figure><p>上诉例子可以看到包含<code>test1</code>的镜像全删除了。但是如果有镜像还又容器存在的话，该镜像是无法删除的。如果要强制性全部删除的话，可以 <code>docker rmi -f </code> 。</p><pre><code>$ docker rmi -f `docker images | grep test1 | awk &#39;&#123;print $3&#125;&#39;`</code></pre><p><code>grep</code>只是模糊匹配的，如果只想删除所有包含<code>test</code>的镜像呢？ </p><p>如果用刚才的方法会发现不止<code>test</code>镜像没有了，<code>test1</code> 和 <code>test2</code>镜像也被删除了，这时候要使用 <code>grep</code> 的 <code>-w</code> 参数进行精准匹配才行。</p><pre><code># 只删除名字是test的镜像$ docker rmi -f `docker images | grep -w test | awk &#39;&#123;print $3&#125;&#39;`REPOSITORY                TAG                 IMAGE ID            CREATED             SIZEnode                      dev                 f22e6969a040        11 seconds ago      614MBtest1                     2.0.0               4db779123344        46 hours ago        614MBtest1                     1.0.0               4db779622371        46 hours ago        614MBtest2                     1.0.0               4db779627477        46 hours ago        614MB&lt;none&gt;                    &lt;none&gt;              92e01ab212ce        13 days ago         263MB&lt;none&gt;                    &lt;none&gt;              abc55744f08a        13 days ago         263MB</code></pre><p>awk函数<code>&#123;print $3&#125;</code> 返回的是根据空格切分的镜像的第三部分的值，比如 </p><pre><code>node                      dev                 f22e6969a040        11 seconds ago      614MB</code></pre><p><code>&#123;print $1&#125;</code> 返回 node</p><p><code>&#123;print $2&#125;</code> 返回 dev</p><p><code>&#123;print $3&#125;</code> 返回 f22e6969a040</p><p><code>&#123;print $4&#125;</code> 返回 11</p><p><code>&#123;print $5&#125;</code> 返回 seconds</p><p><code>&#123;print $6&#125;</code> 返回 ago</p><p><code>&#123;print $7&#125;</code> 返回 614MB</p><pre><code>$ docker images | grep -w testtest                      3.0.0               4db779627117        46 hours ago        614MBtest                      2.0.0               4db739647555        46 hours ago        614MBtest                      1.0.0               4db779627133        46 hours ago        614MB$ docker images | grep -w test | awk &#39;&#123;print $1&#125;&#39;`testtesttest$ docker images | grep -w test | awk &#39;&#123;print $2&#125;&#39;`3.0.0 2.0.0 1.0.0 $ docker images | grep -w test | awk &#39;&#123;print $3&#125;&#39;`3.0.0 2.0.0 1.0.0 $ docker images | grep -w test | awk &#39;&#123;print $4&#125;&#39;`4db7796271174db7396475554db779627133$ docker images | grep -w test | awk &#39;&#123;print $5&#125;&#39;`464646$ docker images | grep -w test | awk &#39;&#123;print $6&#125;&#39;`hourshourshours$ docker images | grep -w test | awk &#39;&#123;print $7&#125;&#39;`agoagoago$ docker images | grep -w test | awk &#39;&#123;print $8&#125;&#39;`614MB614MB614MB</code></pre>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;场景&quot;&gt;&lt;a href=&quot;#场景&quot; class=&quot;headerlink&quot; title=&quot;场景&quot;&gt;&lt;/a&gt;场景&lt;/h1&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;node                      dev                 f22e6969a040        11 seconds ago      614MB&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;test&lt;/span&gt;                      3.0.0               4db779627117        46 hours ago        614MB&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;test&lt;/span&gt;                      2.0.0               4db739647555        46 hours ago        614MB&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;test&lt;/span&gt;                      1.0.0               4db779627133        46 hours ago        614MB&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;test1                     2.0.0               4db779123344        46 hours ago        614MB&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;test1                     1.0.0               4db779622371        46 hours ago        614MB&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;test2                     1.0.0               4db779627477        46 hours ago        614MB&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;lt;none&amp;gt;                    &amp;lt;none&amp;gt;              92e01ab212ce        13 days ago         263MB&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;lt;none&amp;gt;                    &amp;lt;none&amp;gt;              abc55744f08a        13 days ago         263MB&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;

&lt;p&gt;现在想要删除 所有的&lt;code&gt;test1&lt;/code&gt;镜像，可以把所有的镜像id复制粘贴删除，比如：&lt;/p&gt;</summary>
    
    
    
    <category term="后端" scheme="https://blogwxb.cn/categories/%E5%90%8E%E7%AB%AF/"/>
    
    
    <category term="Docker" scheme="https://blogwxb.cn/tags/Docker/"/>
    
  </entry>
  
  <entry>
    <title>axios主动取消或中止请求</title>
    <link href="https://blogwxb.cn/axios%E4%B8%BB%E5%8A%A8%E5%8F%96%E6%B6%88%E6%88%96%E4%B8%AD%E6%AD%A2%E8%AF%B7%E6%B1%82/"/>
    <id>https://blogwxb.cn/axios%E4%B8%BB%E5%8A%A8%E5%8F%96%E6%B6%88%E6%88%96%E4%B8%AD%E6%AD%A2%E8%AF%B7%E6%B1%82/</id>
    <published>2023-02-24T13:52:49.000Z</published>
    <updated>2024-05-09T09:24:37.700Z</updated>
    
    <content type="html"><![CDATA[<h1 id="场景"><a href="#场景" class="headerlink" title="场景"></a>场景</h1><p>有这样一个场景：后台查询统计数据的时候，如果查询全部日期的话会很慢，比如30秒的时候，这时候不想查询全部了，想查询今天的统计数据，就是会很快的0.5秒查询完了。由于查询今天的数据请求完成了，页面显示的数据是今天的，但是等到全部日期的数据请求完成之后页面的所有数据就会又变了全部日期的数据。</p><span id="more"></span><p>大概意思如下图所示：</p><p><img data-src="https://resource.blogwxb.cn/blogResources/011120590b37d77c38ffb94cd961a3f5-1.gif" alt="图片1"></p><h1 id="解决"><a href="#解决" class="headerlink" title="解决"></a>解决</h1><p><code>axios</code> 从<code>0.22.0</code>版本开始就不推荐 <code>cancel token</code> 的方式，推荐的是 <code>AbortController</code>，接下来要用<code>AbortController</code>的方式去主动取消请求。</p><p>AbortController介绍：</p><ul><li>AbortController 接口表示一个控制器对象，允许你根据需要<code>中止一个或多个 Web 请求</code>。</li><li>你可以使用 <code>AbortController.AbortController()</code> 构造函数创建一个新的<code>AbortController</code>。</li><li>使用<code>AbortSignal</code> 对象可以完成与<code> DOM 请求</code>的通信。</li></ul><p>简单封装axios请求一下：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title function_">request</span> = (<span class="params">type</span>) =&gt; &#123;</span><br><span class="line">  <span class="comment">// 生成AbortController实例</span></span><br><span class="line">  <span class="keyword">const</span> abortController = <span class="keyword">new</span> <span class="title class_">AbortController</span>();</span><br><span class="line">  <span class="built_in">setTimeout</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">      <span class="comment">// 中止请求</span></span><br><span class="line">      abortController.<span class="title function_">abort</span>();  </span><br><span class="line">  &#125;,<span class="number">100</span>)</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="title function_">axios</span>(&#123;</span><br><span class="line">      <span class="attr">url</span>: <span class="string">&#x27;http://localhost:8888/test&#x27;</span>,</span><br><span class="line">      <span class="attr">method</span>: <span class="string">&#x27;get&#x27;</span>,</span><br><span class="line">      <span class="attr">params</span>: &#123;</span><br><span class="line">        type,</span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="comment">// 建立请求的通信</span></span><br><span class="line">      <span class="attr">signal</span>: abortController.<span class="property">signal</span>,</span><br><span class="line">    &#125;)</span><br><span class="line">      .<span class="title function_">then</span>(<span class="function">(<span class="params">res</span>) =&gt;</span> &#123;</span><br><span class="line">        <span class="title function_">resolve</span>(res);</span><br><span class="line">      &#125;)</span><br><span class="line">      .<span class="title function_">catch</span>(<span class="function">(<span class="params">error</span>) =&gt;</span> &#123;</span><br><span class="line">          <span class="comment">// 判断是不是主动取消请求的错误</span></span><br><span class="line">        <span class="keyword">if</span> (axios.<span class="title function_">isCancel</span>(error)) &#123;</span><br><span class="line">          <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;Request canceled&#x27;</span>, error.<span class="property">message</span>);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">          <span class="comment">// 处理错误</span></span><br><span class="line">        &#125;</span><br><span class="line">      &#125;);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>这样发送请求就会中止，但是当前场景是下次请求取消上次的请求，目前这样封装只会自动取消，不能人为控制，所以要将 AbortController 实例抛出去，让外部进行控制。总体代码如下：</p><p>axios封装部分</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title function_">request</span> = (<span class="params">type, callback</span>) =&gt; &#123;</span><br><span class="line">  <span class="keyword">const</span> abortController = <span class="keyword">new</span> <span class="title class_">AbortController</span>();</span><br><span class="line">  callback &amp;&amp; <span class="title function_">callback</span>(abortController);</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="title function_">axios</span>(&#123;</span><br><span class="line">      <span class="attr">url</span>: <span class="string">&#x27;http://localhost:8888/test&#x27;</span>,</span><br><span class="line">      <span class="attr">method</span>: <span class="string">&#x27;get&#x27;</span>,</span><br><span class="line">      <span class="attr">params</span>: &#123;</span><br><span class="line">        type,</span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="attr">signal</span>: abortController.<span class="property">signal</span>,</span><br><span class="line">    &#125;)</span><br><span class="line">      .<span class="title function_">then</span>(<span class="function">(<span class="params">res</span>) =&gt;</span> &#123;</span><br><span class="line">        <span class="title function_">resolve</span>(res);</span><br><span class="line">      &#125;)</span><br><span class="line">      .<span class="title function_">catch</span>(<span class="function">(<span class="params">error</span>) =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (axios.<span class="title function_">isCancel</span>(error)) &#123;</span><br><span class="line">          <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;Request canceled&#x27;</span>, error.<span class="property">message</span>);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">          <span class="comment">// 处理错误</span></span><br><span class="line">        &#125;</span><br><span class="line">      &#125;);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>页面结构部分</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title function_">Index</span> = (<span class="params"></span>) =&gt; &#123;</span><br><span class="line">  <span class="keyword">const</span> [value, setValue] = <span class="title function_">useState</span>(<span class="string">&#x27;all&#x27;</span>);</span><br><span class="line">  <span class="keyword">const</span> [response, setResponse] = <span class="title function_">useState</span>(<span class="string">&#x27;&#x27;</span>);</span><br><span class="line">  <span class="keyword">const</span> [abortInstance, setAbortInstance] = <span class="title function_">useState</span>();</span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> <span class="title function_">changeRadio</span> = (<span class="params">e</span>) =&gt; &#123;</span><br><span class="line">    <span class="title function_">setValue</span>(e.<span class="property">target</span>.<span class="property">value</span>);</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> <span class="title function_">submit</span> = <span class="keyword">async</span> (<span class="params"></span>) =&gt; &#123;</span><br><span class="line">    <span class="comment">// 每次请求前把上次的请求取消掉</span></span><br><span class="line">    abortInstance &amp;&amp; abortInstance.<span class="title function_">abort</span>();</span><br><span class="line">    <span class="keyword">const</span> res = <span class="keyword">await</span> <span class="title function_">request</span>(value, <span class="function">(<span class="params">abortController</span>) =&gt;</span> &#123;</span><br><span class="line">      <span class="comment">// 每次请求的时候，将 AbortController实例存起来</span></span><br><span class="line">      <span class="title function_">setAbortInstance</span>(abortController);</span><br><span class="line">    &#125;);</span><br><span class="line">    <span class="title function_">setResponse</span>(res.<span class="property">data</span>.<span class="property">msg</span>);</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> (</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;main&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">input</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">type</span>=<span class="string">&quot;radio&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">name</span>=<span class="string">&quot;sex&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">value</span>=<span class="string">&quot;all&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">checked</span>=<span class="string">&#123;value</span> === <span class="string">&#x27;all&#x27;</span>&#125;</span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">onChange</span>=<span class="string">&#123;changeRadio&#125;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">      /&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">label</span>&gt;</span>全部数据<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">input</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">type</span>=<span class="string">&quot;radio&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">name</span>=<span class="string">&quot;sex&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">value</span>=<span class="string">&quot;little&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">checked</span>=<span class="string">&#123;value</span> === <span class="string">&#x27;little&#x27;</span>&#125;</span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">onChange</span>=<span class="string">&#123;changeRadio&#125;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">      /&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">label</span>&gt;</span>少量数据<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;submit&#125;</span>&gt;</span>请求<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">div</span>&gt;</span>&#123;response&#125;<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">  );</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>最终的效果：</p><p><img data-src="https://resource.blogwxb.cn/blogResources/011120590b37d77c38ffb94cd961a3f5-2.gif" alt="图片2"></p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;场景&quot;&gt;&lt;a href=&quot;#场景&quot; class=&quot;headerlink&quot; title=&quot;场景&quot;&gt;&lt;/a&gt;场景&lt;/h1&gt;&lt;p&gt;有这样一个场景：后台查询统计数据的时候，如果查询全部日期的话会很慢，比如30秒的时候，这时候不想查询全部了，想查询今天的统计数据，就是会很快的0.5秒查询完了。由于查询今天的数据请求完成了，页面显示的数据是今天的，但是等到全部日期的数据请求完成之后页面的所有数据就会又变了全部日期的数据。&lt;/p&gt;</summary>
    
    
    
    <category term="前端" scheme="https://blogwxb.cn/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="JavaScript" scheme="https://blogwxb.cn/tags/JavaScript/"/>
    
    <category term="Axios" scheme="https://blogwxb.cn/tags/Axios/"/>
    
  </entry>
  
  <entry>
    <title>docker中MongoDB数据库安装部署以及自动备份</title>
    <link href="https://blogwxb.cn/docker%E4%B8%ADMongoDB%E6%95%B0%E6%8D%AE%E5%BA%93%E5%AE%89%E8%A3%85%E9%83%A8%E7%BD%B2%E4%BB%A5%E5%8F%8A%E8%87%AA%E5%8A%A8%E5%A4%87%E4%BB%BD/"/>
    <id>https://blogwxb.cn/docker%E4%B8%ADMongoDB%E6%95%B0%E6%8D%AE%E5%BA%93%E5%AE%89%E8%A3%85%E9%83%A8%E7%BD%B2%E4%BB%A5%E5%8F%8A%E8%87%AA%E5%8A%A8%E5%A4%87%E4%BB%BD/</id>
    <published>2023-02-08T13:43:59.000Z</published>
    <updated>2024-05-09T09:24:37.704Z</updated>
    
    <content type="html"><![CDATA[<h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1><p>先了解一下MongoDB数据怎么导入导出的。</p><ul><li><p>数据库导出</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 语法</span></span><br><span class="line">mongodump -h 127.0.0.1:27017 -d &lt;db&gt; -u &lt;username&gt; -p &lt;password&gt; --authenticationDatabase admin -o &lt;path&gt; </span><br><span class="line"></span><br><span class="line"><span class="comment"># 例子</span></span><br><span class="line">mongodump -h 127.0.0.1:27017 -d <span class="built_in">test</span> -u admin -p 123456 --authenticationDatabase admin -o /data/mongodb </span><br></pre></td></tr></table></figure></li></ul><span id="more"></span><p>参数：</p><ol><li>-h mongoDB所在服务器的地址</li><li>-d 需要导出的数据库，例子中的test就是数据库名称</li><li>-u 数据库管理员用户名</li><li>-p 密码</li><li>--authenticationDatabase 是为了解决权限不足的问题</li><li>-o 导出的数据存放的位置</li></ol><ul><li><p>数据库导入</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 语法</span></span><br><span class="line">mongorestore -h dbhost -u &lt;username&gt; -p &lt;password&gt; --authenticationDatabase admin -d dbname path</span><br><span class="line"><span class="comment">#例子</span></span><br><span class="line">mongorestore -h 127.0.0.1:27017 -u admin -p 123456 --authenticationDatabase admin -d <span class="built_in">test</span> /data/mongodb </span><br><span class="line"></span><br></pre></td></tr></table></figure></li></ul><p>参数同上</p><h1 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h1><p>安装最新版本的MongoDB镜像</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker pull mongo:latest</span><br></pre></td></tr></table></figure><h1 id="部署"><a href="#部署" class="headerlink" title="部署"></a>部署</h1><p>这一步很关键，因为需要让宿主主机的文件夹和mongo容器中的文件夹起到映射关系，这样修改可以通过宿主主机映射的文件夹查看容器中对应文件夹的内容。</p><p>我想要mongo容器把导出的数据库文件备份放入到 <code>/data/mongodb</code>中，但是想要查看备份的数据库文件需要每次进入mongo容器中才能看到，我想要直接在宿主主机中<code>/data/mongodb/</code>看到就需要在运行容器的时候去进行映射。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">docker run \ </span><br><span class="line">--name mongod \ </span><br><span class="line">-p 27017:27017 \ </span><br><span class="line">-v /data/mongodb:/data/mongodb/ \ </span><br><span class="line">-d mongo \</span><br><span class="line">-- auth</span><br></pre></td></tr></table></figure><p>参数</p><ul><li>--name 容器名称</li><li>-p 指定端口映射，格式为：主机(宿主)端口:容器端口</li><li>-v 宿主主机文件夹和容器中的文件夹进行映射</li><li>-d 运行的镜像</li><li>-- auth 连接数据库需要用户名和密码</li></ul><p>docker 进入容器的命令</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker <span class="built_in">exec</span> --it &lt;container&gt;</span><br></pre></td></tr></table></figure><p>参数</p><ul><li>container  容器名字或者容器id</li></ul><p>添加用户和设置密码</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"> docker <span class="built_in">exec</span> -it mongo mongo admin</span><br><span class="line"><span class="comment"># 创建一个名为 admin，密码为 123456 的用户。</span></span><br><span class="line">&gt; db.createUser(&#123; user:<span class="string">&#x27;admin&#x27;</span>,<span class="built_in">pwd</span>:<span class="string">&#x27;123456&#x27;</span>,roles:[ &#123; role:<span class="string">&#x27;userAdminAnyDatabase&#x27;</span>, db: <span class="string">&#x27;admin&#x27;</span>&#125;,<span class="string">&quot;readWriteAnyDatabase&quot;</span>]&#125;);</span><br></pre></td></tr></table></figure><p>roles：指定用户的角色，可以用一个空数组给新用户设定空角色；在roles字段,可以指定内置角色和用户定义的角色。role里的角色可以选：</p><p>Built-In Roles（内置角色）：</p><ol><li>数据库用户角色：read、readWrite;</li><li>数据库管理角色：dbAdmin、dbOwner、userAdmin；</li><li>集群管理角色：clusterAdmin、clusterManager、clusterMonitor、hostManager；</li><li>备份恢复角色：backup、restore；</li><li>所有数据库角色：readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase</li><li>超级用户角色：root</li></ol><p>现在是定义好了超级用户角色，如果想要再次添加角色就需要进行验证。<br>例子：如果现在想要再创建一个角色为<code>readAnyDatabase</code>的权限，需要先<code>db.auth(用户名，密码)</code>进行身份认证，通过之后就可以创建用户。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 进行身份验证</span></span><br><span class="line">&gt; db.auth(<span class="string">&quot;admin&quot;</span>,<span class="string">&quot;123456&quot;</span>)</span><br><span class="line">1    <span class="comment"># 1代表通过，0代表未通过</span></span><br><span class="line"><span class="comment"># 创建新的用户</span></span><br><span class="line">&gt;db.createUser(&#123; user:<span class="string">&#x27;user&#x27;</span>,<span class="built_in">pwd</span>:<span class="string">&#x27;123456&#x27;</span>,roles:[ &#123; role:<span class="string">&#x27;userAdminAnyDatabase&#x27;</span>, db: <span class="string">&#x27;admin&#x27;</span>&#125;,<span class="string">&quot;readWriteAnyDatabase&quot;</span>]&#125;);</span><br></pre></td></tr></table></figure><h1 id="备份"><a href="#备份" class="headerlink" title="备份"></a>备份</h1><p>思路</p><ol><li>进入容器</li><li>导出数据库</li></ol><p>实现：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">docker <span class="built_in">exec</span> -it mongo</span><br><span class="line"></span><br><span class="line">mongodump -h 127.0.0.1:27017 -d <span class="built_in">test</span> -u admin -p 123456 --authenticationDatabase admin -o /data/mongodb </span><br></pre></td></tr></table></figure><p>这样就在宿主主机的 &#x2F;data&#x2F;mongodb 文件夹中看到</p><h1 id="定时自动备份"><a href="#定时自动备份" class="headerlink" title="定时自动备份"></a>定时自动备份</h1><p>定时这里是需要用到 <code>crontab</code> 和 <code>shell脚本</code> 这两个知识点了。</p><p>crontab如何使用这里就不介绍了。</p><p>思路：</p><ol><li>shell脚本去导出数据库，并压缩成压缩包</li><li>crontab开启定时任务执行该shell脚本的</li></ol><p>shell脚本为：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line"><span class="built_in">cd</span> /data/mongodb</span><br><span class="line">filename=<span class="string">&#x27;test&#x27;</span></span><br><span class="line">DATE=$(<span class="built_in">date</span> +%Y%m%d)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 删除上次的MongoDB导出的数据库test文件夹</span></span><br><span class="line"><span class="keyword">if</span> [ -d <span class="string">&quot;<span class="variable">$filename</span>&quot;</span> ]; <span class="keyword">then</span></span><br><span class="line"><span class="built_in">rm</span> -rf <span class="string">&quot;<span class="variable">$filename</span>&quot;</span></span><br><span class="line"><span class="keyword">fi</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 进入mongo容器并导出test数据库</span></span><br><span class="line">docker <span class="built_in">exec</span> mongo mongodump -h 127.0.0.1:27017 -d <span class="built_in">test</span> -u admin -p 123456 --authenticationDatabase admin  -o /data/mongodb</span><br><span class="line"></span><br><span class="line"><span class="comment"># 压缩test文件夹成压缩包</span></span><br><span class="line"><span class="keyword">if</span> [ -d <span class="string">&quot;<span class="variable">$filename</span>&quot;</span> ]; <span class="keyword">then</span></span><br><span class="line">tar czvf mongdb-backup-<span class="variable">$DATE</span>.tar.gz <span class="variable">$filename</span></span><br><span class="line"><span class="keyword">fi</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 保留最新60天数据</span></span><br><span class="line"><span class="built_in">ls</span> -t | <span class="built_in">tail</span> -n +60 | xargs <span class="built_in">rm</span> -rf</span><br></pre></td></tr></table></figure><p>使用crontab去定时执行shell脚本</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">crontab -e</span><br><span class="line"></span><br><span class="line"><span class="comment"># 每天凌晨两点十分执行shell脚本</span></span><br><span class="line">10 2 * * * sh /data/backup.sh</span><br></pre></td></tr></table></figure><h1 id="注意"><a href="#注意" class="headerlink" title="注意"></a>注意</h1><p>当定时任务执行docker脚本docker脚本要使用<code>-it</code>时将会失效。如：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">// docker进入mongo容器的方法</span><br><span class="line">docker <span class="built_in">exec</span> -it mongo /bin/dash</span><br></pre></td></tr></table></figure><p>这在shell脚本中运行是正常的，但是如果用crontab去运行的话就会失效，因为<code>exec 加了 -it 参数就开启了一个终端，计划任务无法进入任何终端</code>。所以在crontab任务中docker exec的正确用法是:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker <span class="built_in">exec</span> mongo /bin/dash</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;简介&quot;&gt;&lt;a href=&quot;#简介&quot; class=&quot;headerlink&quot; title=&quot;简介&quot;&gt;&lt;/a&gt;简介&lt;/h1&gt;&lt;p&gt;先了解一下MongoDB数据怎么导入导出的。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;数据库导出&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 语法&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;mongodump -h 127.0.0.1:27017 -d &amp;lt;db&amp;gt; -u &amp;lt;username&amp;gt; -p &amp;lt;password&amp;gt; --authenticationDatabase admin -o &amp;lt;path&amp;gt; &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 例子&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;mongodump -h 127.0.0.1:27017 -d &lt;span class=&quot;built_in&quot;&gt;test&lt;/span&gt; -u admin -p 123456 --authenticationDatabase admin -o /data/mongodb &lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;</summary>
    
    
    
    <category term="后端" scheme="https://blogwxb.cn/categories/%E5%90%8E%E7%AB%AF/"/>
    
    
    <category term="Docker" scheme="https://blogwxb.cn/tags/Docker/"/>
    
  </entry>
  
  <entry>
    <title>node的调试方法-Inspector调试</title>
    <link href="https://blogwxb.cn/node%E7%9A%84%E8%B0%83%E8%AF%95%E6%96%B9%E6%B3%95-Inspector%E8%B0%83%E8%AF%95/"/>
    <id>https://blogwxb.cn/node%E7%9A%84%E8%B0%83%E8%AF%95%E6%96%B9%E6%B3%95-Inspector%E8%B0%83%E8%AF%95/</id>
    <published>2023-01-15T20:11:11.000Z</published>
    <updated>2024-05-09T09:24:37.716Z</updated>
    
    <content type="html"><![CDATA[<p>举例一个简单的例子，创建一个app.js入口文件</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> express = <span class="built_in">require</span>(<span class="string">&#x27;express&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> app = <span class="title function_">express</span>();</span><br><span class="line"><span class="comment">// 启动</span></span><br><span class="line">app.<span class="title function_">listen</span>(<span class="number">3333</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;http://localhost:3333&#x27;</span>);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="comment">// /api接口</span></span><br><span class="line">app.<span class="title function_">use</span>(<span class="string">&#x27;/api&#x27;</span>, <span class="function">(<span class="params">req, res</span>) =&gt;</span> &#123;</span><br><span class="line">    res.<span class="title function_">json</span>(&#123;</span><br><span class="line">        <span class="attr">success</span>: <span class="literal">true</span>,</span><br><span class="line">        <span class="attr">message</span>: <span class="string">&#x27;hell world&#x27;</span></span><br><span class="line">    &#125;)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><span id="more"></span><p>可以直接使用 <code>node--inspect app.js</code> 或 <code>npx nodemon --inspect app.js</code> 。<br>当然也可以在package.json文件中配置脚本去运行，如下：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;npmTest&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;description&quot;</span><span class="punctuation">:</span> <span class="string">&quot;&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;main&quot;</span><span class="punctuation">:</span> <span class="string">&quot;index.js&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;scripts&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;dev&quot;</span><span class="punctuation">:</span> <span class="string">&quot;npx nodemon --inspect app.js &quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>运行 npm run dev 即可。<br>Inspector是通过浏览器和远程服务器建立连接后，是通过 WebSocket 协议通信的<br><img data-src="https://resource.blogwxb.cn/blogResources/4297f44b13955235245b2497399d7a93-1.png"><br>9229 端口是 Node.js 默认选择的端口，这时候随便打开个网页，点击node图标就可以打开新的控制台，然后就可以调试了。<br><img data-src="https://resource.blogwxb.cn/blogResources/4297f44b13955235245b2497399d7a93-2.png"><br><img data-src="https://resource.blogwxb.cn/blogResources/4297f44b13955235245b2497399d7a93-3.png"></p><p>打开<code>sources</code>即可调试，也可以断点调试<br><img data-src="https://resource.blogwxb.cn/blogResources/4297f44b13955235245b2497399d7a93-4.png"></p><p>还有一种方法可以进到<code>node调试工具</code>，在 Chrome 浏览器的地址栏，输入<code>chrome://inspect</code> 或者 <code>about:inspect</code> ，进入到页面之后，点击<code>inspect按钮</code>即可进入到<code>Node调试工具</code>。<br><img data-src="https://resource.blogwxb.cn/blogResources/4297f44b13955235245b2497399d7a93-5.png"><br>Local 作用域和 Global 作用域里面的所有变量<br><img data-src="https://resource.blogwxb.cn/blogResources/4297f44b13955235245b2497399d7a93-6.png"></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;举例一个简单的例子，创建一个app.js入口文件&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; express = &lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&amp;#x27;express&amp;#x27;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; app = &lt;span class=&quot;title function_&quot;&gt;express&lt;/span&gt;();&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// 启动&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;app.&lt;span class=&quot;title function_&quot;&gt;listen&lt;/span&gt;(&lt;span class=&quot;number&quot;&gt;3333&lt;/span&gt;,&lt;span class=&quot;function&quot;&gt;()=&amp;gt;&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;variable language_&quot;&gt;console&lt;/span&gt;.&lt;span class=&quot;title function_&quot;&gt;log&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&amp;#x27;http://localhost:3333&amp;#x27;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// /api接口&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;app.&lt;span class=&quot;title function_&quot;&gt;use&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&amp;#x27;/api&amp;#x27;&lt;/span&gt;, &lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;req, res&lt;/span&gt;) =&amp;gt;&lt;/span&gt; &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    res.&lt;span class=&quot;title function_&quot;&gt;json&lt;/span&gt;(&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;attr&quot;&gt;success&lt;/span&gt;: &lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;attr&quot;&gt;message&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&amp;#x27;hell world&amp;#x27;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;)&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;</summary>
    
    
    
    <category term="后端" scheme="https://blogwxb.cn/categories/%E5%90%8E%E7%AB%AF/"/>
    
    
    <category term="Node" scheme="https://blogwxb.cn/tags/Node/"/>
    
  </entry>
  
  <entry>
    <title>用pixijs实现数字华容道游戏</title>
    <link href="https://blogwxb.cn/%E7%94%A8pixijs%E5%AE%9E%E7%8E%B0%E6%95%B0%E5%AD%97%E5%8D%8E%E5%AE%B9%E9%81%93%E6%B8%B8%E6%88%8F/"/>
    <id>https://blogwxb.cn/%E7%94%A8pixijs%E5%AE%9E%E7%8E%B0%E6%95%B0%E5%AD%97%E5%8D%8E%E5%AE%B9%E9%81%93%E6%B8%B8%E6%88%8F/</id>
    <published>2022-12-12T10:48:31.000Z</published>
    <updated>2024-05-09T09:24:37.784Z</updated>
    
    <content type="html"><![CDATA[<p>最近老是抖音老是刷到一个小孩子玩数字华容道特别厉害，我感觉挺有趣的，就做了一个数字华容道，上班摸鱼可以玩，哈哈哈哈哈。  </p><span id="more"></span><img data-src="https://resource.blogwxb.cn/digitalHuarongRoad/screen-recording.gif"><p><a href="https://dhr.blogwxb.cn/">项目预览地址</a><br><a href="https://github.com/dearDreamWeb/digital-huarong-road">项目地址</a> 喜欢的话请给个 star⭐️</p><p>整体的样式是采用了<code>像素风格</code>。<br>功能：</p><ul><li>游戏模式可以自定义选择难度，比如 3X3、4X4、5X5 等</li><li>设置的有各个模式的排行榜，可以看到排名</li><li>用户昵称是随机的，如果不满意可以更换昵称</li></ul><h1 id="实现思路"><a href="#实现思路" class="headerlink" title="实现思路"></a>实现思路</h1><p>核心的部分肯定是游戏交互的部分了，这里采用的是二维数组的方式实现的。<br><code>二维数组</code>：主要是为了每个模式的初始化的时候，以二维数组的形式为默认值，为了后面区分<code>行数</code>和<code>列数</code>。需要用到两个二维数组，一个是为了初始化的值<code>initData</code>，一个是当前游戏中的值<code>curData</code>。<br>如：3X3 的模式初始化 initData</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[</span><br><span class="line">    [1,2,3],</span><br><span class="line">    [4,5,6],</span><br><span class="line">    [7,8,null]</span><br><span class="line">]</span><br></pre></td></tr></table></figure><p>由于是用的 pixijs 去生成的方格，点击事件获取的是该方格的<code>数值</code>，如：1,2,3,4,5,6 等等。根据点击的方格数值判断该方格<code>四周（上下左右）</code>有没有<code>null</code>值，有的话就进行交换，得到新的<code>curData</code>。这里判断是有些麻烦的。</p><p>例子：<br>如果当前点击的是 3，当前模式的行数(<code>rows</code>)为 3，列数(<code>columns</code>)为 3<br>当前的布局(<code>curData</code>)为：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[</span><br><span class="line">    [2,6,3],</span><br><span class="line">    [1,null,5],</span><br><span class="line">    [7,4,8]</span><br><span class="line">]</span><br></pre></td></tr></table></figure><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 先获取点击数字在 curData中的位置</span></span><br><span class="line"><span class="keyword">const</span> curDataFlat = curData.<span class="title function_">flat</span>(); <span class="comment">// 数组扁平化处理，二维数组转成一维数组</span></span><br><span class="line"><span class="keyword">const</span> index = curDataFlat.<span class="title function_">indexOf</span>(<span class="string">&#x27;3&#x27;</span>); <span class="comment">// index 为2</span></span><br><span class="line"><span class="comment">// 要移动的方向</span></span><br><span class="line"><span class="keyword">let</span> direction = <span class="string">&#x27;&#x27;</span>;</span><br><span class="line"><span class="comment">// 要交换的位置</span></span><br><span class="line"><span class="keyword">let</span> newIndex = index;</span><br><span class="line"><span class="comment">// 左方向的判断</span></span><br><span class="line"><span class="keyword">if</span> (curDataFlat[index - <span class="number">1</span>] === <span class="literal">null</span>) &#123;</span><br><span class="line">  <span class="keyword">if</span> (index % columns !== <span class="number">0</span>) &#123;</span><br><span class="line">    direction = <span class="string">&#x27;left&#x27;</span>;</span><br><span class="line">    newIndex = index - <span class="number">1</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 右方向的判断</span></span><br><span class="line">&#125; <span class="keyword">else</span> <span class="keyword">if</span> (curDataFlat[index + <span class="number">1</span>] === <span class="literal">null</span>) &#123;</span><br><span class="line">  <span class="keyword">if</span> (index % columns !== columns - <span class="number">1</span>) &#123;</span><br><span class="line">    direction = <span class="string">&#x27;right&#x27;</span>;</span><br><span class="line">    newIndex = index + <span class="number">1</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 下方向的判断</span></span><br><span class="line">&#125; <span class="keyword">else</span> <span class="keyword">if</span> (curDataFlat[index + columns] === <span class="literal">null</span>) &#123;</span><br><span class="line">  direction = <span class="string">&#x27;bottom&#x27;</span>;</span><br><span class="line">  newIndex = index + columns;</span><br><span class="line">  <span class="comment">// 上方向的判断</span></span><br><span class="line">&#125; <span class="keyword">else</span> <span class="keyword">if</span> (curDataFlat[index - columns] === <span class="literal">null</span>) &#123;</span><br><span class="line">  direction = <span class="string">&#x27;top&#x27;</span>;</span><br><span class="line">  newIndex = index - columns;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>每次交换之后<code>curData</code>都要和<code>initData</code>进行对比，如果一样代表成功了，游戏结束。</p><h2 id="游戏怎么初始化？"><a href="#游戏怎么初始化？" class="headerlink" title="游戏怎么初始化？"></a>游戏怎么初始化？</h2><p>一开始我想的很简单，拿<code>3X3</code>的模式举例子就是拿<code>1-8</code>的数字随机取。<br>数组： [1,2,3,4,5,6,7,8]<br>第一次随机拿到了<code>3</code>就放第一个格子里,这时候数组变成了[1,2,4,5,6,7,8]<br>第二次随机拿到了<code>5</code>放第二个格子中,这时候数组变成了[1,2,4,6,7,8]<br>…<br>依次类推把格子填满了。<br>本来以为这样就大功告成了。后面发现了一个很致命的<code>问题</code>：<code>有时候这样的随机布局根本就无法通关</code>。<br>举一个最简单的例子：<br>随机的布局是这样子的：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[</span><br><span class="line">    [1,2,3],</span><br><span class="line">    [4,5,6],</span><br><span class="line">    [8,7,null]</span><br><span class="line">]</span><br></pre></td></tr></table></figure><p>这种是无法通关的，emm……。</p><p>换个思路：<br>换个玩魔方的思路，魔方是怎么随机的，是先将一个复原好的魔方进行随机旋转打乱的。ok，用这个思路就可以进行数字华容道的随机布局了。<br>具体思路：</p><ol><li>一开始先用完成好的布局：</li></ol><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[</span><br><span class="line">    [1,2,3],</span><br><span class="line">    [4,5,6],</span><br><span class="line">    [7,8,null]</span><br><span class="line">]</span><br></pre></td></tr></table></figure><ol start="2"><li><code>随机上下左右移动null值</code>，这样随机移动几十步或者上百步就可以打乱初始化的布局了，每次的随机布局也都能通关了。</li></ol><h1 id="游戏昵称怎么随机？"><a href="#游戏昵称怎么随机？" class="headerlink" title="游戏昵称怎么随机？"></a>游戏昵称怎么随机？</h1><p>一开始我想的是随机拿到汉字，这里是可以通过 Unicode 编码去实现的。<br>汉字的范围是 <code>4e00-9fa5</code>,这些编码前面加上<code>0x</code>就是能得到十进制的数值了，再通过<code>toString(16)</code>转换成十六进制<code>4e00</code>，最后将<code>4e00</code>加上<code>\u</code>，得到<code>\u4e00</code>，通过<code>unescape</code>方法得到该字符。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">randomAccess</span>(<span class="params">min, max</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="title class_">Math</span>.<span class="title function_">floor</span>(<span class="title class_">Math</span>.<span class="title function_">random</span>() * (min - max) + max);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 解码</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">decodeUnicode</span>(<span class="params">str</span>) &#123;</span><br><span class="line">  <span class="comment">//Unicode显示方式是\u4e00</span></span><br><span class="line">  str = <span class="string">&#x27;\\u&#x27;</span> + str;</span><br><span class="line">  str = str.<span class="title function_">replace</span>(<span class="regexp">/\\/g</span>, <span class="string">&#x27;%&#x27;</span>);</span><br><span class="line">  <span class="comment">//转换中文</span></span><br><span class="line">  str = <span class="built_in">unescape</span>(str);</span><br><span class="line">  <span class="comment">//将其他受影响的转换回原来</span></span><br><span class="line">  str = str.<span class="title function_">replace</span>(<span class="regexp">/%/g</span>, <span class="string">&#x27;\\&#x27;</span>);</span><br><span class="line">  <span class="keyword">return</span> str;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">translateName</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="comment">// 中文</span></span><br><span class="line">  <span class="keyword">let</span> randomArr = [<span class="number">0x4e00</span>, <span class="number">0x9fa5</span>];</span><br><span class="line">  <span class="keyword">let</span> unicodeNum = <span class="string">&#x27;&#x27;</span>;</span><br><span class="line">  unicodeNum = <span class="title function_">randomAccess</span>(randomArr[<span class="number">0</span>], randomArr[<span class="number">1</span>]).<span class="title function_">toString</span>(<span class="number">16</span>);</span><br><span class="line">  <span class="keyword">let</span> result = <span class="title function_">decodeUnicode</span>(unicodeNum);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 获取到中文</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">translateName</span>());</span><br></pre></td></tr></table></figure><p>这样子虽然能得到中文，但是会得到很多偏僻字，比如<code>鈠 鑙</code>，为了防止这些偏僻字的出现，想到了可以按照中文的<code>笔画数</code>划分，一般来说笔画少的生僻字是会少很多的。<br><code>cnchar</code>这个 npm 包就是<code>可以识别汉字的笔画数的</code>。有了这个 npm 包，事半功倍了起来，当汉字的笔画数大于<code>10</code>就重新获取汉字，直到笔画数<code>少于10</code>为止。<br>后面我又加入了一些<code>日文</code>、<code>符合</code>和<code>阿拉伯数字</code>。</p><p>————–END——————-</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;最近老是抖音老是刷到一个小孩子玩数字华容道特别厉害，我感觉挺有趣的，就做了一个数字华容道，上班摸鱼可以玩，哈哈哈哈哈。  &lt;/p&gt;</summary>
    
    
    
    <category term="前端" scheme="https://blogwxb.cn/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="JavaScript" scheme="https://blogwxb.cn/tags/JavaScript/"/>
    
    <category term="pixi.js" scheme="https://blogwxb.cn/tags/pixi-js/"/>
    
  </entry>
  
  <entry>
    <title>pixijs＋webgl实现城市交通模拟</title>
    <link href="https://blogwxb.cn/pixijs%EF%BC%8Bwebgl%E5%AE%9E%E7%8E%B0%E5%9F%8E%E5%B8%82%E4%BA%A4%E9%80%9A%E6%A8%A1%E6%8B%9F/"/>
    <id>https://blogwxb.cn/pixijs%EF%BC%8Bwebgl%E5%AE%9E%E7%8E%B0%E5%9F%8E%E5%B8%82%E4%BA%A4%E9%80%9A%E6%A8%A1%E6%8B%9F/</id>
    <published>2022-10-27T10:34:48.000Z</published>
    <updated>2024-05-09T09:24:37.716Z</updated>
    
    <content type="html"><![CDATA[<h1 id="交通模拟器"><a href="#交通模拟器" class="headerlink" title="交通模拟器"></a>交通模拟器</h1><p>汽车的行驶以及等红绿灯的场景进行模拟，使用了<code>pixi</code>和<code>webgl</code>去实现的。<br>webgl主要是用在pixi中spite的<code>着色器</code>的编写。</p><span id="more"></span><h1 id="预览"><a href="#预览" class="headerlink" title="预览"></a>预览</h1><p><a href="https://deardreamweb.github.io/traffic_simulator.github.io/">github预览地址</a><br><a href="https://flyingwxb.gitee.io/traffic_simulator.gitee.io">gitee预览地址</a><br><a href="https://github.com/dearDreamWeb/traffic_simulator.github.io">github项目地址</a><br>如果感觉不错的话，给个star⭐️</p><h1 id="界面"><a href="#界面" class="headerlink" title="界面"></a>界面</h1><p><img data-src="https://resource.blogwxb.cn/traffic_simulator/QQ20221020-215230.gif" alt="功能"></p><h1 id="功能"><a href="#功能" class="headerlink" title="功能"></a>功能</h1><p><img data-src="https://resource.blogwxb.cn/traffic_simulator/screenshot_2.png" alt="功能标注"><br>👉🏻右侧区域： </p><ul><li>可以看到当前的帧率</li><li>暂停按钮可以让动画暂停，再次点击即可继续动画</li></ul><p>👈🏻左侧区域：<br>汽车的模式目前是有四种：<code>原始模式</code>、<code>多彩模式</code>、<code>多彩闪光模式</code>、<code>简笔画模式</code>。  </p><ul><li><code>多彩模式</code>是可以让原始的汽车颜色进行更换多种颜色的更换</li><li><code>多彩闪光模式</code>是让汽车颜色一直随机变</li><li><code>简笔画模式</code>是让汽车是简笔画的形态<br>这三部分是通过<code>pixi</code>的<code>sprite</code>用的<code>webgl</code>来写了一部分<code>sharder</code>完成的。</li></ul><p>🚗车辆管理区域：<br>目前就两款车型，可以控制道路上行驶的车辆类型，<code>禁用</code>可以让该类型的车辆不在道路上行驶，<code>启用</code>则是相反，允许该车辆行驶。</p><h1 id="技术实现"><a href="#技术实现" class="headerlink" title="技术实现"></a>技术实现</h1><p>首先车辆的行驶方向是上下左右四个方向，这四个方向的车辆我这里是采用了<code>链表</code>的数据结构。<br>为什么要使用链表这种数据结构呢？<br>回答：老子乐意！！！<br>其实是平时只有刷算法题的时候才用到链表，平时工作用不到，所以就想用用链表来实现。当然用<code>数组也能实现</code>。由于车辆要不断地删除添加的操作所以链表的效率会更高一些。这个项目中用到的链表也挺不难，就是链表的添加和删除，会这两个就能进行车辆的添加和删除。</p><h2 id="车辆添加"><a href="#车辆添加" class="headerlink" title="车辆添加"></a>车辆添加</h2><p>车辆是<code>pixijs</code>的<code>sprite</code>，每种类型的车辆都是分为<code>上下左右</code>四张图片。</p><p><img data-src="https://resource.blogwxb.cn/traffic_simulator/screenshot_3.png" alt="未命名.png"></p><p>添加车辆就是在链表的最后添加上sprite，存储数据是 <code>carData</code>，它是个useRef。是分为<code>left right top bottom</code>四个字段，代表四个方向，每个字段都是一个链表，是每个方向的车辆。根据每个方向要对sprite 进行x，y点进行初始化，根据前一个链表节点的x和y，计算添加车辆的x和y。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// direction ： 方向  WIDTH 画布的宽度 HEIGHT 画布的高度  ROADWIDTH 道路的宽度</span></span><br><span class="line"><span class="comment">// 该链表如果存在节点最后添加节点，没有节点直接放入</span></span><br><span class="line"><span class="keyword">if</span> (carData.<span class="property">current</span>[direction]) &#123;</span><br><span class="line">  <span class="keyword">let</span> current = carData.<span class="property">current</span>[direction]!;</span><br><span class="line">  <span class="comment">// 拿到最后一个节点</span></span><br><span class="line">  <span class="keyword">while</span> (current.<span class="property">next</span>) &#123;</span><br><span class="line">    current = current.<span class="property">next</span>!;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 根据最后一个节点计算出要添加节点的位置</span></span><br><span class="line">  <span class="keyword">switch</span> (direction) &#123;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">&#x27;left&#x27;</span>:</span><br><span class="line">      sprite.<span class="property">y</span> = (<span class="variable constant_">HEIGHT</span> - <span class="variable constant_">ROADWIDTH</span>) / <span class="number">2</span> + <span class="variable constant_">ROADWIDTH</span> / <span class="number">4</span>;</span><br><span class="line">      <span class="keyword">if</span> (current.<span class="property">val</span>.<span class="property">x</span> &gt;= <span class="variable constant_">WIDTH</span> - <span class="variable constant_">CARLENGTH</span> / <span class="number">2</span>) &#123;</span><br><span class="line">        sprite.<span class="property">x</span> = current.<span class="property">val</span>.<span class="property">x</span> + <span class="variable constant_">CARLENGTH</span> * <span class="number">1.5</span>;</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        sprite.<span class="property">x</span> = <span class="variable constant_">WIDTH</span> - <span class="variable constant_">CARLENGTH</span> / <span class="number">2</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">&#x27;right&#x27;</span>:</span><br><span class="line">      sprite.<span class="property">y</span> = <span class="variable constant_">HEIGHT</span> / <span class="number">2</span> + <span class="variable constant_">ROADWIDTH</span> / <span class="number">4</span>;</span><br><span class="line">      <span class="keyword">if</span> (current.<span class="property">val</span>.<span class="property">x</span> &lt;= -<span class="variable constant_">CARLENGTH</span> / <span class="number">2</span>) &#123;</span><br><span class="line">        sprite.<span class="property">x</span> = current.<span class="property">val</span>.<span class="property">x</span> - <span class="variable constant_">CARLENGTH</span> * <span class="number">1.5</span>;</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        sprite.<span class="property">x</span> = -<span class="variable constant_">CARLENGTH</span> / <span class="number">2</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">&#x27;top&#x27;</span>:</span><br><span class="line">      sprite.<span class="property">x</span> = <span class="variable constant_">WIDTH</span> / <span class="number">2</span> + <span class="variable constant_">ROADWIDTH</span> / <span class="number">4</span>;</span><br><span class="line">      <span class="keyword">if</span> (current.<span class="property">val</span>.<span class="property">y</span> &gt;= <span class="variable constant_">HEIGHT</span> + <span class="variable constant_">CARLENGTH</span> / <span class="number">2</span>) &#123;</span><br><span class="line">        sprite.<span class="property">y</span> = current.<span class="property">val</span>.<span class="property">y</span> + <span class="variable constant_">CARLENGTH</span> * <span class="number">1.5</span>;</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        sprite.<span class="property">y</span> = <span class="variable constant_">HEIGHT</span> + <span class="variable constant_">CARLENGTH</span> / <span class="number">2</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">&#x27;bottom&#x27;</span>:</span><br><span class="line">      sprite.<span class="property">x</span> = <span class="variable constant_">WIDTH</span> / <span class="number">2</span> - <span class="variable constant_">ROADWIDTH</span> / <span class="number">4</span>;</span><br><span class="line">      <span class="keyword">if</span> (current.<span class="property">val</span>.<span class="property">y</span> &lt;= -<span class="variable constant_">CARLENGTH</span> / <span class="number">2</span>) &#123;</span><br><span class="line">        sprite.<span class="property">y</span> = current.<span class="property">val</span>.<span class="property">y</span> - <span class="variable constant_">CARLENGTH</span> * <span class="number">1.5</span>;</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        sprite.<span class="property">y</span> = -<span class="variable constant_">CARLENGTH</span> / <span class="number">2</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">break</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  current.<span class="property">next</span> = <span class="keyword">new</span> <span class="title class_">ListNode</span>(sprite);</span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">  <span class="keyword">if</span> (direction === <span class="string">&#x27;left&#x27;</span>) &#123; <span class="comment">// 向左行驶的车辆位置</span></span><br><span class="line">    sprite.<span class="property">y</span> = (<span class="variable constant_">HEIGHT</span> - <span class="variable constant_">ROADWIDTH</span>) / <span class="number">2</span> + <span class="variable constant_">ROADWIDTH</span> / <span class="number">4</span>;</span><br><span class="line">    sprite.<span class="property">x</span> = <span class="variable constant_">WIDTH</span> - <span class="variable constant_">CARLENGTH</span> / <span class="number">2</span>;</span><br><span class="line">  &#125; <span class="keyword">else</span> <span class="keyword">if</span> (direction === <span class="string">&#x27;right&#x27;</span>) &#123; <span class="comment">// 向右行驶的车辆位置</span></span><br><span class="line">    sprite.<span class="property">y</span> = <span class="variable constant_">HEIGHT</span> / <span class="number">2</span> + <span class="variable constant_">ROADWIDTH</span> / <span class="number">4</span>;</span><br><span class="line">    sprite.<span class="property">x</span> = -<span class="variable constant_">CARLENGTH</span> / <span class="number">2</span>;</span><br><span class="line">  &#125; <span class="keyword">else</span> <span class="keyword">if</span> (direction === <span class="string">&#x27;top&#x27;</span>) &#123;  <span class="comment">// 向上行驶的车辆位置</span></span><br><span class="line">    sprite.<span class="property">x</span> = <span class="variable constant_">WIDTH</span> / <span class="number">2</span> + <span class="variable constant_">ROADWIDTH</span> / <span class="number">4</span>;</span><br><span class="line">    sprite.<span class="property">y</span> = <span class="variable constant_">HEIGHT</span> + <span class="variable constant_">CARLENGTH</span> / <span class="number">2</span>;</span><br><span class="line">  &#125; <span class="keyword">else</span> <span class="keyword">if</span> (direction === <span class="string">&#x27;bottom&#x27;</span>) &#123;  <span class="comment">// 向下行驶的车辆位置</span></span><br><span class="line">    sprite.<span class="property">x</span> = <span class="variable constant_">WIDTH</span> / <span class="number">2</span> - <span class="variable constant_">ROADWIDTH</span> / <span class="number">4</span>;</span><br><span class="line">    sprite.<span class="property">y</span> = -<span class="variable constant_">CARLENGTH</span> / <span class="number">2</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  carData.<span class="property">current</span>[direction] = <span class="keyword">new</span> <span class="title class_">ListNode</span>(sprite);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="车辆行驶"><a href="#车辆行驶" class="headerlink" title="车辆行驶"></a>车辆行驶</h2><p>车辆行驶需要考虑几点：</p><ul><li>当前面红灯怎么办？</li><li>后面的车辆要撞到前一个车辆怎么办？</li><li>为了灵活性，汽车什么时候加速，什么时候减速？</li></ul><p>下面一一解答：</p><ul><li>当为红灯的时候，下一步就要闯红灯了，这时需要让车辆停止，位置一直保持为原来的位置</li><li>后面的车要撞到前面的车，有两种情况：一种是前面的车在等红绿灯，另一种是都是行驶状态，后面车的车速大于前面车的车速。这时候需要设置一个<code>阈值 min</code>，当后车与前车的距离小于这个<code>min</code>的时候，需要让后车相对于前车速度进行减速，如果减速还是会小于这个<code>min</code>的话，说明前车在等红绿灯，这时候后车的位置等于这个<code>min</code>就行了，保证不小于这个<code>min</code>。</li><li>上面说设置一个车距之间的最小<code>阈值 min</code>，是为了让车减速，加速则是要设置车距之间的最大<code>阈值 max</code>，车距超过这个<code>max</code>就进行加速操作。<br>代码就不展示了，主要是链表的遍历去对每辆车进行计算。</li></ul><h2 id="车辆模式"><a href="#车辆模式" class="headerlink" title="车辆模式"></a>车辆模式</h2><p>因为<code>pixijs</code>默认是使用<code>webgl</code>去进行渲染的，<code>sprite</code>是<code>支持使用webgl编写着色器的</code>。根据选择的不同模式进行着色器sharder的编写完成的。  </p><p><code>多彩模式</code>：生成一个<code>随机的rgb</code>三个通道的值，然后到通过<code>uniform</code>传入到片元着色器与当前的色值进行<code>相乘</code>，深色部分打算是保留下来的，所以设置一个<code>阈值</code>，超过这个阈值代表<code>浅色</code>，浅色部分会去跟随机rgb进行相乘。</p><p><code>多彩闪光模式</code>：和多彩模式实现是一样的，区别是动画每帧都会使用多彩，所以有了多彩闪光的一个效果。</p><p><code>简笔画模式</code>：这个是我写多彩模式的sharder无意间实现出来的，原理也是很简单的，将浅色部分都变成白色，只留下深色部分，就是简笔画的效果。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 汽车颜色滤镜</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> <span class="variable">sprite</span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">carFilterColor</span> = (<span class="params">sprite: Sprite, type?: number</span>) =&gt; &#123;</span><br><span class="line">  <span class="keyword">const</span> fragStr = <span class="string">`</span></span><br><span class="line"><span class="string">    varying vec2 vTextureCoord;</span></span><br><span class="line"><span class="string">    uniform sampler2D uSampler;</span></span><br><span class="line"><span class="string">    uniform vec2 size;</span></span><br><span class="line"><span class="string">    uniform vec3 secondaryColor;</span></span><br><span class="line"><span class="string">    uniform float type;</span></span><br><span class="line"><span class="string">    </span></span><br><span class="line"><span class="string">    void main(void)&#123;</span></span><br><span class="line"><span class="string">      vec2 uv = size;</span></span><br><span class="line"><span class="string">      vec4 color = texture2D(uSampler, vTextureCoord);</span></span><br><span class="line"><span class="string">      // 阈值</span></span><br><span class="line"><span class="string">      float num = 0.3;</span></span><br><span class="line"><span class="string">      if(type != 0.0)&#123;</span></span><br><span class="line"><span class="string">        if(color.r &gt; num || color.g  &gt;= num || color.b &gt;= num)&#123;</span></span><br><span class="line"><span class="string">            if(type == 1.0 || type == 2.0 )&#123; / 多彩或多彩闪光模式</span></span><br><span class="line"><span class="string">                color.rgb *= secondaryColor;</span></span><br><span class="line"><span class="string">            &#125;else if (type == 3.0)&#123;  // 简笔画模式</span></span><br><span class="line"><span class="string">                color.rgb = vec3(1.0);</span></span><br><span class="line"><span class="string">            &#125;</span></span><br><span class="line"><span class="string">        &#125;</span></span><br><span class="line"><span class="string">        color.rgb = clamp(vec3(0.0),color.rgb,vec3(1.0));</span></span><br><span class="line"><span class="string">      &#125;</span></span><br><span class="line"><span class="string">      gl_FragColor = color;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">  `</span>;</span><br><span class="line">  <span class="keyword">let</span> filter = <span class="keyword">new</span> <span class="variable constant_">PIXI</span>.<span class="title class_">Filter</span>(<span class="literal">undefined</span>, fragStr, &#123;</span><br><span class="line">    <span class="attr">secondaryColor</span>: [</span><br><span class="line">      <span class="title class_">Math</span>.<span class="title function_">random</span>() + <span class="number">0.6</span>,</span><br><span class="line">      <span class="title class_">Math</span>.<span class="title function_">random</span>() + <span class="number">0.6</span>,</span><br><span class="line">      <span class="title class_">Math</span>.<span class="title function_">random</span>() + <span class="number">0.6</span>,</span><br><span class="line">    ],</span><br><span class="line">    <span class="attr">type</span>: type || <span class="number">0</span>,</span><br><span class="line">  &#125;);</span><br><span class="line">  sprite.<span class="property">filters</span> = [filter];</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>还有一些细节点就不一一赘述了，如：交通灯的设计和控制、车辆类型的控制等等。</p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;交通模拟器&quot;&gt;&lt;a href=&quot;#交通模拟器&quot; class=&quot;headerlink&quot; title=&quot;交通模拟器&quot;&gt;&lt;/a&gt;交通模拟器&lt;/h1&gt;&lt;p&gt;汽车的行驶以及等红绿灯的场景进行模拟，使用了&lt;code&gt;pixi&lt;/code&gt;和&lt;code&gt;webgl&lt;/code&gt;去实现的。&lt;br&gt;webgl主要是用在pixi中spite的&lt;code&gt;着色器&lt;/code&gt;的编写。&lt;/p&gt;</summary>
    
    
    
    <category term="娱乐" scheme="https://blogwxb.cn/categories/%E5%A8%B1%E4%B9%90/"/>
    
    
    <category term="pixi.js" scheme="https://blogwxb.cn/tags/pixi-js/"/>
    
    <category term="webgl" scheme="https://blogwxb.cn/tags/webgl/"/>
    
  </entry>
  
  <entry>
    <title>webgl实现ps混合模式第三章-强光,柔光,亮光,点光,线性光,实色混合,排除,差值</title>
    <link href="https://blogwxb.cn/webgl%E5%AE%9E%E7%8E%B0ps%E6%B7%B7%E5%90%88%E6%A8%A1%E5%BC%8F%E7%AC%AC%E4%B8%89%E7%AB%A0-%E5%BC%BA%E5%85%89-%E6%9F%94%E5%85%89-%E4%BA%AE%E5%85%89-%E7%82%B9%E5%85%89-%E7%BA%BF%E6%80%A7%E5%85%89-%E5%AE%9E%E8%89%B2%E6%B7%B7%E5%90%88-%E6%8E%92%E9%99%A4-%E5%B7%AE%E5%80%BC-%E7%9B%B8%E5%8A%A0-%E5%87%8F%E6%B3%95/"/>
    <id>https://blogwxb.cn/webgl%E5%AE%9E%E7%8E%B0ps%E6%B7%B7%E5%90%88%E6%A8%A1%E5%BC%8F%E7%AC%AC%E4%B8%89%E7%AB%A0-%E5%BC%BA%E5%85%89-%E6%9F%94%E5%85%89-%E4%BA%AE%E5%85%89-%E7%82%B9%E5%85%89-%E7%BA%BF%E6%80%A7%E5%85%89-%E5%AE%9E%E8%89%B2%E6%B7%B7%E5%90%88-%E6%8E%92%E9%99%A4-%E5%B7%AE%E5%80%BC-%E7%9B%B8%E5%8A%A0-%E5%87%8F%E6%B3%95/</id>
    <published>2022-09-08T22:04:25.000Z</published>
    <updated>2024-05-09T09:24:37.744Z</updated>
    
    <content type="html"><![CDATA[<p>本章的图片和之前两张的图替换一下，第一张是底层的图片，第二张图是进行混合模式的，这是png图片，空白的地方全是透明的。</p><div style="display:flex">    <img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/7f352606-e5b7-4a89-a02c-7e2b8d818148-1.png" height="200/">    <img data-src="https://cdn2.mihuiai.com/ff0ad43c-48e8-4b9a-9179-3ede5e9dab4f-10.png" height="200/"></div><span id="more"></span>公式图如下：<img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/7f352606-e5b7-4a89-a02c-7e2b8d818148-0.png" height="400/"><h1 id="叠加"><a href="#叠加" class="headerlink" title="叠加"></a>叠加</h1><p>叠加这里就需要进行进行各个通道也就是rgb的值是否小于<code>128</code>，在webgl中就是<code>0.5</code>，根据大小的判断去进行公式计算。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">const</span> FSHADER_SOURCE = `</span><br><span class="line">    precision mediump <span class="type">float</span>;</span><br><span class="line">    varying vec2 v_PointUV;</span><br><span class="line">    uniform sampler2D u_Image;</span><br><span class="line">    uniform sampler2D u_Image1;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 颜色计算</span></span><br><span class="line">    <span class="function"><span class="type">float</span> <span class="title">colorValue</span><span class="params">(<span class="type">float</span> color1, <span class="type">float</span> color2)</span></span>&#123;</span><br><span class="line">        <span class="type">float</span> value = <span class="number">0.0</span>;</span><br><span class="line">        <span class="keyword">if</span>(color1 &lt;= <span class="number">0.5</span>)&#123;</span><br><span class="line">            value = color1 * color2 / <span class="number">0.5</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            value = <span class="number">1.0</span> - (<span class="number">1.0</span>-color1) * (<span class="number">1.0</span>-color2)/<span class="number">0.5</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> value;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 底层图片颜色</span></span><br><span class="line">        vec4 baseColor = <span class="built_in">texture2D</span>(u_Image, v_PointUV);</span><br><span class="line">        <span class="comment">// 上层混合图片的颜色</span></span><br><span class="line">        vec4 blendColor = <span class="built_in">texture2D</span>(u_Image1, v_PointUV);</span><br><span class="line">        vec4 color = <span class="built_in">vec4</span>(<span class="number">1.0</span>);</span><br><span class="line"></span><br><span class="line">        color.r = <span class="built_in">colorValue</span>(baseColor.r,blendColor.r);</span><br><span class="line">        color.g = <span class="built_in">colorValue</span>(baseColor.g,blendColor.g);</span><br><span class="line">        color.b = <span class="built_in">colorValue</span>(baseColor.b,blendColor.b);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span>(blendColor.a == <span class="number">0.0</span>)&#123;</span><br><span class="line">            color = baseColor;</span><br><span class="line">        &#125;</span><br><span class="line">        gl_FragColor = color;</span><br><span class="line">    &#125;</span><br><span class="line">`;</span><br></pre></td></tr></table></figure><p>运行效果：<br><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/ff0ad43c-48e8-4b9a-9179-3ede5e9dab4f-1.png" height="200/"></p><h1 id="强光"><a href="#强光" class="headerlink" title="强光"></a>强光</h1><p>强光的判断是和叠加反着来的，shader就不写了，和上面的例子判断是相反的，效果图：<br><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/ff0ad43c-48e8-4b9a-9179-3ede5e9dab4f-2.png" height="200/"></p><h1 id="柔光"><a href="#柔光" class="headerlink" title="柔光"></a>柔光</h1><p>这里要用到<code>平方</code>和<code>根号</code>，glsl里面的内建的函数有这两种方法，分别是 <code>pow(x,y)</code>，<code>sqrt(x)</code>。pow代表x的次方。和js的表达意思差不多。<br>注意：下面公司用到的乘<code>2</code>，要写成<code>2.0</code>，因为之前声明的就是浮点数，所以所有的计算都是浮点数的计算。<br>代码如下：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">float</span> <span class="title">colorValue</span><span class="params">(<span class="type">float</span> color1, <span class="type">float</span> color2)</span></span>&#123;</span><br><span class="line">    <span class="type">float</span> value = <span class="number">0.0</span>;</span><br><span class="line">    <span class="keyword">if</span>(color2 &lt;= <span class="number">0.5</span>)&#123;</span><br><span class="line">        value = color1 * color2 / <span class="number">0.5</span> + <span class="built_in">pow</span>(color1,<span class="number">2.0</span>) * (<span class="number">1.0</span><span class="number">-2.0</span> * color2);</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        value = color1 *  (<span class="number">1.0</span> - color2)/<span class="number">0.5</span> + <span class="built_in">sqrt</span>(color1) * (<span class="number">2.0</span> * color2 - <span class="number">1.0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> value;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>效果图如下：<br><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/ff0ad43c-48e8-4b9a-9179-3ede5e9dab4f-3.png" height="200/"></p><h1 id="亮光"><a href="#亮光" class="headerlink" title="亮光"></a>亮光</h1><p>亮光也是需要做<code>0.5</code>的判断的，如下</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">float</span> <span class="title">colorValue</span><span class="params">(<span class="type">float</span> color1, <span class="type">float</span> color2)</span></span>&#123;</span><br><span class="line">    <span class="type">float</span> value = <span class="number">0.0</span>;</span><br><span class="line">    <span class="keyword">if</span>(color2 &lt;= <span class="number">0.5</span>)&#123;</span><br><span class="line">        value = color1 - (<span class="number">1.0</span> - color1) * (<span class="number">1.0</span> - <span class="number">2.0</span> * color2) / (<span class="number">2.0</span> * color2);</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        value = color1 + color1 * (<span class="number">2.0</span> * color2<span class="number">-1.0</span>) / (<span class="number">2.0</span> * (<span class="number">1.0</span> - color2)) ;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> value;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>效果图：<br><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/ff0ad43c-48e8-4b9a-9179-3ede5e9dab4f-4.png" height="200/"></p><h1 id="点光"><a href="#点光" class="headerlink" title="点光"></a>点光</h1><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">float</span> <span class="title">colorValue</span><span class="params">(<span class="type">float</span> color1, <span class="type">float</span> color2)</span></span>&#123;</span><br><span class="line">    <span class="type">float</span> value = <span class="number">0.0</span>;</span><br><span class="line">    <span class="keyword">if</span>(color2 &lt;= <span class="number">0.5</span>)&#123;</span><br><span class="line">        value = <span class="built_in">min</span>(color1,<span class="number">2.0</span> * color2);</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        value = <span class="built_in">max</span>(color1,<span class="number">2.0</span> * color2 - <span class="number">1.0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> value;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>效果：<br><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/ff0ad43c-48e8-4b9a-9179-3ede5e9dab4f-5.png" height="200/"></p><h1 id="线性光"><a href="#线性光" class="headerlink" title="线性光"></a>线性光</h1><p>线性光的效果和点光的差不多的，但是线性光的呈现效果会比点光的更亮一些。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">float</span> <span class="title">colorValue</span><span class="params">(<span class="type">float</span> color1, <span class="type">float</span> color2)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> color1 + color2 * <span class="number">2.0</span> - <span class="number">1.0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/ff0ad43c-48e8-4b9a-9179-3ede5e9dab4f-6.png" height="200/"><h1 id="实色混合"><a href="#实色混合" class="headerlink" title="实色混合"></a>实色混合</h1><p>实色混合这里代码要用到<code>三目运算符?:</code>   （实现效果和ps有点不一致）</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">float</span> <span class="title">colorValue</span><span class="params">(<span class="type">float</span> color1, <span class="type">float</span> color2)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> (color1 + color2) &gt;= <span class="number">1.0</span> ? <span class="number">1.0</span> : <span class="number">0.0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>效果图：<br><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/ff0ad43c-48e8-4b9a-9179-3ede5e9dab4f-7.png" height="200/"></p><h1 id="排除和差值"><a href="#排除和差值" class="headerlink" title="排除和差值"></a>排除和差值</h1><p>排除和差值的公式都很简单就放在一起了</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 排除</span></span><br><span class="line"><span class="function"><span class="type">float</span> <span class="title">colorValue</span><span class="params">(<span class="type">float</span> color1, <span class="type">float</span> color2)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> color1 + color2 - color1 * color2 / <span class="number">0.5</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 差值</span></span><br><span class="line"><span class="function"><span class="type">float</span> <span class="title">colorValue</span><span class="params">(<span class="type">float</span> color1, <span class="type">float</span> color2)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">abs</span>(color1 - color2);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>排除和差值效果如下：</p><div style="display:flex">    <img data-src="https://cdn2.mihuiai.com/ff0ad43c-48e8-4b9a-9179-3ede5e9dab4f-8.png" height="200/">    <img data-src="https://cdn2.mihuiai.com/ff0ad43c-48e8-4b9a-9179-3ede5e9dab4f-9.png" height="200/"></div>]]></content>
    
    
    <summary type="html">&lt;p&gt;本章的图片和之前两张的图替换一下，第一张是底层的图片，第二张图是进行混合模式的，这是png图片，空白的地方全是透明的。&lt;/p&gt;
&lt;div style=&quot;display:flex&quot;&gt;
    &lt;img data-src=&quot;https://lire.oss-cn-hangzhou.aliyuncs.com/7f352606-e5b7-4a89-a02c-7e2b8d818148-1.png&quot; height=&quot;200/&quot;&gt;
    &lt;img data-src=&quot;https://cdn2.mihuiai.com/ff0ad43c-48e8-4b9a-9179-3ede5e9dab4f-10.png&quot; height=&quot;200/&quot;&gt;
&lt;/div&gt;</summary>
    
    
    
    <category term="前端" scheme="https://blogwxb.cn/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="WebGl" scheme="https://blogwxb.cn/tags/WebGl/"/>
    
  </entry>
  
  <entry>
    <title>webgl实现ps混合模式第二章-变暗、变亮、颜色加深、颜色简单、线性加深、线性减淡</title>
    <link href="https://blogwxb.cn/webgl%E5%AE%9E%E7%8E%B0ps%E6%B7%B7%E5%90%88%E6%A8%A1%E5%BC%8F%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E5%8F%98%E6%9A%97%E3%80%81%E5%8F%98%E4%BA%AE%E3%80%81%E9%A2%9C%E8%89%B2%E5%8A%A0%E6%B7%B1%E3%80%81%E9%A2%9C%E8%89%B2%E7%AE%80%E5%8D%95%E3%80%81%E7%BA%BF%E6%80%A7%E5%8A%A0%E6%B7%B1%E3%80%81%E7%BA%BF%E6%80%A7%E5%87%8F%E6%B7%A1/"/>
    <id>https://blogwxb.cn/webgl%E5%AE%9E%E7%8E%B0ps%E6%B7%B7%E5%90%88%E6%A8%A1%E5%BC%8F%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E5%8F%98%E6%9A%97%E3%80%81%E5%8F%98%E4%BA%AE%E3%80%81%E9%A2%9C%E8%89%B2%E5%8A%A0%E6%B7%B1%E3%80%81%E9%A2%9C%E8%89%B2%E7%AE%80%E5%8D%95%E3%80%81%E7%BA%BF%E6%80%A7%E5%8A%A0%E6%B7%B1%E3%80%81%E7%BA%BF%E6%80%A7%E5%87%8F%E6%B7%A1/</id>
    <published>2022-08-28T10:34:06.000Z</published>
    <updated>2024-05-09T09:24:37.756Z</updated>
    
    <content type="html"><![CDATA[<p>接着上一章讲解，如果本章有些知识点和公式看不懂可以看一下<a href="/webgl%E5%AE%9E%E7%8E%B0ps%E6%B7%B7%E5%90%88%E6%A8%A1%E5%BC%8F%E7%AC%AC%E4%B8%80%E7%AB%A0-%E6%AD%A3%E7%89%87%E5%8F%A0%E5%BA%95%E3%80%81%E6%BB%A4%E8%89%B2" target="_blank">第一章</a>的讲解。</p><h1 id="变暗、变亮的实现"><a href="#变暗、变亮的实现" class="headerlink" title="变暗、变亮的实现"></a>变暗、变亮的实现</h1><p>这两个方案实现起来很简单，就是去两张图的<code>rgb</code>的<code>最小值</code>或<code>最大值</code>，直接上shader代码： </p><span id="more"></span><p>变暗shader代码：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">const</span> FSHADER_SOURCE = `</span><br><span class="line">    precision mediump <span class="type">float</span>;</span><br><span class="line">    varying vec2 v_PointUV;</span><br><span class="line">    uniform sampler2D u_Image;</span><br><span class="line">    uniform sampler2D u_Image1;</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 底层图片颜色</span></span><br><span class="line">        vec4 baseColor = <span class="built_in">texture2D</span>(u_Image, v_PointUV);</span><br><span class="line">        <span class="comment">// 上层混合图片的颜色</span></span><br><span class="line">        vec4 blendColor = <span class="built_in">texture2D</span>(u_Image1, v_PointUV);</span><br><span class="line">        vec4 color = <span class="built_in">vec4</span>(<span class="built_in">min</span>(baseColor.rgb,blendColor.rgb),<span class="built_in">max</span>(baseColor.a,blendColor.a));</span><br><span class="line">        gl_FragColor = color;</span><br><span class="line">    &#125;</span><br><span class="line">`;</span><br></pre></td></tr></table></figure><p>效果：<br><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/a1911228-d5bd-4f79-9113-190201aea47b-0.png" height="200/"></p><p>变亮shader代码：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">const</span> FSHADER_SOURCE = `</span><br><span class="line">    precision mediump <span class="type">float</span>;</span><br><span class="line">    varying vec2 v_PointUV;</span><br><span class="line">    uniform sampler2D u_Image;</span><br><span class="line">    uniform sampler2D u_Image1;</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 底层图片颜色</span></span><br><span class="line">        vec4 baseColor = <span class="built_in">texture2D</span>(u_Image, v_PointUV);</span><br><span class="line">        <span class="comment">// 上层混合图片的颜色</span></span><br><span class="line">        vec4 blendColor = <span class="built_in">texture2D</span>(u_Image1, v_PointUV);</span><br><span class="line">        vec4 color = <span class="built_in">vec4</span>(<span class="built_in">max</span>(baseColor,blendColor));</span><br><span class="line">        gl_FragColor = color;</span><br><span class="line">    &#125;</span><br><span class="line">`;</span><br></pre></td></tr></table></figure><p>效果:<br><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/a1911228-d5bd-4f79-9113-190201aea47b-1.png" height="200/"></p><h1 id="颜色加深、颜色减淡"><a href="#颜色加深、颜色减淡" class="headerlink" title="颜色加深、颜色减淡"></a>颜色加深、颜色减淡</h1><p>颜色加深、颜色减淡这两个功能都要用到<code>反相</code>，反相的计算方式是 <code>1.0减去rgb的颜色值</code><br>如： 底层图的反向就是 vec3(1.0)-baseColor.rgb<br>颜色加深的实现：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">const</span> FSHADER_SOURCE = `</span><br><span class="line">    precision mediump <span class="type">float</span>;</span><br><span class="line">    varying vec2 v_PointUV;</span><br><span class="line">    uniform sampler2D u_Image;</span><br><span class="line">    uniform sampler2D u_Image1;</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 底层图片颜色</span></span><br><span class="line">        vec4 baseColor = <span class="built_in">texture2D</span>(u_Image, v_PointUV);</span><br><span class="line">        <span class="comment">// 上层混合图片的颜色</span></span><br><span class="line">        vec4 blendColor = <span class="built_in">texture2D</span>(u_Image1, v_PointUV);</span><br><span class="line">        vec4 color = <span class="built_in">vec4</span>(baseColor.rgb-(<span class="built_in">vec3</span>(<span class="number">1.0</span>)-baseColor.rgb)*(<span class="built_in">vec3</span>(<span class="number">1.0</span>)-blendColor.rgb)/blendColor.rgb,<span class="number">1.0</span>);</span><br><span class="line">        <span class="keyword">if</span>(blendColor.a == <span class="number">0.0</span>)&#123;</span><br><span class="line">            color = baseColor;</span><br><span class="line">        &#125;</span><br><span class="line">        gl_FragColor = color;</span><br><span class="line">    &#125;</span><br><span class="line">`;</span><br></pre></td></tr></table></figure><p>效果：<br><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/a1911228-d5bd-4f79-9113-190201aea47b-2.png" height="200/"></p><p>颜色加深的实现：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">const</span> FSHADER_SOURCE = `</span><br><span class="line">    precision mediump <span class="type">float</span>;</span><br><span class="line">    varying vec2 v_PointUV;</span><br><span class="line">    uniform sampler2D u_Image;</span><br><span class="line">    uniform sampler2D u_Image1;</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 底层图片颜色</span></span><br><span class="line">        vec4 baseColor = <span class="built_in">texture2D</span>(u_Image, v_PointUV);</span><br><span class="line">        <span class="comment">// 上层混合图片的颜色</span></span><br><span class="line">        vec4 blendColor = <span class="built_in">texture2D</span>(u_Image1, v_PointUV);</span><br><span class="line">        vec4 color = <span class="built_in">vec4</span>(baseColor.rgb + (baseColor.rgb * blendColor.rgb/(<span class="built_in">vec3</span>(<span class="number">1.0</span>)-blendColor.rgb)),<span class="number">1.0</span>);</span><br><span class="line">        <span class="keyword">if</span>(blendColor.a == <span class="number">0.0</span>)&#123;</span><br><span class="line">            color = baseColor;</span><br><span class="line">        &#125;</span><br><span class="line">        gl_FragColor = color;</span><br><span class="line">    &#125;</span><br><span class="line">`;</span><br></pre></td></tr></table></figure><p>效果：<br><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/a1911228-d5bd-4f79-9113-190201aea47b-3.png" height="200/"></p><h1 id="线性加深和线性减淡"><a href="#线性加深和线性减淡" class="headerlink" title="线性加深和线性减淡"></a>线性加深和线性减淡</h1><p>线性加深和线性减淡是向量进行相加减的过程，需要用到<code>clamp()</code>函数进行范围限制。<br>clamp使用方法：<br><code>clamp (genType x, float minVal, float maxVal)</code><br>获取<code>x</code>和<code>minVal</code>之间<code>较大</code>的那个值，然后再拿较大的那个值和最后那个最大的值进行比较然后获取<code>较小</code>的那个，意思是x的取值范围是<code>[minVal,maxVal]</code>。<br>颜色加深代码如下：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">const</span> FSHADER_SOURCE = `</span><br><span class="line">    precision mediump <span class="type">float</span>;</span><br><span class="line">    varying vec2 v_PointUV;</span><br><span class="line">    uniform sampler2D u_Image;</span><br><span class="line">    uniform sampler2D u_Image1;</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 底层图片颜色</span></span><br><span class="line">        vec4 baseColor = <span class="built_in">texture2D</span>(u_Image, v_PointUV);</span><br><span class="line">        <span class="comment">// 上层混合图片的颜色</span></span><br><span class="line">        vec4 blendColor = <span class="built_in">texture2D</span>(u_Image1, v_PointUV);</span><br><span class="line">        vec4 color = <span class="built_in">vec4</span>(<span class="built_in">clamp</span>(baseColor.rgb+blendColor.rgb-<span class="built_in">vec3</span>(<span class="number">1.0</span>),<span class="built_in">vec3</span>(<span class="number">0.0</span>),<span class="built_in">vec3</span>(<span class="number">1.0</span>)),baseColor.a);</span><br><span class="line">        <span class="keyword">if</span>(blendColor.a == <span class="number">0.0</span>)&#123;</span><br><span class="line">            color = baseColor;</span><br><span class="line">        &#125;</span><br><span class="line">        gl_FragColor = color;</span><br><span class="line">    &#125;</span><br><span class="line">`;</span><br></pre></td></tr></table></figure><p>效果：<br><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/a1911228-d5bd-4f79-9113-190201aea47b-4.png" height="200/"></p><p>线性减淡效果：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">const</span> FSHADER_SOURCE = `</span><br><span class="line">    precision mediump <span class="type">float</span>;</span><br><span class="line">    varying vec2 v_PointUV;</span><br><span class="line">    uniform sampler2D u_Image;</span><br><span class="line">    uniform sampler2D u_Image1;</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 底层图片颜色</span></span><br><span class="line">        vec4 baseColor = <span class="built_in">texture2D</span>(u_Image, v_PointUV);</span><br><span class="line">        <span class="comment">// 上层混合图片的颜色</span></span><br><span class="line">        vec4 blendColor = <span class="built_in">texture2D</span>(u_Image1, v_PointUV);</span><br><span class="line">        vec4 color = <span class="built_in">vec4</span>(<span class="built_in">clamp</span>(baseColor.rgb+blendColor.rgb,<span class="built_in">vec3</span>(<span class="number">0.0</span>),<span class="built_in">vec3</span>(<span class="number">1.0</span>)),baseColor.a);</span><br><span class="line">        <span class="keyword">if</span>(blendColor.a == <span class="number">0.0</span>)&#123;</span><br><span class="line">            color = baseColor;</span><br><span class="line">        &#125;</span><br><span class="line">        gl_FragColor = color;</span><br><span class="line">    &#125;</span><br><span class="line">`;</span><br></pre></td></tr></table></figure><p>效果：<br><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/a1911228-d5bd-4f79-9113-190201aea47b-5.png" height="200/"></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;接着上一章讲解，如果本章有些知识点和公式看不懂可以看一下&lt;a href=&quot;/webgl%E5%AE%9E%E7%8E%B0ps%E6%B7%B7%E5%90%88%E6%A8%A1%E5%BC%8F%E7%AC%AC%E4%B8%80%E7%AB%A0-%E6%AD%A3%E7%89%87%E5%8F%A0%E5%BA%95%E3%80%81%E6%BB%A4%E8%89%B2&quot; target=&quot;_blank&quot;&gt;第一章&lt;/a&gt;的讲解。&lt;/p&gt;
&lt;h1 id=&quot;变暗、变亮的实现&quot;&gt;&lt;a href=&quot;#变暗、变亮的实现&quot; class=&quot;headerlink&quot; title=&quot;变暗、变亮的实现&quot;&gt;&lt;/a&gt;变暗、变亮的实现&lt;/h1&gt;&lt;p&gt;这两个方案实现起来很简单，就是去两张图的&lt;code&gt;rgb&lt;/code&gt;的&lt;code&gt;最小值&lt;/code&gt;或&lt;code&gt;最大值&lt;/code&gt;，直接上shader代码： &lt;/p&gt;</summary>
    
    
    
    <category term="前端" scheme="https://blogwxb.cn/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="WebGl" scheme="https://blogwxb.cn/tags/WebGl/"/>
    
  </entry>
  
  <entry>
    <title>webgl实现ps混合模式第一章~正片叠底、滤色</title>
    <link href="https://blogwxb.cn/webgl%E5%AE%9E%E7%8E%B0ps%E6%B7%B7%E5%90%88%E6%A8%A1%E5%BC%8F%E7%AC%AC%E4%B8%80%E7%AB%A0-%E6%AD%A3%E7%89%87%E5%8F%A0%E5%BA%95%E3%80%81%E6%BB%A4%E8%89%B2/"/>
    <id>https://blogwxb.cn/webgl%E5%AE%9E%E7%8E%B0ps%E6%B7%B7%E5%90%88%E6%A8%A1%E5%BC%8F%E7%AC%AC%E4%B8%80%E7%AB%A0-%E6%AD%A3%E7%89%87%E5%8F%A0%E5%BA%95%E3%80%81%E6%BB%A4%E8%89%B2/</id>
    <published>2022-08-18T10:24:34.000Z</published>
    <updated>2024-05-09T09:24:37.720Z</updated>
    
    <content type="html"><![CDATA[<h1 id="一、混合模式"><a href="#一、混合模式" class="headerlink" title="一、混合模式"></a>一、混合模式</h1><p>在ps中有很多的混合模式，如：正片叠底、滤色、变暗、变亮等等。下图为ps的算法公式图：<br><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/7f352606-e5b7-4a89-a02c-7e2b8d818148-0.png" height="400/"></p><span id="more"></span><h1 id="二、什么是正片叠底和滤色"><a href="#二、什么是正片叠底和滤色" class="headerlink" title="二、什么是正片叠底和滤色"></a>二、什么是正片叠底和滤色</h1><p>正片叠底简单的来说就是<code>“去白留黑”</code>，所谓的<code>“去白留黑”</code>的实现原理就是将两张图的<code>rgba相乘</code>，rgba的各个值的区间为<code>[0.0,1.0]</code>，1.0乘任何值还是任何值本身，所以白色就被去除掉了。<br>滤色和正片叠底是相反的，也就是<code>“去黑留白”</code>。</p><h1 id="三、正片叠底实现过程"><a href="#三、正片叠底实现过程" class="headerlink" title="三、正片叠底实现过程"></a>三、正片叠底实现过程</h1><p>下面例子中的两张图片原图为下面两个，第一张是效果图中的底图，第二张图是实现叠加效果的上层的图片</p><div style="display:flex">    <img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/7f352606-e5b7-4a89-a02c-7e2b8d818148-1.png" height="200/">    <img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/7f352606-e5b7-4a89-a02c-7e2b8d818148-2.png" height="200/"></div><p>这两个图片混合模式的顶点着色器都是一样的。<br>例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">const</span> VSHADER_SOURCE = `</span><br><span class="line">    attribute vec2 a_Position;    <span class="comment">// 顶点坐标</span></span><br><span class="line">    attribute vec2 a_PointUV;     <span class="comment">// 顶点UV</span></span><br><span class="line">    varying vec2 v_PointUV;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">        gl_Position = <span class="built_in">vec4</span>(a_Position,<span class="number">0.0</span>,<span class="number">1.0</span>);</span><br><span class="line">        v_PointUV = a_PointUV;</span><br><span class="line">    &#125;</span><br><span class="line">`;</span><br></pre></td></tr></table></figure><p>正片叠底的片元着色器为：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">const</span> FSHADER_SOURCE = `</span><br><span class="line">    precision mediump <span class="type">float</span>;</span><br><span class="line">    varying vec2 v_PointUV;</span><br><span class="line">    uniform sampler2D u_Image;</span><br><span class="line">    uniform sampler2D u_Image1;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        vec4 baseColor = <span class="built_in">texture2D</span>(u_Image, v_PointUV);</span><br><span class="line">        vec4 blendColor = <span class="built_in">texture2D</span>(u_Image1, v_PointUV);</span><br><span class="line">        gl_FragColor = blendColor * baseColor;</span><br><span class="line">    &#125;</span><br><span class="line">`;</span><br></pre></td></tr></table></figure><p>运行结果：<br><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/7f352606-e5b7-4a89-a02c-7e2b8d818148-3.png" height="200/"><br>这种两张都没有透明的部分的图片正片叠底的效果是没错的，但是，当混合模式的<code>图片部分有透明</code>的话就会导致下层的图片显示不出来，如下图：<br><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/7f352606-e5b7-4a89-a02c-7e2b8d818148-4.png" height="200/"></p><p>可以看的出来除了人物正片叠底了，人物之外透明部分是没有混合显示出来的。</p><h3 id="为什么呢？"><a href="#为什么呢？" class="headerlink" title="为什么呢？"></a>为什么呢？</h3><p>因为透明部分的<code>alpha值</code>是<code>0.0</code>，也就是rgba中的a是0.0，任何值乘以0.0都是0.0，所以下面的图片也就不显示了。</p><h3 id="怎么显示出来下面的图片？"><a href="#怎么显示出来下面的图片？" class="headerlink" title="怎么显示出来下面的图片？"></a>怎么显示出来下面的图片？</h3><p>判断上层图片的alpha值是否为0.0，若为0.0时，就显示下层图片的颜色值。改良过的片元着色器如下：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">const</span> FSHADER_SOURCE = `</span><br><span class="line">    precision mediump <span class="type">float</span>;</span><br><span class="line">    varying vec2 v_PointUV;</span><br><span class="line">    uniform sampler2D u_Image;</span><br><span class="line">    uniform sampler2D u_Image1;</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 底层图片颜色</span></span><br><span class="line">        vec4 baseColor = <span class="built_in">texture2D</span>(u_Image, v_PointUV);</span><br><span class="line">        <span class="comment">// 上层混合图片的颜色</span></span><br><span class="line">        vec4 blendColor = <span class="built_in">texture2D</span>(u_Image1, v_PointUV);</span><br><span class="line">        vec4 color = blendColor * baseColor + blendColor * (<span class="number">1.0</span> - baseColor.a) + baseColor * (<span class="number">1.0</span> - blendColor.a);</span><br><span class="line">        <span class="keyword">if</span>(blendColor.a == <span class="number">0.0</span>)&#123;</span><br><span class="line">            color = baseColor;</span><br><span class="line">        &#125;</span><br><span class="line">        gl_FragColor = color;</span><br><span class="line">    &#125;</span><br><span class="line">`;</span><br></pre></td></tr></table></figure><p>效果图如下：<br><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/7f352606-e5b7-4a89-a02c-7e2b8d818148-5.png" height="200/"></p><h1 id="滤色实现过程"><a href="#滤色实现过程" class="headerlink" title="滤色实现过程"></a>滤色实现过程</h1><p>滤色的片元着色器为：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">const</span> FSHADER_SOURCE = `</span><br><span class="line">    precision mediump <span class="type">float</span>;</span><br><span class="line">    varying vec2 v_PointUV;</span><br><span class="line">    uniform sampler2D u_Image;</span><br><span class="line">    uniform sampler2D u_Image1;</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 底层图片颜色</span></span><br><span class="line">        vec4 baseColor = <span class="built_in">texture2D</span>(u_Image, v_PointUV);</span><br><span class="line">        <span class="comment">// 上层混合图片的颜色</span></span><br><span class="line">        vec4 blendColor = <span class="built_in">texture2D</span>(u_Image1, v_PointUV);</span><br><span class="line">        vec4 color = <span class="built_in">vec4</span>(<span class="number">1.0</span>)-((<span class="built_in">vec4</span>(<span class="number">1.0</span>)-blendColor)*(<span class="built_in">vec4</span>(<span class="number">1.0</span>)-baseColor));</span><br><span class="line">        <span class="keyword">if</span>(blendColor.a == <span class="number">0.0</span>)&#123;</span><br><span class="line">            color = baseColor;</span><br><span class="line">        &#125;</span><br><span class="line">        gl_FragColor = color;</span><br><span class="line">    &#125;</span><br><span class="line">`;</span><br></pre></td></tr></table></figure><img data-src="https://lire.oss-cn-hangzhou.aliyuncs.com/7f352606-e5b7-4a89-a02c-7e2b8d818148-6.png" height="200/"><p>正片叠底完整代码片段：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> textureList = [];  </span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">VSHADER_SOURCE</span> = <span class="string">`</span></span><br><span class="line"><span class="string">    attribute vec2 a_Position;    // 顶点坐标</span></span><br><span class="line"><span class="string">    attribute vec2 a_PointUV;     // 顶点UV</span></span><br><span class="line"><span class="string">    varying vec2 v_PointUV;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">    void main()&#123;</span></span><br><span class="line"><span class="string">        gl_Position = vec4(a_Position,0.0,1.0);</span></span><br><span class="line"><span class="string">        v_PointUV = a_PointUV;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">`</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">FSHADER_SOURCE</span> = <span class="string">`</span></span><br><span class="line"><span class="string">    precision mediump float;</span></span><br><span class="line"><span class="string">    varying vec2 v_PointUV;</span></span><br><span class="line"><span class="string">    uniform sampler2D u_Image;</span></span><br><span class="line"><span class="string">    uniform sampler2D u_Image1;</span></span><br><span class="line"><span class="string">    void main() &#123;</span></span><br><span class="line"><span class="string">        // 底层图片颜色</span></span><br><span class="line"><span class="string">        vec4 baseColor = texture2D(u_Image, v_PointUV);</span></span><br><span class="line"><span class="string">        // 上层混合图片的颜色</span></span><br><span class="line"><span class="string">        vec4 blendColor = texture2D(u_Image1, v_PointUV);</span></span><br><span class="line"><span class="string">        vec4 color = blendColor * baseColor;</span></span><br><span class="line"><span class="string">        if(blendColor.a == 0.0)&#123;</span></span><br><span class="line"><span class="string">            color = baseColor;</span></span><br><span class="line"><span class="string">        &#125;</span></span><br><span class="line"><span class="string">        gl_FragColor = color;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">`</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> vShader = gl.<span class="title function_">createShader</span>(gl.<span class="property">VERTEX_SHADER</span>);</span><br><span class="line">gl.<span class="title function_">shaderSource</span>(vShader, <span class="variable constant_">VSHADER_SOURCE</span>);</span><br><span class="line">gl.<span class="title function_">compileShader</span>(vShader);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> fShader = gl.<span class="title function_">createShader</span>(gl.<span class="property">FRAGMENT_SHADER</span>);</span><br><span class="line">gl.<span class="title function_">shaderSource</span>(fShader, <span class="variable constant_">FSHADER_SOURCE</span>);</span><br><span class="line">gl.<span class="title function_">compileShader</span>(fShader);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> program = gl.<span class="title function_">createProgram</span>()</span><br><span class="line">gl.<span class="title function_">attachShader</span>(program, vShader) <span class="comment">// 添加顶点着色器</span></span><br><span class="line">gl.<span class="title function_">attachShader</span>(program, fShader) <span class="comment">// 添加片元着色器</span></span><br><span class="line">gl.<span class="title function_">linkProgram</span>(program) <span class="comment">// 连接 program 中的着色器</span></span><br><span class="line"></span><br><span class="line">gl.<span class="title function_">useProgram</span>(program) <span class="comment">// 告诉 WebGL 用这个 program 进行渲染</span></span><br><span class="line"><span class="keyword">const</span> bufferId = gl.<span class="title function_">createBuffer</span>();</span><br><span class="line">gl.<span class="title function_">bindBuffer</span>(gl.<span class="property">ARRAY_BUFFER</span>, bufferId);</span><br><span class="line"></span><br><span class="line"><span class="title function_">draw</span>()</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">random</span>(<span class="params">min, max</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> min + <span class="title class_">Math</span>.<span class="title function_">random</span>() * (max - min);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">draw</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">let</span> data = [</span><br><span class="line">        -<span class="number">1</span>, -<span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>,</span><br><span class="line">        <span class="number">1</span>, -<span class="number">1</span>, <span class="number">1</span>, <span class="number">0</span>,</span><br><span class="line">        <span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>,</span><br><span class="line">        <span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>,</span><br><span class="line">        -<span class="number">1</span>, <span class="number">1</span>, <span class="number">0</span>, <span class="number">1</span>,</span><br><span class="line">        -<span class="number">1</span>, -<span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>,</span><br><span class="line">    ];</span><br><span class="line">    data = <span class="keyword">new</span> <span class="title class_">Float32Array</span>(data)</span><br><span class="line">    <span class="keyword">await</span> <span class="title function_">loadTextureImage</span>(<span class="number">0</span>, <span class="string">&#x27;./images/1.jpeg&#x27;</span>)</span><br><span class="line">    <span class="keyword">await</span> <span class="title function_">loadTextureImage</span>(<span class="number">1</span>, <span class="string">&#x27;./images/0.jpeg&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> <span class="variable constant_">FSIZE</span> = data.<span class="property">BYTES_PER_ELEMENT</span>;</span><br><span class="line"></span><br><span class="line">    gl.<span class="title function_">bufferData</span>(gl.<span class="property">ARRAY_BUFFER</span>, data, gl.<span class="property">STATIC_DRAW</span>);</span><br><span class="line">    <span class="keyword">const</span> a_Position = gl.<span class="title function_">getAttribLocation</span>(program, <span class="string">&#x27;a_Position&#x27;</span>);</span><br><span class="line">    gl.<span class="title function_">vertexAttribPointer</span>(a_Position, <span class="number">2</span>, gl.<span class="property">FLOAT</span>, <span class="literal">false</span>, <span class="variable constant_">FSIZE</span> * <span class="number">4</span>, <span class="number">0</span>);</span><br><span class="line">    gl.<span class="title function_">enableVertexAttribArray</span>(a_Position);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> a_PointUV = gl.<span class="title function_">getAttribLocation</span>(program, <span class="string">&#x27;a_PointUV&#x27;</span>);</span><br><span class="line">    gl.<span class="title function_">vertexAttribPointer</span>(a_PointUV, <span class="number">2</span>, gl.<span class="property">FLOAT</span>, <span class="literal">false</span>, <span class="variable constant_">FSIZE</span> * <span class="number">4</span>, <span class="variable constant_">FSIZE</span> * <span class="number">2</span>);</span><br><span class="line">    gl.<span class="title function_">enableVertexAttribArray</span>(a_PointUV);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> u_Image = gl.<span class="title function_">getUniformLocation</span>(program, <span class="string">&quot;u_Image&quot;</span>);</span><br><span class="line">    gl.<span class="title function_">activeTexture</span>(gl.<span class="property">TEXTURE0</span> + <span class="number">0</span>);</span><br><span class="line">    gl.<span class="title function_">bindTexture</span>(gl.<span class="property">TEXTURE_2D</span>, textureList[<span class="number">0</span>]);</span><br><span class="line">    gl.<span class="title function_">uniform1i</span>(u_Image, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> u_Image1 = gl.<span class="title function_">getUniformLocation</span>(program, <span class="string">&quot;u_Image1&quot;</span>);</span><br><span class="line">    gl.<span class="title function_">activeTexture</span>(gl.<span class="property">TEXTURE0</span> + <span class="number">1</span>);</span><br><span class="line">    gl.<span class="title function_">bindTexture</span>(gl.<span class="property">TEXTURE_2D</span>, textureList[<span class="number">1</span>]);</span><br><span class="line">    gl.<span class="title function_">uniform1i</span>(u_Image1, <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> u_TranslateImage = gl.<span class="title function_">getUniformLocation</span>(program, <span class="string">&quot;u_TranslateImage&quot;</span>);</span><br><span class="line">    gl.<span class="title function_">uniform1f</span>(u_TranslateImage, translateNumber);</span><br><span class="line"></span><br><span class="line">    gl.<span class="title function_">clearColor</span>(<span class="number">1.0</span>, <span class="number">1.0</span>, <span class="number">1.0</span>, <span class="number">1.0</span>);</span><br><span class="line">    gl.<span class="title function_">clear</span>(gl.<span class="property">COLOR_BUFFER_BIT</span>);</span><br><span class="line">    gl.<span class="title function_">drawArrays</span>(gl.<span class="property">TRIANGLES</span>, <span class="number">0</span>, data.<span class="property">length</span> / <span class="number">4</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 判断是否是 2 的 整数次方</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">isPowerOf2</span>(<span class="params">value</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> (value &amp; (value - <span class="number">1</span>)) === <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">    * 加载纹理</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">loadTextureImage</span>(<span class="params">index, url</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve</span>) =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">const</span> img = <span class="keyword">new</span> <span class="title class_">Image</span>();</span><br><span class="line">        img.<span class="property">src</span> = url || <span class="string">&#x27;./images/0.jpeg&#x27;</span>;</span><br><span class="line">        img.<span class="property">crossOrigin</span> = <span class="string">&#x27;anonymous&#x27;</span></span><br><span class="line">        img.<span class="property">onload</span> = <span class="function">() =&gt;</span> &#123;</span><br><span class="line">            <span class="comment">// 在 WebGL 里创建一个 texture</span></span><br><span class="line">            <span class="keyword">let</span> texture = gl.<span class="title function_">createTexture</span>();</span><br><span class="line">            textureList.<span class="title function_">push</span>(texture)</span><br><span class="line">            gl.<span class="title function_">bindTexture</span>(gl.<span class="property">TEXTURE_2D</span>, texture);</span><br><span class="line">            gl.<span class="title function_">activeTexture</span>(gl.<span class="property">TEXTURE0</span> + index);</span><br><span class="line">            gl.<span class="title function_">bindTexture</span>(gl.<span class="property">TEXTURE_2D</span>, textureList[index])</span><br><span class="line">            gl.<span class="title function_">pixelStorei</span>(gl.<span class="property">UNPACK_FLIP_Y_WEBGL</span>, <span class="literal">true</span>);</span><br><span class="line">            gl.<span class="title function_">texImage2D</span>(gl.<span class="property">TEXTURE_2D</span>, <span class="number">0</span>, gl.<span class="property">RGBA</span>, gl.<span class="property">RGBA</span>, gl.<span class="property">UNSIGNED_BYTE</span>, img);</span><br><span class="line">            <span class="keyword">if</span> (<span class="title function_">isPowerOf2</span>(img.<span class="property">width</span>) &amp;&amp; <span class="title function_">isPowerOf2</span>(img.<span class="property">height</span>)) &#123;</span><br><span class="line">                gl.<span class="title function_">generateMipmap</span>(gl.<span class="property">TEXTURE_2D</span>);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;非2的整数次方&quot;</span>);</span><br><span class="line">                gl.<span class="title function_">texParameteri</span>(gl.<span class="property">TEXTURE_2D</span>, gl.<span class="property">TEXTURE_WRAP_S</span>, gl.<span class="property">CLAMP_TO_EDGE</span>);</span><br><span class="line">                gl.<span class="title function_">texParameteri</span>(gl.<span class="property">TEXTURE_2D</span>, gl.<span class="property">TEXTURE_WRAP_T</span>, gl.<span class="property">CLAMP_TO_EDGE</span>);</span><br><span class="line">                gl.<span class="title function_">texParameteri</span>(gl.<span class="property">TEXTURE_2D</span>, gl.<span class="property">TEXTURE_MIN_FILTER</span>, gl.<span class="property">LINEAR</span>);</span><br><span class="line">                gl.<span class="title function_">texParameteri</span>(gl.<span class="property">TEXTURE_2D</span>, gl.<span class="property">TEXTURE_MAG_FILTER</span>, gl.<span class="property">LINEAR</span>);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="title function_">resolve</span>(texture)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;一、混合模式&quot;&gt;&lt;a href=&quot;#一、混合模式&quot; class=&quot;headerlink&quot; title=&quot;一、混合模式&quot;&gt;&lt;/a&gt;一、混合模式&lt;/h1&gt;&lt;p&gt;在ps中有很多的混合模式，如：正片叠底、滤色、变暗、变亮等等。下图为ps的算法公式图：&lt;br&gt;&lt;img data-src=&quot;https://lire.oss-cn-hangzhou.aliyuncs.com/7f352606-e5b7-4a89-a02c-7e2b8d818148-0.png&quot; height=&quot;400/&quot;&gt;&lt;/p&gt;</summary>
    
    
    
    <category term="前端" scheme="https://blogwxb.cn/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="WebGl" scheme="https://blogwxb.cn/tags/WebGl/"/>
    
  </entry>
  
  <entry>
    <title>C++ 基础知识(6)--结构体</title>
    <link href="https://blogwxb.cn/C-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%866-%E7%BB%93%E6%9E%84%E4%BD%93/"/>
    <id>https://blogwxb.cn/C-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%866-%E7%BB%93%E6%9E%84%E4%BD%93/</id>
    <published>2022-08-08T09:48:06.000Z</published>
    <updated>2024-05-09T09:24:37.692Z</updated>
    
    <content type="html"><![CDATA[<h1 id="结构体"><a href="#结构体" class="headerlink" title="结构体"></a>结构体</h1><p>结构体<code>struct</code>是用来存放一组不同类型的数据。  </p><ol><li>声明结构体类型</li><li>定义变量名<span id="more"></span><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;string&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 1. 声明结构体类型Student</span></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Student</span> &#123;</span><br><span class="line">    string name;</span><br><span class="line">    <span class="type">int</span> age;</span><br><span class="line">    <span class="type">float</span> score;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">// 2.定义变量名</span></span><br><span class="line">    <span class="keyword">struct</span> <span class="title class_">Student</span> student = &#123;<span class="string">&quot;张三&quot;</span>,<span class="number">19</span>,<span class="number">80.0</span>&#125;;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;姓名：&quot;</span> &lt;&lt;student.name  &lt;&lt;endl; </span><br><span class="line">    cout&lt;&lt; <span class="string">&quot;年龄：&quot;</span> &lt;&lt; student.age  &lt;&lt;endl;  </span><br><span class="line">    cout&lt;&lt; <span class="string">&quot;分数：&quot;</span> &lt;&lt; student.score &lt;&lt;endl; </span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>运行结果：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">姓名：张三</span><br><span class="line">年龄：19</span><br><span class="line">分数：80</span><br></pre></td></tr></table></figure>结构体的初始化也可以使用<code>.</code>，如<code>student.name = &quot;张三&quot;;</code><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">#include &lt;iostream&gt;</span><br><span class="line">#include &lt;string&gt;</span><br><span class="line"></span><br><span class="line">using namespace std;</span><br><span class="line"></span><br><span class="line">struct Student &#123;</span><br><span class="line">    string name;</span><br><span class="line">    int age;</span><br><span class="line">    float score;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">int main()&#123;</span><br><span class="line">    struct Student student;</span><br><span class="line">    student.name = &quot;李四&quot;;</span><br><span class="line">    student.age = 18;</span><br><span class="line">    student.score = 90.2;</span><br><span class="line">    cout &lt;&lt; &quot;姓名：&quot; &lt;&lt;student.name  &lt;&lt;endl;</span><br><span class="line">    cout&lt;&lt; &quot;年龄：&quot; &lt;&lt; student.age  &lt;&lt;endl;</span><br><span class="line">    cout&lt;&lt; &quot;分数：&quot; &lt;&lt; student.score &lt;&lt;endl;</span><br><span class="line">    return  0;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>运行结果：<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">姓名：李四</span><br><span class="line">年龄：18</span><br><span class="line">分数：90.2</span><br></pre></td></tr></table></figure>如果想要定义多个变量名可以用<code>,</code>隔开。<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 定义Student结构体两个变量名</span></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Student</span> student,stundent1;</span><br></pre></td></tr></table></figure>如果是定义结构体变量名的话是可以省略关键字<code>struct</code>的,但是声明结构体是必须要带关键字<code>struct</code>。<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// struct 必须要有</span></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Student</span> &#123;</span><br><span class="line">    string name;</span><br><span class="line">    <span class="type">int</span> age;</span><br><span class="line">    <span class="type">float</span> score;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="comment">// struct 可以忽略</span></span><br><span class="line">Student student;</span><br></pre></td></tr></table></figure></li></ol><h1 id="结构体嵌套"><a href="#结构体嵌套" class="headerlink" title="结构体嵌套"></a>结构体嵌套</h1><p>结构体嵌套就是一个结构体里面的成员是另一个结构体。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;string&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> LEN = <span class="number">2</span>;</span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Student</span> &#123;</span><br><span class="line">    string name;</span><br><span class="line">    <span class="type">int</span> age;</span><br><span class="line">    <span class="type">float</span> score;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Teacher</span> &#123;</span><br><span class="line">    string name;</span><br><span class="line">    <span class="type">int</span> age;</span><br><span class="line">    Student students[LEN];  <span class="comment">// students成员代表Student结构体数组</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">struct</span> <span class="title class_">Teacher</span> teacher = &#123;</span><br><span class="line">        <span class="string">&quot;王老师&quot;</span>,<span class="number">37</span>,&#123;</span><br><span class="line">            &#123;<span class="string">&quot;张三&quot;</span>,<span class="number">19</span>,<span class="number">81.2</span>&#125;,</span><br><span class="line">            &#123;<span class="string">&quot;李四&quot;</span>,<span class="number">18</span>,<span class="number">66.6</span>&#125;,</span><br><span class="line">        &#125;,</span><br><span class="line">    &#125;;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;老师名字：&quot;</span> &lt;&lt; teacher.name &lt;&lt; endl;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;老师年龄：&quot;</span> &lt;&lt; teacher.age &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i&lt;LEN; i++) &#123;</span><br><span class="line">        cout&lt;&lt; <span class="string">&quot;学生姓名：&quot;</span> &lt;&lt; teacher.students[i].name &lt;&lt; <span class="string">&quot;\t学生年龄：&quot;</span> &lt;&lt;  teacher.students[i].age &lt;&lt; <span class="string">&quot;\t学生分数：&quot;</span> &lt;&lt; teacher.students[i].score &lt;&lt;endl;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">老师名字：王老师</span><br><span class="line">老师年龄：37</span><br><span class="line">学生姓名：张三学生年龄：19学生分数：81.2</span><br><span class="line">学生姓名：李四学生年龄：18学生分数：66.6</span><br></pre></td></tr></table></figure><h1 id="结构体与指针"><a href="#结构体与指针" class="headerlink" title="结构体与指针"></a>结构体与指针</h1><p>结构体赋值给指针，指针一样是可以指向该结构体的内存地址的。指针想访问或者修改结构体变量的值需要用到<code>-&gt;</code>。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;string&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Student</span> &#123;</span><br><span class="line">    string name;</span><br><span class="line">    <span class="type">int</span> age;</span><br><span class="line">    <span class="type">float</span> score;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line"><span class="comment">//    创建结构体变量</span></span><br><span class="line">    Student student=&#123;<span class="string">&quot;张三&quot;</span>,<span class="number">20</span>,<span class="number">45.1</span>&#125;;</span><br><span class="line"><span class="comment">//    通过指针指向结构体变量</span></span><br><span class="line">    Student * <span class="type">const</span> p = &amp;student;</span><br><span class="line"><span class="comment">//    通过指针访问结构体变量</span></span><br><span class="line">    cout &lt;&lt; p-&gt;name &lt;&lt; <span class="string">&quot;\t&quot;</span> &lt;&lt; p-&gt;age &lt;&lt; <span class="string">&quot;\t&quot;</span>&lt;&lt; p-&gt;score &lt;&lt; endl; <span class="comment">// 张三2045.1</span></span><br><span class="line">    </span><br><span class="line"><span class="comment">//    通过指针修改值</span></span><br><span class="line">    p-&gt;name = <span class="string">&quot;李四&quot;</span>;</span><br><span class="line">    p-&gt;age = <span class="number">22</span>;</span><br><span class="line">    p-&gt;score = <span class="number">35</span>;</span><br><span class="line"></span><br><span class="line">    cout &lt;&lt; p-&gt;name &lt;&lt; <span class="string">&quot;\t&quot;</span> &lt;&lt; p-&gt;age &lt;&lt; <span class="string">&quot;\t&quot;</span>&lt;&lt; p-&gt;score &lt;&lt; endl; <span class="comment">// 李四2235</span></span><br><span class="line">    cout &lt;&lt; student.name &lt;&lt; <span class="string">&quot;\t&quot;</span> &lt;&lt;student.age &lt;&lt; <span class="string">&quot;\t&quot;</span>&lt;&lt;student.score &lt;&lt; endl; <span class="comment">//李四2235</span></span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">张三2045.1</span><br><span class="line">李四2235</span><br><span class="line">李四2235</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;结构体&quot;&gt;&lt;a href=&quot;#结构体&quot; class=&quot;headerlink&quot; title=&quot;结构体&quot;&gt;&lt;/a&gt;结构体&lt;/h1&gt;&lt;p&gt;结构体&lt;code&gt;struct&lt;/code&gt;是用来存放一组不同类型的数据。  &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;声明结构体类型&lt;/li&gt;
&lt;li&gt;定义变量名&lt;/li&gt;&lt;/ol&gt;</summary>
    
    
    
    <category term="C++" scheme="https://blogwxb.cn/categories/C/"/>
    
    
    <category term="C++" scheme="https://blogwxb.cn/tags/C/"/>
    
  </entry>
  
  <entry>
    <title>C++ 基础知识(5)--指针</title>
    <link href="https://blogwxb.cn/C-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%865-%E6%8C%87%E9%92%88/"/>
    <id>https://blogwxb.cn/C-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%865-%E6%8C%87%E9%92%88/</id>
    <published>2022-07-20T14:46:58.000Z</published>
    <updated>2024-05-09T09:24:37.692Z</updated>
    
    <content type="html"><![CDATA[<h1 id="变量的内存地址"><a href="#变量的内存地址" class="headerlink" title="变量的内存地址"></a>变量的内存地址</h1><p>每一个变量都有一个内存位置，每一个内存位置都定义了可使用连字号<code>（&amp;）</code>运算符访问的地址，它表示了在内存中的一个地址。<br>例子：  </p><span id="more"></span><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span> <span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="type">int</span>  num;</span><br><span class="line">    <span class="type">bool</span> boolValue;</span><br><span class="line">    <span class="type">char</span> strArray[<span class="number">1</span>];</span><br><span class="line">    <span class="type">char</span> charValue;</span><br><span class="line">    <span class="type">char</span> caherValue1 = <span class="string">&#x27;a&#x27;</span>;</span><br><span class="line">    </span><br><span class="line">    cout &lt;&lt; &amp;num &lt;&lt; endl;</span><br><span class="line">    cout &lt;&lt; &amp;boolValue &lt;&lt; endl;</span><br><span class="line">    cout &lt;&lt; &amp;strArray &lt;&lt; endl;</span><br><span class="line">    cout &lt;&lt; &amp;charValue &lt;&lt; endl;</span><br><span class="line">    cout &lt;&lt; &amp;caherValue1 &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">0x16fdff238</span><br><span class="line">0x16fdff237</span><br><span class="line">0x16fdff236</span><br><span class="line"></span><br><span class="line">a</span><br></pre></td></tr></table></figure><p>可以发现当为<code>char类型</code>的时候是没有内存地址的，即使赋值了也只是显示赋值的内容，char数组是有内存地址的。</p><h1 id="什么是指针？"><a href="#什么是指针？" class="headerlink" title="什么是指针？"></a>什么是指针？</h1><p>指针的作用是指向内存地址，指针是一个变量。指针的声明方式为<code>type *name</code>，中文理解方式是<code>数据类型 指针的名字</code>。例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span>    *ip;    <span class="comment">/* 一个整型的指针 */</span></span><br><span class="line"><span class="type">double</span> *dp;    <span class="comment">/* 一个 double 型的指针 */</span></span><br><span class="line"><span class="type">float</span>  *fp;    <span class="comment">/* 一个浮点型的指针 */</span></span><br><span class="line"><span class="type">char</span>   *ch     <span class="comment">/* 一个字符型的指针 */</span></span><br></pre></td></tr></table></figure><p>什么是空指针？  </p><p>定义：指针变量指向内存中编号为0的空间。<br>用途：用来初始化指针<br>注意：空指针指向的内存不可访问  </p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span> <span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="comment">// 指针变量指向内存中编号为0的空间</span></span><br><span class="line">    <span class="type">int</span> * p = <span class="literal">NULL</span>;</span><br><span class="line">    </span><br><span class="line">    cout &lt;&lt; p &lt;&lt; endl;  <span class="comment">// 0x0</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 内存编号为0~255为系统占用内存，不允许用户访问</span></span><br><span class="line">    cout &lt;&lt; *p &lt;&lt; endl;  <span class="comment">// 报错</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>什么是野指针？<br>定义： 指针变量指向的是非法的内存编号   </p><p>比如 0x1100 内存编号并不存在，指针指向该地址就属于指向了非法的内存编号。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span> <span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="type">int</span> * p = (<span class="type">int</span> *)<span class="number">0x1100</span>;</span><br><span class="line">    </span><br><span class="line">    cout &lt;&lt; p &lt;&lt; endl;  <span class="comment">// 0x1100</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 访问野指针报错</span></span><br><span class="line">    cout &lt;&lt; *p &lt;&lt; endl; </span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="指针的用法"><a href="#指针的用法" class="headerlink" title="指针的用法"></a>指针的用法</h1><ol><li>声明一个指针变量</li><li>将一个变量的内存地址赋值给指针</li></ol><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span> <span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="type">int</span> num = <span class="number">10</span>;</span><br><span class="line">    <span class="type">int</span> * p = &amp;num;</span><br><span class="line">    cout &lt;&lt; *p &lt;&lt; endl;</span><br><span class="line">    </span><br><span class="line">    <span class="type">bool</span> boolValue = <span class="literal">false</span>;</span><br><span class="line">    <span class="type">bool</span> * p1 = &amp;boolValue;</span><br><span class="line">    cout &lt;&lt; *p1 &lt;&lt; endl;</span><br><span class="line">    </span><br><span class="line">    <span class="type">char</span> charValue = <span class="string">&#x27;a&#x27;</span>;</span><br><span class="line">    <span class="type">char</span> * p2 = &amp;charValue;</span><br><span class="line">    cout &lt;&lt; *p2 &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">10</span><br><span class="line">0</span><br><span class="line">a</span><br></pre></td></tr></table></figure><p>*p是值，p是内存地址</p><h2 id="const修饰指针"><a href="#const修饰指针" class="headerlink" title="const修饰指针"></a>const修饰指针</h2><p>const 修饰指针有三种情况：</p><ol><li>const修饰指针 — 常量指针</li><li>const修饰常量 — 指针常量</li><li>const即修饰指针，又修饰常量</li></ol><p>常量指针: 指针的指向可以改变，但指针指向的值不能更改。  </p><p>错误例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> num = <span class="number">10</span>;</span><br><span class="line"><span class="type">int</span> num1 = <span class="number">20</span>;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> * p = &amp;num;</span><br><span class="line">*p = <span class="number">20</span>;  <span class="comment">// 报错</span></span><br><span class="line">cout &lt;&lt; *p &lt;&lt; endl;</span><br></pre></td></tr></table></figure><p>正确例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> num = <span class="number">10</span>;</span><br><span class="line"><span class="type">int</span> num1 = <span class="number">20</span>;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> * p = &amp;num;</span><br><span class="line">p = &amp;num1;</span><br><span class="line">cout &lt;&lt; *p &lt;&lt; endl;  <span class="comment">// 20</span></span><br></pre></td></tr></table></figure><p>指针常量：指针的指向不可以改变，指针的指向的值可以更改。</p><p>错误例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> num = <span class="number">10</span>;</span><br><span class="line"><span class="type">int</span> num1 = <span class="number">20</span>;</span><br><span class="line"><span class="type">int</span> * <span class="type">const</span> p = &amp;num;</span><br><span class="line">p = &amp;num1; <span class="comment">// 报错</span></span><br><span class="line">cout &lt;&lt; *p &lt;&lt; endl;  </span><br></pre></td></tr></table></figure><p>正确例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> num = <span class="number">10</span>;</span><br><span class="line"><span class="type">int</span> num1 = <span class="number">20</span>;</span><br><span class="line"><span class="type">int</span> * <span class="type">const</span> p = &amp;num;</span><br><span class="line">*p =<span class="number">30</span>;</span><br><span class="line">cout &lt;&lt; *p &lt;&lt; endl;   <span class="comment">// 30</span></span><br></pre></td></tr></table></figure><p>const修饰指针和常量： 指针的指向和指向的值都不可以更改。 </p><p>错误例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> num = <span class="number">10</span>;</span><br><span class="line"><span class="type">int</span> num1 = <span class="number">20</span>;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> * <span class="type">const</span> p = &amp;num;</span><br><span class="line">p = &amp;num1; <span class="comment">// 报错</span></span><br><span class="line">*p = <span class="number">30</span>; <span class="comment">// 报错</span></span><br><span class="line">cout &lt;&lt; *p &lt;&lt; endl;  </span><br></pre></td></tr></table></figure><p>正确例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> num = <span class="number">10</span>;</span><br><span class="line"><span class="type">int</span> num1 = <span class="number">20</span>;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> * <span class="type">const</span> p = &amp;num;</span><br><span class="line">cout &lt;&lt; *p &lt;&lt; endl;   <span class="comment">// 10</span></span><br></pre></td></tr></table></figure><h2 id="指针和数组"><a href="#指针和数组" class="headerlink" title="指针和数组"></a>指针和数组</h2><p>当数组赋值给指针时，指针指向的是数组第一位的内存地址。可以通过 <code>++</code>，改变指针的指向。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> numArray[<span class="number">4</span>] = &#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>&#125;;</span><br><span class="line"><span class="type">int</span> * p = numArray;</span><br><span class="line">cout &lt;&lt; * p &lt;&lt; endl; <span class="comment">// 1</span></span><br><span class="line">    </span><br><span class="line">p++;</span><br><span class="line">cout &lt;&lt; * p &lt;&lt; endl; <span class="comment">// 2</span></span><br></pre></td></tr></table></figure><h2 id="指针与函数"><a href="#指针与函数" class="headerlink" title="指针与函数"></a>指针与函数</h2><p>在函数中用到指针是，在函数的形参中定义为指针类型。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 未使用指针的函数</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">test</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span></span>&#123;</span><br><span class="line">    <span class="type">int</span> temp = b;</span><br><span class="line">    b = a;</span><br><span class="line">    a = temp;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用指针的函数</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">test1</span><span class="params">(<span class="type">int</span> * a, <span class="type">int</span> * b)</span></span>&#123;</span><br><span class="line">    <span class="type">int</span> temp = * b;</span><br><span class="line">    * b = * a;</span><br><span class="line">    * a = temp;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">int</span> a = <span class="number">10</span>;</span><br><span class="line">    <span class="type">int</span> b = <span class="number">20</span>;</span><br><span class="line">    <span class="built_in">test</span>(a, b);</span><br><span class="line">    cout &lt;&lt; a &lt;&lt; endl;  <span class="comment">// 10</span></span><br><span class="line">    cout &lt;&lt; b &lt;&lt; endl;  <span class="comment">// 20</span></span><br><span class="line">    </span><br><span class="line">    <span class="built_in">test1</span>(&amp;a, &amp;b);</span><br><span class="line">    cout &lt;&lt; a &lt;&lt; endl;  <span class="comment">// 20</span></span><br><span class="line">    cout &lt;&lt; b &lt;&lt; endl;  <span class="comment">// 10</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>一旦使用指针作为形参接收值，指针修改指向的值，就会导致该内存地址的值改变。</p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;变量的内存地址&quot;&gt;&lt;a href=&quot;#变量的内存地址&quot; class=&quot;headerlink&quot; title=&quot;变量的内存地址&quot;&gt;&lt;/a&gt;变量的内存地址&lt;/h1&gt;&lt;p&gt;每一个变量都有一个内存位置，每一个内存位置都定义了可使用连字号&lt;code&gt;（&amp;amp;）&lt;/code&gt;运算符访问的地址，它表示了在内存中的一个地址。&lt;br&gt;例子：  &lt;/p&gt;</summary>
    
    
    
    <category term="C++" scheme="https://blogwxb.cn/categories/C/"/>
    
    
    <category term="C++" scheme="https://blogwxb.cn/tags/C/"/>
    
  </entry>
  
  <entry>
    <title>C++基础知识(4)--函数、分文件函数</title>
    <link href="https://blogwxb.cn/C-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%864-%E5%87%BD%E6%95%B0%E3%80%81%E5%88%86%E6%96%87%E4%BB%B6%E5%87%BD%E6%95%B0/"/>
    <id>https://blogwxb.cn/C-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%864-%E5%87%BD%E6%95%B0%E3%80%81%E5%88%86%E6%96%87%E4%BB%B6%E5%87%BD%E6%95%B0/</id>
    <published>2022-07-10T11:42:10.000Z</published>
    <updated>2024-05-09T09:24:37.692Z</updated>
    
    <content type="html"><![CDATA[<h1 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h1><p>函数的语法格式：<br><code> return_type  function_name(params)&#123;&#125;</code>换成更好理解的中文是<code>函数返回的类型  函数名(参数)&#123;&#125;</code>。<br>函数返回类型是根据函数里面最后的返回结果是什么，比如函数类型返回是int类型，那么函数类型就应该是int类型。</p><span id="more"></span><p>例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// return 返回后的类型是123，属于int类型，所以要用int类型去定义函数</span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">test</span> <span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">123</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 返回的字符char类型</span></span><br><span class="line"><span class="function"><span class="type">char</span> <span class="title">test1</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">&#x27;a&#x27;</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="如何调用函数？"><a href="#如何调用函数？" class="headerlink" title="如何调用函数？"></a>如何调用函数？</h2><p>直接函数名后面加上()，在括号里面加入对应的参数即可。 例子:</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">sum</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span>  a+b;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    cout &lt;&lt; <span class="built_in">sum</span>(<span class="number">1</span>,<span class="number">2</span>) &lt;&lt;endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>运行结果是：<code>3</code>  </p><p>需要注意的是函数定义要放到调用函数的前面，否则会报错。错误例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    cout &lt;&lt; <span class="built_in">sum</span>(<span class="number">1</span>,<span class="number">2</span>) &lt;&lt;endl;  <span class="comment">// 会报错</span></span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">sum</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span>  a+b;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>如果在调用前为定义函数怎么调用呢？<br>答案：可以提前声明函数。<br>例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 声明函数</span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">sum</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    cout &lt;&lt; <span class="built_in">sum</span>(<span class="number">1</span>,<span class="number">2</span>) &lt;&lt;endl; </span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义函数</span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">sum</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span>  a+b;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>运行结果是：<code>3</code>  </p><h1 id="分文件函数"><a href="#分文件函数" class="headerlink" title="分文件函数"></a>分文件函数</h1><p>函数分文件有两种：一种是.h头文件配合实现文件.cpp，一种是.hpp文件。  </p><h2 id="h头文件"><a href="#h头文件" class="headerlink" title=".h头文件"></a>.h头文件</h2><p>创建<code>一个.h头文件用来声明函数</code>和<code>一个.cpp实现文件用来定义.h文件声明的函数</code>。<br>例子：  </p><ol><li>创建一个名为<code>header.h</code>的文件，去声明函数:</li></ol><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 声明一个max函数</span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">max</span><span class="params">(<span class="type">int</span> a,<span class="type">int</span> b)</span></span>;</span><br></pre></td></tr></table></figure><ol start="2"><li>再创建一个名为<code>header.cpp</code> 文件，需要头文件引入一下刚才创建的<code>header.h</code> 文件</li></ol><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;header.h&quot;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义一个header.h文件中声明的max函数</span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">max</span><span class="params">(<span class="type">int</span> a,<span class="type">int</span> b)</span></span>&#123;</span><br><span class="line">    <span class="type">int</span> num = a &gt; b ? a : b;</span><br><span class="line">    <span class="keyword">return</span>  num;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ol start="3"><li>在源文件中引入<code>header.h</code> 文件，再调用<code>header.h</code> 文件中的声明的函数。<br>main.cpp文件：</li></ol><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;header.h&quot;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">// 调用再header.h 文件中声明的函数</span></span><br><span class="line">    cout &lt;&lt; <span class="built_in">max</span>(<span class="number">1</span>,<span class="number">2</span>) &lt;&lt;endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>运行结果：<code>2</code></p><h2 id="hpp"><a href="#hpp" class="headerlink" title=".hpp"></a>.hpp</h2><p>.hpp是C++程序头文件格式，.hpp文件的方式是将.cpp的实现代码混入.h头文件当中。<br>例子：<br>创建一个名为<code>header.hpp</code>文件</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">min</span><span class="params">(<span class="type">int</span> a,<span class="type">int</span> b)</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">min</span><span class="params">(<span class="type">int</span> a,<span class="type">int</span> b)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> a &lt; b ? a : b;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>在源文件main.cpp引入调用。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;header.hpp&quot;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">// 调用再header.h 文件中声明的函数</span></span><br><span class="line">    cout &lt;&lt; <span class="built_in">min</span>(<span class="number">1</span>,<span class="number">2</span>) &lt;&lt;endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>运行结果: <code>1</code></p><h1 id="h和-hpp的区别"><a href="#h和-hpp的区别" class="headerlink" title=".h和.hpp的区别"></a>.h和.hpp的区别</h1><p>.h里面可以有using namespace std，而.hpp里则无。 </p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;函数&quot;&gt;&lt;a href=&quot;#函数&quot; class=&quot;headerlink&quot; title=&quot;函数&quot;&gt;&lt;/a&gt;函数&lt;/h1&gt;&lt;p&gt;函数的语法格式：&lt;br&gt;&lt;code&gt; return_type  function_name(params)&amp;#123;&amp;#125;&lt;/code&gt;换成更好理解的中文是&lt;code&gt;函数返回的类型  函数名(参数)&amp;#123;&amp;#125;&lt;/code&gt;。&lt;br&gt;函数返回类型是根据函数里面最后的返回结果是什么，比如函数类型返回是int类型，那么函数类型就应该是int类型。&lt;/p&gt;</summary>
    
    
    
    <category term="C++" scheme="https://blogwxb.cn/categories/C/"/>
    
    
    <category term="C++" scheme="https://blogwxb.cn/tags/C/"/>
    
  </entry>
  
  <entry>
    <title>C++ 基础知识(3)--三目运算符、随机数、水仙花例子</title>
    <link href="https://blogwxb.cn/C-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%863-%E4%B8%89%E7%9B%AE%E8%BF%90%E7%AE%97%E7%AC%A6%E3%80%81%E9%9A%8F%E6%9C%BA%E6%95%B0%E3%80%81%E6%B0%B4%E4%BB%99%E8%8A%B1%E4%BE%8B%E5%AD%90/"/>
    <id>https://blogwxb.cn/C-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%863-%E4%B8%89%E7%9B%AE%E8%BF%90%E7%AE%97%E7%AC%A6%E3%80%81%E9%9A%8F%E6%9C%BA%E6%95%B0%E3%80%81%E6%B0%B4%E4%BB%99%E8%8A%B1%E4%BE%8B%E5%AD%90/</id>
    <published>2022-06-28T13:41:12.000Z</published>
    <updated>2024-05-09T09:24:37.692Z</updated>
    
    <content type="html"><![CDATA[<h1 id="三目运算符"><a href="#三目运算符" class="headerlink" title="三目运算符"></a>三目运算符</h1><p>三目运算符的格式是：<br><code>&lt;表达式1&gt; ? &lt;表达式2&gt; : &lt;表达式3&gt;</code><br>当<code>表达式1</code>为<code>true</code>时执行<code>表达式2</code>，当<code>表达式1</code>为<code>false</code>时执行<code>表达式3</code>。 </p><span id="more"></span>> <p>例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> num = <span class="number">5</span>;</span><br><span class="line"><span class="comment">// num &gt; 5 为false，执行num--</span></span><br><span class="line">num &gt; <span class="number">5</span> ? num ++ : num -- ;</span><br><span class="line">cout &lt;&lt; num &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> num1 = <span class="number">5</span>;</span><br><span class="line"><span class="comment">// num1 == 5 为true，执行num1++</span></span><br><span class="line">num1 == <span class="number">5</span> ? num1 ++ : num1 -- ;</span><br><span class="line">cout &lt;&lt; num1 &lt;&lt; endl;</span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">4</span><br><span class="line">6</span><br></pre></td></tr></table></figure><p>c++ 中的三目运算符可以<code>变量赋值</code>。<br>例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> a = <span class="number">0</span>;</span><br><span class="line"><span class="type">int</span> b = <span class="number">0</span>;</span><br><span class="line"><span class="comment">// 此时a&lt;=b 为true，所以给a赋值1</span></span><br><span class="line">(a&lt;=b ? a : b) = <span class="number">1</span>;</span><br><span class="line">cout &lt;&lt; a &lt;&lt; endl;</span><br><span class="line">    </span><br><span class="line"><span class="comment">// 此时a&lt;=b false，所以给b赋值2</span></span><br><span class="line">(a&lt;=b ? a : b) = <span class="number">2</span>;</span><br><span class="line">cout &lt;&lt; b &lt;&lt; endl;</span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td></tr></table></figure><h1 id="随机数"><a href="#随机数" class="headerlink" title="随机数"></a>随机数</h1><p>c++ 的随机数生成方式是<code>rand()</code>和<code>srand()</code>。<br>rand并不是真随机数，而是伪随机数。  </p><h2 id="rand"><a href="#rand" class="headerlink" title="rand()"></a>rand()</h2><p>使用rand()会获取到一个随机数，使用rand()是需要加上头文件<code>#include &lt;stdlib.h&gt;</code>的。取值范围是<code>0~2147483647</code>。<br>例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    cout &lt;&lt; <span class="built_in">rand</span>() &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>打印结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">16807</span><br></pre></td></tr></table></figure><p>注意： 只有第一次运行的时候才会随机，比如这次案例执行的结果是<code>16807</code>，你之后的在怎么运行都还是<code>16807</code>。原因是没有随机种子，所有需要用到<code>srand()</code>。</p><h2 id="srand"><a href="#srand" class="headerlink" title="srand()"></a>srand()</h2><p>初始化随机数发生器。srand需要生成一个整数，而且保证每次这个整数都不一样才行，否则每次生成的随机数会是一样的。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">unsigned</span> <span class="type">int</span> seed;</span><br><span class="line"><span class="built_in">srand</span>(seed);</span><br></pre></td></tr></table></figure><p>也就是要保证<code>seed</code>每次都是不一样的才能才产生随机数。可以使用当前时钟作为随机数种子，这里要用到<code>time()</code>，需要用到头文件<code>time.h</code>。<br>完整例子如下：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;time.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="built_in">srand</span>((<span class="type">unsigned</span> <span class="type">int</span>) <span class="built_in">time</span>(<span class="literal">NULL</span>));</span><br><span class="line">    cout &lt;&lt; <span class="built_in">rand</span>() &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这样运行就会出现不同的随机数。  </p><h3 id="选择随机数产生的范围"><a href="#选择随机数产生的范围" class="headerlink" title="选择随机数产生的范围"></a>选择随机数产生的范围</h3><p>要取得 <code>[a,b)</code> 的随机整数，使用 <code>(rand() % (b-a))+ a</code>;</p><p>要取得 <code>[a,b]</code> 的随机整数，使用 <code>(rand() % (b-a+1))+ a</code>;</p><p>要取得 <code>(a,b]</code> 的随机整数，使用 <code>(rand() % (b-a))+ a + 1</code>;</p><p>通用公式: <code>a + rand() % n</code>；其中的 a 是起始值，n 是整数的范围。</p><p>要取得 <code>a 到 b 之间的随机整数</code>，另一种表示：<code>a + (int)b * rand() / (RAND_MAX + 1)</code>。</p><p>要取得 <code>0～1 之间的浮点数</code>，可以使用 <code>rand() / double(RAND_MAX)</code>。</p><p>例子：</p><ul><li>获取[0,10)的范围<br><code>rand() % 10</code></li></ul><h1 id="水仙花例子"><a href="#水仙花例子" class="headerlink" title="水仙花例子"></a>水仙花例子</h1><p>水仙花数是指一个 <code>3 位数</code>，它的每个位上的数字的 3次幂之和等于它本身。例如：<code>1^3 + 5^3+ 3^3 = 153</code>。<br>找到所有三位数的水仙花数。  </p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;cmath&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> num =<span class="number">100</span>;num&lt;<span class="number">1000</span>;num++)&#123;</span><br><span class="line">        <span class="type">int</span> a = <span class="built_in">pow</span>(num / <span class="number">100</span>,<span class="number">3</span>);</span><br><span class="line">        <span class="type">int</span> b = <span class="built_in">pow</span>(num / <span class="number">10</span> % <span class="number">10</span>,<span class="number">3</span>);</span><br><span class="line">        <span class="type">int</span> c = <span class="built_in">pow</span>(num % <span class="number">10</span>,<span class="number">3</span>);</span><br><span class="line">        <span class="keyword">if</span>(a+b+c == num)&#123;</span><br><span class="line">            cout&lt;&lt;num&lt;&lt;endl;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这个例子中用到了<code>pow()</code>方法，就是求数的次幂(n^m)，第一次参数就是n，第二个参数就是m，m是几代表几次幂。需要头文件<code>cmath</code><br>例子：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">pow(5,2);  // 5 * 5 = 25</span><br><span class="line">pow(5,3);  // 5 * 5 * 5 = 125</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;三目运算符&quot;&gt;&lt;a href=&quot;#三目运算符&quot; class=&quot;headerlink&quot; title=&quot;三目运算符&quot;&gt;&lt;/a&gt;三目运算符&lt;/h1&gt;&lt;p&gt;三目运算符的格式是：&lt;br&gt;&lt;code&gt;&amp;lt;表达式1&amp;gt; ? &amp;lt;表达式2&amp;gt; : &amp;lt;表达式3&amp;gt;&lt;/code&gt;&lt;br&gt;当&lt;code&gt;表达式1&lt;/code&gt;为&lt;code&gt;true&lt;/code&gt;时执行&lt;code&gt;表达式2&lt;/code&gt;，当&lt;code&gt;表达式1&lt;/code&gt;为&lt;code&gt;false&lt;/code&gt;时执行&lt;code&gt;表达式3&lt;/code&gt;。 &lt;/p&gt;</summary>
    
    
    
    <category term="C++" scheme="https://blogwxb.cn/categories/C/"/>
    
    
    <category term="C++" scheme="https://blogwxb.cn/tags/C/"/>
    
  </entry>
  
  <entry>
    <title>C++基础知识(2)--转义字符、数据的输入、sizeof</title>
    <link href="https://blogwxb.cn/C-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86-%E8%BD%AC%E4%B9%89%E5%AD%97%E7%AC%A6%E3%80%81%E6%95%B0%E6%8D%AE%E7%9A%84%E8%BE%93%E5%85%A5%E3%80%81sizeof/"/>
    <id>https://blogwxb.cn/C-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86-%E8%BD%AC%E4%B9%89%E5%AD%97%E7%AC%A6%E3%80%81%E6%95%B0%E6%8D%AE%E7%9A%84%E8%BE%93%E5%85%A5%E3%80%81sizeof/</id>
    <published>2022-06-20T10:35:56.000Z</published>
    <updated>2024-05-09T09:24:37.692Z</updated>
    
    <content type="html"><![CDATA[<h1 id="转义字符"><a href="#转义字符" class="headerlink" title="转义字符"></a>转义字符</h1><p>转义字符是为了表达一些不能显示出来的ASCII字符。  常见的转义字符有 <code>\n</code>, <code>\\</code> ,<code>\t</code></p><span id="more"></span><table><thead><tr><th>转义字符</th><th>意义</th><th>ASCII码值（十进制）</th></tr></thead><tbody><tr><td>\a</td><td>响铃(BEL)</td><td>007</td></tr><tr><td>\b</td><td>退格(BS) ，将当前位置移到前一列</td><td>008</td></tr><tr><td>\f</td><td>换页(FF)，将当前位置移到下页开头</td><td>012</td></tr><tr><td>\n</td><td>换行(LF) ，将当前位置移到下一行开头</td><td>010</td></tr><tr><td>\r</td><td>回车(CR) ，将当前位置移到本行开头</td><td>013</td></tr><tr><td>\t</td><td>水平制表(HT) （跳到下一个TAB位置）</td><td>009</td></tr><tr><td>\v</td><td>垂直制表(VT)</td><td>011</td></tr><tr><td>\\</td><td>代表一个反斜线字符’’&#39;</td><td>092</td></tr><tr><td>\‘</td><td>代表一个单引号（撇号）字符</td><td>039</td></tr><tr><td>\“</td><td>代表一个双引号字符</td><td>034</td></tr><tr><td>?</td><td>代表一个问号</td><td>063</td></tr><tr><td>\0</td><td>空字符(NULL)</td><td>000</td></tr><tr><td>\ddd</td><td>1到3位八进制数所代表的任意字符</td><td>三位八进制</td></tr><tr><td>\xhh</td><td>1到2位十六进制所代表的任意字符</td><td>二位十六进制</td></tr></tbody></table><p>为什么要用到转义字符？<br>因为有些字符有特殊含义是没法正常的显示的，比如要打印字符串，字符串里面要包含<code>&quot;</code>，如果直接<code>&quot;&quot;&quot;</code>会报错的，错误例子：  </p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cout &lt;&lt; <span class="string">&quot;&quot;</span><span class="string">&quot; &lt;&lt; endl;</span></span><br></pre></td></tr></table></figure><p>所以就需要转义字符了，正确例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cout &lt;&lt; <span class="string">&quot;\&quot;&quot;</span> &lt;&lt; endl;</span><br></pre></td></tr></table></figure><p>比如<code>\n</code>这种是表示特殊含义的，就是<code>换行</code>的意思，如：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cout &lt;&lt; <span class="string">&quot;a\nb&quot;</span> &lt;&lt;endl;</span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">a</span><br><span class="line">b</span><br></pre></td></tr></table></figure><h1 id="数据的输入"><a href="#数据的输入" class="headerlink" title="数据的输入"></a>数据的输入</h1><p>cin和cout的区别：  </p><ul><li><p>cin 是 C++ 标准<code>输入流对象</code>，即 <code>istream</code> 类的对象。cin 主要用于从标准输入读取数据，这里的标准输入指<code>终端键盘</code>。</p></li><li><p>cout 是标准<code>输出流对象</code>，即 <code>ostream</code> 类的对象。cerr 是标准错误输出流对象，也是 ostream 类的对象。</p></li></ul><p>之前一直都是用cout去输出数据，下面是用cin去终端输入数据，改变程序中的变量。  </p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> a = <span class="number">10</span>;</span><br><span class="line">cin &gt;&gt; a;   <span class="comment">// 输入a的值</span></span><br><span class="line">cout &lt;&lt; <span class="string">&quot;a的值为：&quot;</span> &lt;&lt; a &lt;&lt; endl;</span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">20   // 先输入20，按下回车键就看到改变后的a的值了</span><br><span class="line">a的值为：20</span><br></pre></td></tr></table></figure><p>cin 也可以连续输入： </p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> a = <span class="number">10</span>;</span><br><span class="line"><span class="type">int</span> b = <span class="number">10</span>;</span><br><span class="line"><span class="type">int</span> c = <span class="number">10</span>;</span><br><span class="line">cin &gt;&gt; a &gt;&gt; b &gt;&gt; c;</span><br><span class="line">cout &lt;&lt; a &lt;&lt; <span class="string">&quot;-&quot;</span> &lt;&lt; b &lt;&lt; <span class="string">&quot;-&quot;</span> &lt;&lt; c &lt;&lt; endl;</span><br></pre></td></tr></table></figure><p>运行结果：<br>在终端三次分别输入1、2、3  </p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">1-2-3</span><br></pre></td></tr></table></figure><h1 id="sizeof运算符"><a href="#sizeof运算符" class="headerlink" title="sizeof运算符"></a>sizeof运算符</h1><p>sizeof用于判断变量或数据类型的字节大小。<br>查看变量的字节大小：  </p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> a = <span class="number">10</span>;</span><br><span class="line"><span class="type">short</span> b = <span class="number">10</span>;</span><br><span class="line"><span class="type">long</span> c = <span class="number">10</span>;</span><br><span class="line"><span class="type">char</span> d = <span class="string">&#x27;c&#x27;</span>;</span><br><span class="line"><span class="type">bool</span> e = <span class="literal">true</span>;</span><br><span class="line"></span><br><span class="line">cout &lt;&lt; <span class="built_in">sizeof</span>(a) &lt;&lt; endl;</span><br><span class="line">cout &lt;&lt; <span class="built_in">sizeof</span>(b) &lt;&lt; endl;</span><br><span class="line">cout &lt;&lt; <span class="built_in">sizeof</span>(c) &lt;&lt; endl;</span><br><span class="line">cout &lt;&lt; <span class="built_in">sizeof</span>(d) &lt;&lt; endl;</span><br><span class="line">cout &lt;&lt; <span class="built_in">sizeof</span>(e) &lt;&lt; endl;</span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">4</span><br><span class="line">2</span><br><span class="line">8</span><br><span class="line">1</span><br><span class="line">1</span><br></pre></td></tr></table></figure><p>直接查看数据类型的字节大小，和看变量结果是一样的。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">cout &lt;&lt; <span class="built_in">sizeof</span>(<span class="type">int</span>) &lt;&lt; endl;</span><br><span class="line">cout &lt;&lt; <span class="built_in">sizeof</span>(<span class="type">short</span>) &lt;&lt; endl;</span><br><span class="line">cout &lt;&lt; <span class="built_in">sizeof</span>(<span class="type">long</span>) &lt;&lt; endl;</span><br><span class="line">cout &lt;&lt; <span class="built_in">sizeof</span>(<span class="type">char</span>) &lt;&lt; endl;</span><br><span class="line">cout &lt;&lt; <span class="built_in">sizeof</span>(<span class="type">bool</span>) &lt;&lt; endl;</span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">4</span><br><span class="line">2</span><br><span class="line">8</span><br><span class="line">1</span><br><span class="line">1</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;转义字符&quot;&gt;&lt;a href=&quot;#转义字符&quot; class=&quot;headerlink&quot; title=&quot;转义字符&quot;&gt;&lt;/a&gt;转义字符&lt;/h1&gt;&lt;p&gt;转义字符是为了表达一些不能显示出来的ASCII字符。  常见的转义字符有 &lt;code&gt;\n&lt;/code&gt;, &lt;code&gt;\\&lt;/code&gt; ,&lt;code&gt;\t&lt;/code&gt;&lt;/p&gt;</summary>
    
    
    
    <category term="C++" scheme="https://blogwxb.cn/categories/C/"/>
    
    
    <category term="C++" scheme="https://blogwxb.cn/tags/C/"/>
    
  </entry>
  
  <entry>
    <title>C++基础知识(1)--变量、数据类型、打印</title>
    <link href="https://blogwxb.cn/C-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86-%E5%8F%98%E9%87%8F%E3%80%81%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E3%80%81%E6%89%93%E5%8D%B0/"/>
    <id>https://blogwxb.cn/C-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86-%E5%8F%98%E9%87%8F%E3%80%81%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E3%80%81%E6%89%93%E5%8D%B0/</id>
    <published>2022-06-09T23:27:16.000Z</published>
    <updated>2024-05-09T09:24:37.692Z</updated>
    
    <content type="html"><![CDATA[<p>本篇博客对于c++的基础知识讲解适用于有其他语言基础的人群，如JavaScript、Java、C等。因此有些简单的东西而且相对于其他语言来讲用法是一模一样就不会记录下来了，比如<code>if语句</code>、<code>while语句</code>、<code>switch语句</code>等等。<br>博主是从事web前端这个岗位的，所以对于C++的专业知识没有比较深的理解，有些点讲解的也不是很到位，只是自己学习时候的记录笔记，可以评论留言讨论学习。</p><h1 id="打印"><a href="#打印" class="headerlink" title="打印"></a>打印</h1><p>以<code>cout</code>开始，以<code>endl</code>结尾，<code>&lt;&lt;</code>展示打印信息，由于c++对代码规范要求严格，所以需要写<code>;</code>结尾，否则报错。具体打印代码如：<br><code>cout &lt;&lt; &quot;hello world&quot; &lt;&lt; endl;</code>    </p><span id="more"></span><p>完整例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;hello world&quot;</span>  &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><code>endl</code>代表着打印换行，也就是下一个打印结果会再下一行打印出来。<br>无endl例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;hello&quot;</span> ;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;world&quot;</span> ;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>打印结果就是</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">helloworld</span><br></pre></td></tr></table></figure><p>有endl例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;hello&quot;</span> &lt;&lt; endl;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;world&quot;</span> &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>打印结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">hello</span><br><span class="line">world</span><br></pre></td></tr></table></figure><p>后面讲到变量再介绍如何打印变量。</p><h1 id="变量和常量"><a href="#变量和常量" class="headerlink" title="变量和常量"></a>变量和常量</h1><p>变量是先声明一个变量，然后可以根据声明的类型进行赋值对应的类型。如：  </p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">int</span> a = <span class="number">1</span>;</span><br><span class="line">    cout &lt;&lt; a  &lt;&lt; endl;</span><br><span class="line">    a=<span class="number">2</span>;</span><br><span class="line">    cout &lt;&lt; a  &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td></tr></table></figure><p>int声明的是整型类型并赋值了1，然后第二次赋值了2。</p><p>常量是不可以修改的，变量是可以的，常量的声明有两种方式。</p><ul><li>使用 <code>#define</code> 预处理器。  </li><li>使用 <code>const</code> 关键字。</li></ul><p>#define 预处理器一般是在文件的开头定义常量。  </p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> DAY 7</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    cout &lt;&lt; DAY  &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">7</span><br></pre></td></tr></table></figure><p>const 在声明类型之前使用，就规定了该值是常量。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">const</span> <span class="type">int</span> DAY = <span class="number">7</span>;</span><br><span class="line">    cout &lt;&lt; DAY  &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">7</span><br></pre></td></tr></table></figure><p>错误例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">const</span> <span class="type">int</span> DAY = <span class="number">7</span>;</span><br><span class="line">    DAY = <span class="number">8</span>;  <span class="comment">// 错误，不能重新赋值</span></span><br><span class="line">    cout &lt;&lt; DAY  &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="数据类型"><a href="#数据类型" class="headerlink" title="数据类型"></a>数据类型</h1><p>本文介绍的数据类型有：整型、字符型、字符串型、浮点型、布尔型</p><h2 id="整型"><a href="#整型" class="headerlink" title="整型"></a>整型</h2><p>整型也就是数字。整型分为：short(短整型)、int(整型)、long长短整型)、long long(长整型)。类型不同，所占的内存空间不同，表示的数字范围不一样。  </p><table><thead><tr><th>整型类型</th><th>占用空间</th><th>取值范围</th></tr></thead><tbody><tr><td>short(短整型)</td><td>2字节</td><td>-2^15 ~ 2^15-1</td></tr><tr><td>int(整型)</td><td>4字节</td><td>-2^31 ~ 2^31-1</td></tr><tr><td>long长短整型)</td><td>windows为4字节，linux为4字节（32位），8字节(64位)</td><td>-2^31 ~ 2^31-1</td></tr><tr><td>long long(长整型)</td><td>8字节</td><td>-2^63 ~ 2^63-1</td></tr><tr><td>最常使用的整型是<code>int</code>。</td><td></td><td></td></tr><tr><td>例子：</td><td></td><td></td></tr></tbody></table><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">short</span> a = <span class="number">0</span>;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;a的值为：&quot;</span> &lt;&lt; a &lt;&lt;endl;</span><br><span class="line">    <span class="type">int</span>  b  = <span class="number">1</span>;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;b的值为：&quot;</span> &lt;&lt; b &lt;&lt;endl;</span><br><span class="line">    <span class="type">long</span> c = <span class="number">2</span>;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;c的值为：&quot;</span> &lt;&lt; c &lt;&lt;endl;</span><br><span class="line">    <span class="type">long</span> <span class="type">long</span> d =<span class="number">3</span>;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;d的值为：&quot;</span> &lt;&lt; d &lt;&lt;endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">a的值为：0</span><br><span class="line">b的值为：1</span><br><span class="line">c的值为：2</span><br><span class="line">d的值为：3</span><br></pre></td></tr></table></figure><p>这样是好像是没有问题的，但是如果赋值的数值大过定义的范围就无法得到赋值的数值，如short的取值范围是<code>-2^15 ~ 2^15-1</code>，也就是<code>-32768 到 32767</code>。如果使用short赋值 32768 是得不到该值的。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">short</span> a = <span class="number">32768</span>;</span><br><span class="line">    cout &lt;&lt; a &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">-32768</span><br></pre></td></tr></table></figure><h2 id="字符型"><a href="#字符型" class="headerlink" title="字符型"></a>字符型</h2><p>字符型的声明关键词是<code>char</code>，例子如下：  </p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">char</span> str = <span class="string">&#x27;a&#x27;</span>;</span><br><span class="line">    cout &lt;&lt; str  &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>注意：</p><ol><li>char声明的字符型只能使用单引号，用双引号会报错。</li><li>char声明的是字符型，也就是单引号里面只能有一个字符，多个字符是错误的。如错误例子：<code>char str = &#39;abc&#39;</code>，abc就属于多个字符了。</li></ol><h2 id="字符串型"><a href="#字符串型" class="headerlink" title="字符串型"></a>字符串型</h2><p>上面提到的字符型是只能有一个字符的，字符串类型的数据就可以有多个字符了。c++是继承了c的风格，所以字符串类型可以和c的一样，如：  </p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">char</span> str[] = <span class="string">&quot;abc&quot;</span>;</span><br><span class="line">    cout &lt;&lt; str  &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>运行结果：  </p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">abc</span><br></pre></td></tr></table></figure><p>也可以使用c++标准库提供的string类型去声明字符串类型。需要在开头引入string类，如：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;string&gt;</span> <span class="comment">// 引入string类</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    string str = <span class="string">&quot;abc&quot;</span>;</span><br><span class="line">    cout &lt;&lt; str  &lt;&lt; endl;</span><br><span class="line">    </span><br><span class="line">    string str1 = <span class="string">&quot;df&quot;</span>;</span><br><span class="line">    cout &lt;&lt; str1  &lt;&lt; endl;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 拼接字符串</span></span><br><span class="line">    string str2=str + str1;</span><br><span class="line">    cout &lt;&lt; str2  &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">abc</span><br><span class="line">df</span><br><span class="line">abcdf</span><br></pre></td></tr></table></figure><h2 id="布尔类型"><a href="#布尔类型" class="headerlink" title="布尔类型"></a>布尔类型</h2><p>布尔类型只有两个值： <code>true</code> 和 <code>false</code> 。  </p><ul><li>true 真（本质就是1）</li><li>false 假 （本质就是0）</li></ul><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">bool</span> flag = <span class="literal">true</span>;</span><br><span class="line">    cout &lt;&lt; flag &lt;&lt; endl;</span><br><span class="line">    flag = <span class="literal">false</span>;</span><br><span class="line">    cout &lt;&lt; flag &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">1</span><br><span class="line">0</span><br></pre></td></tr></table></figure><h2 id="浮点型"><a href="#浮点型" class="headerlink" title="浮点型"></a>浮点型</h2><p>浮点型就是小数，分为<code>单精度float</code>和<code>双精度double</code>。二者区别是有效数字范围不同。  </p><table><thead><tr><th>数据类型</th><th>占用空间</th><th>有效数字范围</th></tr></thead><tbody><tr><td>float</td><td>4字节</td><td>7位有效数字</td></tr><tr><td>double</td><td>8字节</td><td>15~16位有效数字</td></tr></tbody></table><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">float</span> f = <span class="number">3.14f</span>;</span><br><span class="line">    cout &lt;&lt; f &lt;&lt; endl;</span><br><span class="line">    </span><br><span class="line">    <span class="type">double</span> d = <span class="number">3.14</span>;</span><br><span class="line">    cout &lt;&lt; d &lt;&lt; endl;</span><br><span class="line">    </span><br><span class="line">    <span class="type">float</span> f1 = <span class="number">3.1415926f</span>;</span><br><span class="line">    cout &lt;&lt; f1 &lt;&lt; endl;</span><br><span class="line">    </span><br><span class="line">    <span class="type">double</span> d1 = <span class="number">3.1415926</span>;</span><br><span class="line">    cout &lt;&lt; d1 &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span>  <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>打印结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">3.14</span><br><span class="line">3.14</span><br><span class="line">3.14159</span><br><span class="line">3.14159</span><br></pre></td></tr></table></figure><p>float 赋值的时候需要在最后面加上<code>f</code>，否则会默认为双精度。可以看出赋值为<code>3.1415926</code>最后float和double打印出来都是3.14159。因为float和double默认只会显示<code>6</code>位有效数字。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;本篇博客对于c++的基础知识讲解适用于有其他语言基础的人群，如JavaScript、Java、C等。因此有些简单的东西而且相对于其他语言来讲用法是一模一样就不会记录下来了，比如&lt;code&gt;if语句&lt;/code&gt;、&lt;code&gt;while语句&lt;/code&gt;、&lt;code&gt;switch语句&lt;/code&gt;等等。&lt;br&gt;博主是从事web前端这个岗位的，所以对于C++的专业知识没有比较深的理解，有些点讲解的也不是很到位，只是自己学习时候的记录笔记，可以评论留言讨论学习。&lt;/p&gt;
&lt;h1 id=&quot;打印&quot;&gt;&lt;a href=&quot;#打印&quot; class=&quot;headerlink&quot; title=&quot;打印&quot;&gt;&lt;/a&gt;打印&lt;/h1&gt;&lt;p&gt;以&lt;code&gt;cout&lt;/code&gt;开始，以&lt;code&gt;endl&lt;/code&gt;结尾，&lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt;展示打印信息，由于c++对代码规范要求严格，所以需要写&lt;code&gt;;&lt;/code&gt;结尾，否则报错。具体打印代码如：&lt;br&gt;&lt;code&gt;cout &amp;lt;&amp;lt; &amp;quot;hello world&amp;quot; &amp;lt;&amp;lt; endl;&lt;/code&gt;    &lt;/p&gt;</summary>
    
    
    
    <category term="C++" scheme="https://blogwxb.cn/categories/C/"/>
    
    
    <category term="C++" scheme="https://blogwxb.cn/tags/C/"/>
    
  </entry>
  
  <entry>
    <title>不同页面跳转到指定位置和同页面跳到指定位置</title>
    <link href="https://blogwxb.cn/%E4%B8%8D%E5%90%8C%E9%A1%B5%E9%9D%A2%E8%B7%B3%E8%BD%AC%E5%88%B0%E6%8C%87%E5%AE%9A%E4%BD%8D%E7%BD%AE%E5%92%8C%E5%90%8C%E9%A1%B5%E9%9D%A2%E8%B7%B3%E5%88%B0%E6%8C%87%E5%AE%9A%E4%BD%8D%E7%BD%AE/"/>
    <id>https://blogwxb.cn/%E4%B8%8D%E5%90%8C%E9%A1%B5%E9%9D%A2%E8%B7%B3%E8%BD%AC%E5%88%B0%E6%8C%87%E5%AE%9A%E4%BD%8D%E7%BD%AE%E5%92%8C%E5%90%8C%E9%A1%B5%E9%9D%A2%E8%B7%B3%E5%88%B0%E6%8C%87%E5%AE%9A%E4%BD%8D%E7%BD%AE/</id>
    <published>2022-05-24T09:47:59.000Z</published>
    <updated>2024-05-09T09:24:37.772Z</updated>
    
    <content type="html"><![CDATA[<h1 id="一、场景"><a href="#一、场景" class="headerlink" title="一、场景"></a>一、场景</h1><p>当一个页面跳转到另一个页面，有时候需要跳转到另一个页面的指定的内容部分，该内容部分有可能就是在顶部、中间、底部。还有就是很多博客网站都有目录，点击目录中的标题就能跳转到该标题的指定位置，这两种场景是该怎么实现呢？</p><h1 id="二、实现方法"><a href="#二、实现方法" class="headerlink" title="二、实现方法"></a>二、实现方法</h1><p>主要是用到了 <code>scrollIntoView</code> ，这个是<code>dom元素</code>才有的方法。当该元素调用<code>scrollIntoView</code>方法后，页面就会自动滑到该dom的位置，<code>前提是父元素要有滚动条</code>，滑到的位置是相对于父元素的。</p><span id="more"></span><h2 id="简单的介绍一下语法："><a href="#简单的介绍一下语法：" class="headerlink" title="简单的介绍一下语法："></a>简单的介绍一下语法：</h2><p><code>element.scrollIntoView()</code>  等同于 <code>element.scrollIntoView(true)</code><br>为<code>true</code>的话会滑到该<code>元素顶部</code>与<code>可视区域顶部对齐</code>,<br>为false的话会滑到该<code>元素底部</code>与<code>可视区域的底部对齐</code>。<br>详细的语法介绍，请看 <a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Element/scrollIntoView">MDN</a> 的讲解。</p><h2 id="示例"><a href="#示例" class="headerlink" title="示例"></a>示例</h2><p>下面用到的例子都是用react去完成的。</p><h3 id="展示同级页面的跳转到指定位置"><a href="#展示同级页面的跳转到指定位置" class="headerlink" title="展示同级页面的跳转到指定位置"></a>展示同级页面的跳转到指定位置</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">App</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">const</span> dom = useRef&lt;<span class="title class_">HTMLDivElement</span>&gt;(<span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> listData = [<span class="string">&#x27;#00a1ff&#x27;</span>, <span class="string">&#x27;green&#x27;</span>, <span class="string">&#x27;black&#x27;</span>, <span class="string">&#x27;red&#x27;</span>, <span class="string">&#x27;pink&#x27;</span>,<span class="string">&#x27;#ffd500&#x27;</span>,<span class="string">&#x27;#ff8800&#x27;</span>,<span class="string">&#x27;#12886b&#x27;</span>,<span class="string">&#x27;#9b0e7c&#x27;</span>]</span><br><span class="line"> </span><br><span class="line">  <span class="comment">// 点击跳转到指定位置</span></span><br><span class="line">  <span class="keyword">const</span> <span class="title function_">jumpTo</span> = (<span class="params">index:number</span>)=&gt;&#123;</span><br><span class="line">    <span class="keyword">const</span> dom = <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">`#item_<span class="subst">$&#123;index&#125;</span>`</span>)</span><br><span class="line">    dom.<span class="title function_">scrollIntoView</span>()</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> (</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&#x27;container&#x27;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        &#123;listData.map((item, index) =&gt; &#123;</span></span><br><span class="line"><span class="language-xml">          // 定义id，方便选中dom元素</span></span><br><span class="line"><span class="language-xml">          return <span class="tag">&lt;<span class="name">li</span> <span class="attr">key</span>=<span class="string">&#123;item&#125;</span> <span class="attr">id</span>=<span class="string">&#123;</span>`<span class="attr">item_</span>$&#123;<span class="attr">index</span>&#125;`&#125; <span class="attr">className</span>=<span class="string">&#x27;listItem&#x27;</span> <span class="attr">style</span>=<span class="string">&#123;&#123;</span> <span class="attr">backgroundColor:</span> <span class="attr">item</span> &#125;&#125;&gt;</span>第&#123;index + 1&#125;部分<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        &#125;)&#125;</span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">ul</span> <span class="attr">className</span>=<span class="string">&#x27;optionsBox&#x27;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        &#123;listData.map((item, index) =&gt; &#123;</span></span><br><span class="line"><span class="language-xml">          return <span class="tag">&lt;<span class="name">li</span> <span class="attr">key</span>=<span class="string">&#123;item&#125;</span> <span class="attr">className</span>=<span class="string">&#x27;option_item&#x27;</span> <span class="attr">onClick</span>=<span class="string">&#123;()</span>=&gt;</span>jumpTo(index)&#125;&gt;跳转到第&#123;index + 1&#125;部分<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        &#125;)&#125;</span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">  )</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>运行效果如下：<br><img data-src="/%E4%B8%8D%E5%90%8C%E9%A1%B5%E9%9D%A2%E8%B7%B3%E8%BD%AC%E5%88%B0%E6%8C%87%E5%AE%9A%E4%BD%8D%E7%BD%AE%E5%92%8C%E5%90%8C%E9%A1%B5%E9%9D%A2%E8%B7%B3%E5%88%B0%E6%8C%87%E5%AE%9A%E4%BD%8D%E7%BD%AE/0.png" alt="0.png"><br>点击跳转到第四部分的效果：<br><img data-src="/%E4%B8%8D%E5%90%8C%E9%A1%B5%E9%9D%A2%E8%B7%B3%E8%BD%AC%E5%88%B0%E6%8C%87%E5%AE%9A%E4%BD%8D%E7%BD%AE%E5%92%8C%E5%90%8C%E9%A1%B5%E9%9D%A2%E8%B7%B3%E5%88%B0%E6%8C%87%E5%AE%9A%E4%BD%8D%E7%BD%AE/1.png" alt="1.png">  </p><h3 id="不同页面之间的跳转指定位置"><a href="#不同页面之间的跳转指定位置" class="headerlink" title="不同页面之间的跳转指定位置"></a>不同页面之间的跳转指定位置</h3><p>从一个页面跳转到另一个页面的实现本质上也是使用 <code>scrollIntoView</code> 方法，但是获取dom元素的方法就有所不同了，从一个页面跳转到另一个页面首先要知道跳转到哪个dom元素的位置，这就需要页面传参了，本章采用的是<code>hash值传参</code>的方法。<br>就是第一个页面跳转到第二个页面带上hash参数，如：<a href="https://baidu.com/#two,%E5%8F%AA%E9%9C%80%E8%A6%81%E8%8E%B7%E5%8F%96%E5%88%B0">https://baidu.com#two,只需要获取到</a> #后面的参数，然后去获取对应的dom元素再进行跳转。这时候就可以使用<code>location.hash</code>去获取到参数。例如：  </p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 假设地址为 https://baidu.com/api#test</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(location.<span class="property">hash</span>.<span class="title function_">split</span>(<span class="string">&#x27;#&#x27;</span>)[<span class="number">1</span>])  <span class="comment">// test</span></span><br></pre></td></tr></table></figure><p>例子：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; useState, useEffect, useRef &#125; <span class="keyword">from</span> <span class="string">&quot;react&quot;</span>;</span><br><span class="line"><span class="keyword">import</span> &#123; <span class="title class_">BrowserRouter</span>, <span class="title class_">Route</span>, <span class="title class_">Routes</span>,useLocation,useNavigate &#125; <span class="keyword">from</span> <span class="string">&#x27;react-router-dom&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">&quot;./App.css&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> listData = [<span class="string">&#x27;#00a1ff&#x27;</span>, <span class="string">&#x27;green&#x27;</span>, <span class="string">&#x27;black&#x27;</span>, <span class="string">&#x27;red&#x27;</span>, <span class="string">&#x27;pink&#x27;</span>, <span class="string">&#x27;#ffd500&#x27;</span>, <span class="string">&#x27;#ff8800&#x27;</span>, <span class="string">&#x27;#12886b&#x27;</span>, <span class="string">&#x27;#9b0e7c&#x27;</span>]</span><br><span class="line"></span><br><span class="line"><span class="comment">// 开始页面</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">StartPage</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">const</span> navigate = <span class="title function_">useNavigate</span>()</span><br><span class="line">  <span class="comment">// 跳转到第二个页面，传值</span></span><br><span class="line">  <span class="keyword">const</span> <span class="title function_">jumpTo</span> = (<span class="params">index</span>) =&gt; &#123;</span><br><span class="line">    <span class="title function_">navigate</span>(<span class="string">`/endPage/#<span class="subst">$&#123;index&#125;</span>`</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> (</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>  <span class="attr">className</span>=<span class="string">&#x27;container&#x27;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">ul</span> <span class="attr">className</span>=<span class="string">&#x27;optionsBox&#x27;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        &#123;listData.map((item, index) =&gt; &#123;</span></span><br><span class="line"><span class="language-xml">          return <span class="tag">&lt;<span class="name">li</span> <span class="attr">key</span>=<span class="string">&#123;item&#125;</span> <span class="attr">className</span>=<span class="string">&#x27;option_item&#x27;</span> <span class="attr">onClick</span>=<span class="string">&#123;()</span> =&gt;</span> jumpTo(index)&#125;&gt;跳转到第&#123;index + 1&#125;部分<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        &#125;)&#125;</span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">  )</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 跳转到的页面</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">EndPage</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">const</span> dom = useRef&lt;<span class="title class_">HTMLDivElement</span>&gt;(<span class="literal">null</span>);</span><br><span class="line">  <span class="title function_">useEffect</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="comment">// 获取到hash的参数</span></span><br><span class="line">    <span class="keyword">const</span> hashProps = location.<span class="property">hash</span>.<span class="title function_">split</span>(<span class="string">&#x27;#&#x27;</span>)[<span class="number">1</span>];</span><br><span class="line">    <span class="comment">// 找到对应的指定的dom元素</span></span><br><span class="line">    <span class="keyword">const</span> dom = <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">`#item_<span class="subst">$&#123;hashProps&#125;</span>`</span>)</span><br><span class="line">    dom.<span class="title function_">scrollIntoView</span>()</span><br><span class="line">  &#125;, [])</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> (</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>  <span class="attr">className</span>=<span class="string">&#x27;container&#x27;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        &#123;listData.map((item, index) =&gt; &#123;</span></span><br><span class="line"><span class="language-xml">          return <span class="tag">&lt;<span class="name">li</span> <span class="attr">key</span>=<span class="string">&#123;item&#125;</span> <span class="attr">id</span>=<span class="string">&#123;</span>`<span class="attr">item_</span>$&#123;<span class="attr">index</span>&#125;`&#125; <span class="attr">className</span>=<span class="string">&#x27;listItem&#x27;</span> <span class="attr">style</span>=<span class="string">&#123;&#123;</span> <span class="attr">backgroundColor:</span> <span class="attr">item</span> &#125;&#125;&gt;</span>第&#123;index + 1&#125;部分<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        &#125;)&#125;</span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">  )</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">App</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> (</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&#x27;container&#x27;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">BrowserRouter</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">Routes</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&#x27;/startPage&#x27;</span>  <span class="attr">element</span>=<span class="string">&#123;</span>&lt;<span class="attr">StartPage</span>/&gt;</span>&#125; /&gt;</span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&#x27;/endPage&#x27;</span> <span class="attr">element</span>=<span class="string">&#123;</span>&lt;<span class="attr">EndPage</span>/&gt;</span>&#125; /&gt;</span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">Routes</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">BrowserRouter</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">  )</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>行效果如下：<br>第一个页面的内容<br><img data-src="/%E4%B8%8D%E5%90%8C%E9%A1%B5%E9%9D%A2%E8%B7%B3%E8%BD%AC%E5%88%B0%E6%8C%87%E5%AE%9A%E4%BD%8D%E7%BD%AE%E5%92%8C%E5%90%8C%E9%A1%B5%E9%9D%A2%E8%B7%B3%E5%88%B0%E6%8C%87%E5%AE%9A%E4%BD%8D%E7%BD%AE/2.png" alt="2.png"><br>点击“跳转到第5部分” 去跳转到第二个页面<br><img data-src="/%E4%B8%8D%E5%90%8C%E9%A1%B5%E9%9D%A2%E8%B7%B3%E8%BD%AC%E5%88%B0%E6%8C%87%E5%AE%9A%E4%BD%8D%E7%BD%AE%E5%92%8C%E5%90%8C%E9%A1%B5%E9%9D%A2%E8%B7%B3%E5%88%B0%E6%8C%87%E5%AE%9A%E4%BD%8D%E7%BD%AE/3.png" alt="3.png">  </p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;一、场景&quot;&gt;&lt;a href=&quot;#一、场景&quot; class=&quot;headerlink&quot; title=&quot;一、场景&quot;&gt;&lt;/a&gt;一、场景&lt;/h1&gt;&lt;p&gt;当一个页面跳转到另一个页面，有时候需要跳转到另一个页面的指定的内容部分，该内容部分有可能就是在顶部、中间、底部。还有就是很多博客网站都有目录，点击目录中的标题就能跳转到该标题的指定位置，这两种场景是该怎么实现呢？&lt;/p&gt;
&lt;h1 id=&quot;二、实现方法&quot;&gt;&lt;a href=&quot;#二、实现方法&quot; class=&quot;headerlink&quot; title=&quot;二、实现方法&quot;&gt;&lt;/a&gt;二、实现方法&lt;/h1&gt;&lt;p&gt;主要是用到了 &lt;code&gt;scrollIntoView&lt;/code&gt; ，这个是&lt;code&gt;dom元素&lt;/code&gt;才有的方法。当该元素调用&lt;code&gt;scrollIntoView&lt;/code&gt;方法后，页面就会自动滑到该dom的位置，&lt;code&gt;前提是父元素要有滚动条&lt;/code&gt;，滑到的位置是相对于父元素的。&lt;/p&gt;</summary>
    
    
    
    <category term="前端" scheme="https://blogwxb.cn/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="js" scheme="https://blogwxb.cn/tags/js/"/>
    
  </entry>
  
  <entry>
    <title>React中dangerouslySetInnerHTML实现dom插入Html代码</title>
    <link href="https://blogwxb.cn/React%E4%B8%ADdangerouslySetInnerHTML%E5%AE%9E%E7%8E%B0dom%E6%8F%92%E5%85%A5Html%E4%BB%A3%E7%A0%81/"/>
    <id>https://blogwxb.cn/React%E4%B8%ADdangerouslySetInnerHTML%E5%AE%9E%E7%8E%B0dom%E6%8F%92%E5%85%A5Html%E4%BB%A3%E7%A0%81/</id>
    <published>2022-05-18T09:49:28.000Z</published>
    <updated>2024-05-09T09:24:37.700Z</updated>
    
    <content type="html"><![CDATA[<h1 id="场景"><a href="#场景" class="headerlink" title="场景"></a>场景</h1><p>当用富文本编辑好内容保存到数据库之后，数据库存的富文本的内容格式如下：  </p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;div&gt;&lt;h1&gt;标题&lt;/h1&gt;&lt;main&gt;内容&lt;/main&gt;&lt;/div&gt;</span><br></pre></td></tr></table></figure><p>当需要在某个页面某个位置去展示它的话需要原样展示出来，要怎么办呢？</p><span id="more"></span><h1 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h1><p>解决方案有两种： </p><ol><li>使用<code>useRef</code>获取dom元素之后使用<code>innerHTML</code>属性去吧html代码插入到dom元素中去，具体如下：<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; useEffect, useRef &#125; <span class="keyword">from</span> <span class="string">&quot;react&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">App</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">const</span> dom = <span class="title function_">useRef</span>(<span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line">  <span class="title function_">useEffect</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(dom.<span class="property">current</span>)&#123;</span><br><span class="line">      dom.<span class="property">current</span>.<span class="property">innerHTML</span> = <span class="string">&#x27;&lt;h2&gt;标题2&lt;/h2&gt;&#x27;</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,[])</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> (</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">ref</span>=<span class="string">&#123;dom&#125;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">  )</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li>使用react在dom上新增的一个属性<a href="https://zh-hans.reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml">dangerouslySetInnerHTML</a>,官方文档介绍：<blockquote><p><code>dangerouslySetInnerHTML</code> 是 React 为浏览器 DOM 提供 <code>innerHTML</code> 的替换方案。通常来讲，使用代码直接设置 HTML 存在风险，因为很容易无意中使用户暴露于<code>跨站脚本（XSS）</code>的攻击。因此，你可以直接在 React 中设置 HTML，但当你想设置 <code>dangerouslySetInnerHTML</code> 时，需要向其传递包含 key 为 <code>__html</code> 的对象，以此来警示你。<br>下面不用官方例子了，用本文章的例子：</p></blockquote><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; useState, useEffect &#125; <span class="keyword">from</span> <span class="string">&quot;react&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">App</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">const</span> [htmlContent,setHtmlContent] = <span class="title function_">useState</span>(<span class="string">&#x27;&#x27;</span>)</span><br><span class="line"></span><br><span class="line">  <span class="title function_">useEffect</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="title function_">setHtmlContent</span>(<span class="string">&#x27;&lt;h2&gt;标题2&lt;/h2&gt;&#x27;</span>)</span><br><span class="line">  &#125;,[])</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> (</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">dangerouslySetInnerHTML</span>=<span class="string">&#123;&#123;__html:htmlContent&#125;&#125;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">  )</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这个用法更加安全一些。</p></li></ol>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;场景&quot;&gt;&lt;a href=&quot;#场景&quot; class=&quot;headerlink&quot; title=&quot;场景&quot;&gt;&lt;/a&gt;场景&lt;/h1&gt;&lt;p&gt;当用富文本编辑好内容保存到数据库之后，数据库存的富文本的内容格式如下：  &lt;/p&gt;
&lt;figure class=&quot;highlight plaintext&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&amp;lt;div&amp;gt;&amp;lt;h1&amp;gt;标题&amp;lt;/h1&amp;gt;&amp;lt;main&amp;gt;内容&amp;lt;/main&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;当需要在某个页面某个位置去展示它的话需要原样展示出来，要怎么办呢？&lt;/p&gt;</summary>
    
    
    
    <category term="前端" scheme="https://blogwxb.cn/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="React" scheme="https://blogwxb.cn/tags/React/"/>
    
  </entry>
  
</feed>
