-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
104 lines (55 loc) · 112 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>JerryWebBlog</title>
<subtitle>面朝大海,春暖花开</subtitle>
<link href="https://jerrywebleeblog.top/atom.xml" rel="self"/>
<link href="https://jerrywebleeblog.top/"/>
<updated>2021-06-14T09:04:49.838Z</updated>
<id>https://jerrywebleeblog.top/</id>
<author>
<name>Jerry Web Lee</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>继承</title>
<link href="https://jerrywebleeblog.top/2021/06/12/10/43/20210612%E7%BB%A7%E6%89%BF/"/>
<id>https://jerrywebleeblog.top/2021/06/12/10/43/20210612%E7%BB%A7%E6%89%BF/</id>
<published>2021-06-12T02:43:51.000Z</published>
<updated>2021-06-14T09:04:49.838Z</updated>
<content type="html"><![CDATA[<p> 通过下面的代码块可以看到,每个类都有3个部分,第一部分是构造函数内的,这是供实例化对象复制用的,第二部分是构造函数外的,直接通过点语法添加的,这是供类使用的,实例化对象是访问不到的,第三部分是类的原型中的,实例化对象可以通过其原型链间接地访问到,也是为供所有实例化对象所共用的。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> Book = <span class="function"><span class="keyword">function</span> (<span class="params">title, time, author</span>) </span>{</span><br><span class="line"> <span class="comment">// 私有属性</span></span><br><span class="line"> <span class="keyword">var</span> num = <span class="number">1</span></span><br><span class="line"> <span class="comment">// 私有方法</span></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">checkID</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'check id'</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 构造函数内的,这是供实例化对象复制用的</span></span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">this</span> <span class="keyword">instanceof</span> Book) {</span><br><span class="line"> <span class="comment">// 公有属性</span></span><br><span class="line"> <span class="built_in">this</span>.title = title</span><br><span class="line"> <span class="built_in">this</span>.time = time</span><br><span class="line"> <span class="built_in">this</span>.author = author</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"> 通过this创建的方法,不但可以访问这些对象</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="comment"> 权利比较大,所以我们又将它看作特权方法。 </span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="built_in">this</span>.getName = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{ }</span><br><span class="line"> <span class="built_in">this</span>.getPrice = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{ }</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="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="built_in">this</span>.setName = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{ }</span><br><span class="line"> <span class="built_in">this</span>.setPrice = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{ }</span><br><span class="line"> <span class="comment">//对象公有方法</span></span><br><span class="line"> <span class="built_in">this</span>.copy = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{ }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> Book(title, time, author)</span><br><span class="line"> }</span><br><span class="line">}</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">Book.isChinese = <span class="literal">true</span></span><br><span class="line"><span class="comment">// 类静态公有方法</span></span><br><span class="line">Book.setItem = <span class="function"><span class="keyword">function</span> (<span class="params">item</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(item);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 类的原型中的,实例化对象可以通过其原型链间接地访问到,也是为供所有实例化对象所共用的</span></span><br><span class="line">Book.prototype = {</span><br><span class="line"> <span class="comment">// 公有属性</span></span><br><span class="line"> <span class="attr">isAboutJS</span>: <span class="literal">true</span>,</span><br><span class="line"> <span class="comment">// 公有方法</span></span><br><span class="line"> <span class="attr">display</span>: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'book displayed'</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> book = Book(<span class="string">'Javascript设计模式'</span>, <span class="string">'2000-01-01'</span>, <span class="string">'ZRM'</span>)</span><br><span class="line"><span class="built_in">console</span>.log(book); <span class="comment">// { title: 'Javascript设计模式', time: '2000-01-01', author: 'ZRM' }</span></span><br><span class="line"><span class="built_in">console</span>.log(book <span class="keyword">instanceof</span> Book); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(book.isChinese); <span class="comment">// undefined</span></span><br><span class="line"><span class="comment">// book.setItem('js book') // TypeError: book.setItem is not a function</span></span><br><span class="line">Book.setItem(<span class="string">'js book'</span>) <span class="comment">// js book</span></span><br><span class="line"><span class="built_in">console</span>.log(book.isAboutJS); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(Book.isAboutJS); <span class="comment">// undefined</span></span><br><span class="line">book.display() <span class="comment">// book displayed</span></span><br><span class="line"><span class="comment">// Book.display() // TypeError: Book.display is not a function</span></span><br></pre></td></tr></table></figure><hr /><h2 id="原型链和原型对象"><a class="markdownIt-Anchor" href="#原型链和原型对象"></a> 原型链和原型对象</h2><p> 原型链和原型对象是<code>js</code>的核心,<code>js</code>以原型链的形式,保证函数或对象中的方法、属性可以向下传递。按照面向对象的说法,这就是继承。而<code>js</code>通过原型链才得以实现函数或对象的继承。</p><p> 每个构造函数都有一个原型对象<code>prototype</code>,原型有一个<code>constructor</code>属性指回构造函数,而实例有一个隐式原型属性<code>__proto__</code>指向原型。</p><h3 id="原型链"><a class="markdownIt-Anchor" href="#原型链"></a> 原型链</h3><h4 id="什么是原型链"><a class="markdownIt-Anchor" href="#什么是原型链"></a> 什么是原型链</h4><p> 请看下面的代码:</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Foo</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="comment">// 检察长:当没有使用new关键字初始化实例对象的时候,内部返回一个使用new关键字实例化的对象</span></span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">this</span> <span class="keyword">instanceof</span> Foo) {</span><br><span class="line"> <span class="comment">// 属性初始</span></span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> Foo()</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> obj = <span class="keyword">new</span> <span class="built_in">Object</span>()</span><br><span class="line"> <span class="comment">// -- Foo构造函数的原型对象</span></span><br><span class="line"> <span class="built_in">console</span>.log(Foo.prototype); <span class="comment">// Foo {} </span></span><br><span class="line"> <span class="comment">// -- 实例对象不存在显式原型属性</span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">this</span>.prototype); <span class="comment">// undefined </span></span><br><span class="line"> <span class="comment">// -- 实例的隐士原型属性指向函数的显示原型属性</span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">this</span>.__proto__); <span class="comment">// Foo {} </span></span><br><span class="line"> <span class="built_in">console</span>.log(Foo.prototype === <span class="built_in">this</span>.__proto__); <span class="comment">// true </span></span><br><span class="line"> <span class="comment">// -- 原型对象的constructor属性指向构造函数</span></span><br><span class="line"> <span class="built_in">console</span>.log(Foo.prototype.constructor); <span class="comment">// [Function: Foo] </span></span><br><span class="line"> <span class="built_in">console</span>.log(Foo.prototype.constructor === Foo); <span class="comment">// true </span></span><br><span class="line"> <span class="comment">// -- Foo构造函数作为一个Function实例对象,他的隐式原型属性指向Function构造函数的原型对象</span></span><br><span class="line"> <span class="built_in">console</span>.log(Foo.__proto__); <span class="comment">// [Function] </span></span><br><span class="line"> <span class="built_in">console</span>.log(Foo.__proto__ === <span class="built_in">Function</span>.prototype); <span class="comment">// true </span></span><br><span class="line"> <span class="comment">// -- Function构造函数的原型对象的隐式原型属性,指向Object函数的原型对象</span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">Function</span>.prototype.__proto__); <span class="comment">// {} </span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">Function</span>.prototype.__proto__===<span class="built_in">Object</span>.prototype); <span class="comment">// true </span></span><br><span class="line"> <span class="comment">// -- Object实例对象的隐式原型属性指向Object构造函数的原型对象</span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">Object</span>.prototype === obj.__proto__); <span class="comment">// true </span></span><br><span class="line"> <span class="comment">// -- Object作为Function构造函数创建的实例对象,他的隐式原型属性指向Function构造函数的原型对象</span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">Object</span>.__proto__); <span class="comment">// [Function] </span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">Object</span>.__proto__ === <span class="built_in">Function</span>.prototype); <span class="comment">// true </span></span><br><span class="line"> <span class="comment">// -- Object.prototype.__proto__原型链的尽头</span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">Object</span>.prototype.__proto__); <span class="comment">// null </span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> Foo()</span><br><span class="line"><span class="comment">// Foo()</span></span><br></pre></td></tr></table></figure><p> 通过上面的代码可以看出以下的一个链式结构:</p><ul><li>原型对象也称为函数的<strong>显示原型属性</strong>,只有函数才拥有该属性。</li><li>原型对象的<code>constructor</code>属性,指向原型对象的<strong>构造函数</strong>。</li><li>实例化函数对象的<strong>隐式原型属性</strong>,指向函数的<strong>显示原型属性</strong>。</li><li><code>Foo</code>构造函数作为一个<code>Function</code>构造函数的实例对象,他的隐式原型属性指向Function构造函数的原型对象。</li><li><code>Function</code>构造函数的原型对象的隐式原型属性,指向<code>Object</code>构造函数的原型对象。</li><li><code>Object</code>实例化对象<code>(obj)</code>的隐式原型属性指向<code>Object</code>构造函数的原型对象。</li><li><code>Object</code>作为<code>Function</code>构造函数创建的实例对象,他的隐式原型属性指向<code>Function</code>构造函数的原型对象。</li><li><code>Object.prototype.__proto__ = null</code>为原型链的尽头。</li></ul><p> 这样形成的一个链式结构,称为<strong>原型链</strong>。</p><hr /><h4 id="原型链示意图"><a class="markdownIt-Anchor" href="#原型链示意图"></a> 原型链示意图</h4><p> 综合上述代码,可以画图以下的一个链式结构示意图。</p><p><img src="/img/prototype.png" alt="原型链示意图" /></p><hr /><h2 id="继承"><a class="markdownIt-Anchor" href="#继承"></a> 继承</h2><p> <code>ECMA-262</code> 把<strong>原型链</strong>定义为<code>ECMAScript</code> 的主要继承方式。其基本思想就是通过原型继承多个引用类型的属性和方法。</p><hr /><h3 id="子类的原型对象类式继承"><a class="markdownIt-Anchor" href="#子类的原型对象类式继承"></a> 子类的原型对象——类式继承</h3><p> <strong>类式继承</strong>的基本思想是:子类的原型对象<code>prototype</code>被赋予了父类的一个实例对象。</p><p> 我们实例化一个父类的时候,<strong>父类的实例化对象</strong>复制了父类的构造函数内的属性与方法并且将原型<code>__proto__</code>指向了<strong>父类的原型对象</strong>,这样就拥有了父类的原型对象上的属性与方法,并且这个<strong>实例化对象</strong>可直接访问到父类原型对象上的属性与方法。如果我们将这个<strong>实例化对象</strong>赋值给<strong>子类的原型</strong>,那么子类的原型就可以访问到父类的原型属性和方法。</p><p> 而且<strong>实例化对象</strong>不仅仅可以访问父类原型上的属性和方法,同样也可访问从父类构造函数中复制的属性和方法。将<strong>实例化对象</strong>赋值给<strong>子类的原型</strong>,那么这个<strong>子类的原型</strong>同样可以访问<strong>父类原型</strong>上的属性和方法与从父类构造函数中复制的属性和方法。这正是<strong>类式继承原理</strong>。</p><p> 如下代码所示:</p><figure class="highlight javascript"><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">// 父类</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">superClass</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">this</span>.superValue = <span class="literal">true</span></span><br><span class="line">}</span><br><span class="line"><span class="comment">// 共有方法</span></span><br><span class="line">superClass.prototype.getsuperValue = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">this</span>.superValue</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 子类</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">subClass</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="built_in">this</span>.subValue = <span class="literal">false</span></span><br><span class="line">}</span><br><span class="line"><span class="comment">// 继承父类</span></span><br><span class="line">subClass.prototype = <span class="keyword">new</span> superClass()</span><br><span class="line"><span class="comment">// 为子类添加共有方法</span></span><br><span class="line">subClass.prototype.getsubValue = <span class="function"><span class="keyword">function</span> (<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">this</span>.subValue</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> instance = <span class="keyword">new</span> subClass()</span><br><span class="line"><span class="built_in">console</span>.log(instance.getsuperValue()) <span class="comment">//true</span></span><br><span class="line"><span class="built_in">console</span>.log(instance.getsubValue()) <span class="comment">// false</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(instance <span class="keyword">instanceof</span> superClass) <span class="comment">//true</span></span><br><span class="line"><span class="built_in">console</span>.log(instance <span class="keyword">instanceof</span> subClass) <span class="comment">//true</span></span><br><span class="line"><span class="comment">// subClass.prototype继承了superClass</span></span><br><span class="line"><span class="built_in">console</span>.log(subClass <span class="keyword">instanceof</span> superClass) <span class="comment">//false</span></span><br><span class="line"><span class="built_in">console</span>.log(subClass.prototype <span class="keyword">instanceof</span> superClass) <span class="comment">// true</span></span><br></pre></td></tr></table></figure><hr /><h4 id="类式继承的缺点"><a class="markdownIt-Anchor" href="#类式继承的缺点"></a> 类式继承的缺点</h4><ul><li><p>由于子类通过其原型<code>prototype</code>指向<strong>父类的实例化对象</strong>,继承了父类。所以说<strong>父类中的共有属性要是引用类型,就会在子类中被所有实例共用,因此一个子类的实例更改子类原型从父类构造函数中继承来的共有属性就会直接影响到其他子类</strong>。</p><figure class="highlight javascript"><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="comment">// 父类</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">superClass</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">this</span>.superValue = <span class="literal">true</span></span><br><span class="line"> <span class="built_in">this</span>.car = {</span><br><span class="line"> <span class="attr">size</span>:<span class="string">'2*4'</span>,</span><br><span class="line"> <span class="attr">color</span>: <span class="string">'blue'</span>,</span><br><span class="line"> <span class="attr">speed</span>:<span class="string">'60km/h'</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 共有方法</span></span><br><span class="line">superClass.prototype.getsuperValue = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">this</span>.superValue</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 子类</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">subClass</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="built_in">this</span>.subValue = <span class="literal">false</span></span><br><span class="line">}</span><br><span class="line"><span class="comment">// 继承父类</span></span><br><span class="line">subClass.prototype = <span class="keyword">new</span> superClass()</span><br><span class="line"><span class="comment">// 为子类添加共有方法</span></span><br><span class="line">subClass.prototype.getsubValue = <span class="function"><span class="keyword">function</span> (<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">this</span>.subValue</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> instance1 = <span class="keyword">new</span> subClass()</span><br><span class="line"><span class="keyword">var</span> instance2 = <span class="keyword">new</span> subClass()</span><br><span class="line"><span class="built_in">console</span>.log(instance1.car) <span class="comment">// { size: '2*4', color: 'blue', speed: '60km/h' }</span></span><br><span class="line"><span class="built_in">console</span>.log(instance2.car) <span class="comment">// { size: '2*4', color: 'blue', speed: '60km/h' }</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 实例1改变了父类共有对象的属性值,实例2中共有对象属性值也会跟着改变</span></span><br><span class="line">instance1.car.size = <span class="string">'4*6'</span></span><br><span class="line">instance1.car.speed = <span class="string">"80km/h"</span></span><br><span class="line"><span class="built_in">console</span>.log(instance1.car) <span class="comment">// { size: '4*6', color: 'blue', speed: '80km/h' }</span></span><br><span class="line"><span class="built_in">console</span>.log(instance2.car) <span class="comment">// { size: '4*6', color: 'blue', speed: '80km/h' }</span></span><br></pre></td></tr></table></figure></li><li><p>由于子类实现的继承是靠其原型 <code>prototype</code>指向父类的实例化对象实现的,因此<strong>在创建父类的时候,是无法向父类传递参数的,因而在实例化父类的时候也无法对父类构造函数内的属性进行初始化</strong>。</p><figure class="highlight javascript"><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="comment">// 父类</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">superClass</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">this</span>.superValue = <span class="literal">true</span></span><br><span class="line">}</span><br><span class="line"><span class="comment">// 共有方法</span></span><br><span class="line">superClass.prototype.getsuperValue = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">this</span>.superValue</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 子类</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">subClass</span>(<span class="params">args</span>)</span>{</span><br><span class="line"> <span class="built_in">this</span>.subValue = <span class="literal">false</span></span><br><span class="line"> <span class="built_in">this</span>.args = args</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 继承父类</span></span><br><span class="line">subClass.prototype = <span class="keyword">new</span> superClass()</span><br><span class="line"><span class="comment">// 为子类添加共有方法</span></span><br><span class="line">subClass.prototype.getsubValue = <span class="function"><span class="keyword">function</span> (<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">this</span>.subValue</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> instance = <span class="keyword">new</span> subClass(<span class="string">'哈哈哈'</span>)</span><br><span class="line"><span class="built_in">console</span>.log(instance.args); <span class="comment">// 哈哈哈</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="keyword">new</span> superClass().args); <span class="comment">// undefined</span></span><br></pre></td></tr></table></figure></li></ul><hr /><h3 id="创建即继承构造函数继承"><a class="markdownIt-Anchor" href="#创建即继承构造函数继承"></a> 创建即继承——构造函数继承</h3><p> 如下代码所示:</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">superClass</span>(<span class="params">id</span>)</span>{</span><br><span class="line"> <span class="comment">// 引用类型共有属性</span></span><br><span class="line"> <span class="built_in">this</span>.books = [<span class="string">'Javascript'</span>, <span class="string">'html'</span>, <span class="string">'css'</span>]</span><br><span class="line"> <span class="comment">// 值类型共有属性</span></span><br><span class="line"> <span class="built_in">this</span>.id = id</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 父类声明原型方法</span></span><br><span class="line">superClass.prototype.showBooks = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">this</span>.books)</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 声明子类</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">subClass</span>(<span class="params">id</span>)</span>{</span><br><span class="line"> <span class="comment">// 继承父类</span></span><br><span class="line"> superClass.call(<span class="built_in">this</span>, id)</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 创建第一个子类的实例</span></span><br><span class="line"><span class="keyword">var</span> instance1 = <span class="keyword">new</span> subClass(<span class="number">10</span>)</span><br><span class="line"><span class="comment">// 创建第二个子类的实例</span></span><br><span class="line"><span class="keyword">var</span> instance2 = <span class="keyword">new</span> subClass(<span class="number">11</span>)</span><br><span class="line">instance1.books.push(<span class="string">"设计模式"</span>)</span><br><span class="line"><span class="built_in">console</span>.log(instance1.books) <span class="comment">// ["Javascript", "html", "css", "设计模式"]</span></span><br><span class="line"><span class="built_in">console</span>.log(instance1.id) <span class="comment">// 10</span></span><br><span class="line"><span class="built_in">console</span>.log(instance2.books) <span class="comment">// ["Javascript", "html", "css"]</span></span><br><span class="line"><span class="built_in">console</span>.log(instance2.id) <span class="comment">// 11</span></span><br><span class="line"><span class="comment">// instance1.showBooks() // TypeError</span></span><br></pre></td></tr></table></figure><p> <code>SuperClass.call(this, id)</code>这条语句是构造函数式继承的精华,由于<code>call</code>这个方法可以更改函数的作用环境,因此在子类中,对<code>superClass</code>调用这个方法就是将子类中的变量在父类中执行一遍,由于父类中是给this绑定属性的,因此子类自然也就继承了父类的共有属性。<strong>由于这种类型的继承没有涉及原型 <code>prototype</code>,所以父类的原型方法自然不会被子类继承,而如果要想被子类继承就必须要放在构造函数中,这样创建出来的每个实例都会单独拥有一份而不能共用,这样就违背了代码复用的原则</strong>。</p><hr /><h3 id="将优点为我所用组合继承"><a class="markdownIt-Anchor" href="#将优点为我所用组合继承"></a> 将优点为我所用——组合继承</h3><p> <strong>类式继承</strong>是<strong>通过子类的原型<code>prototype</code>指向父类实例化对象来实现的</strong>,<strong>构造函数式继承</strong>是<strong>通过在子类的构造函数作用环境中执行一次父类的构造函数来实现的</strong>,所以只要在继承中同时做到这两点即可,即实现<strong>组合继承</strong>。</p><figure class="highlight javascript"><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="function"><span class="keyword">function</span> <span class="title">superClass</span>(<span class="params">id</span>)</span>{</span><br><span class="line"> <span class="built_in">this</span>.books = [<span class="string">'Javascript'</span>, <span class="string">'html'</span>, <span class="string">'css'</span>]</span><br><span class="line"> <span class="built_in">this</span>.id = id</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 父类声明原型方法</span></span><br><span class="line">superClass.prototype.showBooks = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">this</span>.books)</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 构造函数继承</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">subClass</span>(<span class="params">id</span>)</span>{</span><br><span class="line"> <span class="comment">// 继承父类</span></span><br><span class="line"> superClass.call(<span class="built_in">this</span>, id)</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 类式继承</span></span><br><span class="line">subClass.prototype = <span class="keyword">new</span> superClass()</span><br><span class="line"><span class="comment">// 子类实例化过程中又能将参数传递到父类的构造函数中</span></span><br><span class="line"><span class="keyword">var</span> instance1 = <span class="keyword">new</span> subClass(<span class="number">10</span>)</span><br><span class="line"><span class="keyword">var</span> instance2 = <span class="keyword">new</span> subClass(<span class="number">11</span>)</span><br><span class="line">instance1.books.push(<span class="string">"设计模式"</span>)</span><br><span class="line"><span class="built_in">console</span>.log(instance1.books) <span class="comment">// ["Javascript", "html", "css", "设计模式"]</span></span><br><span class="line"><span class="built_in">console</span>.log(instance1.id) <span class="comment">// 10</span></span><br><span class="line">instance1.showBooks() <span class="comment">// ["Javascript", "html", "css", "设计模式"]</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// instance1的books中添加书籍,不会影响父级的和子级其他实例对象的books对象属性</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="keyword">new</span> subClass().books); <span class="comment">// [ 'Javascript', 'html', 'css' ]</span></span><br><span class="line"><span class="built_in">console</span>.log(instance2.books) <span class="comment">// ["Javascript", "html", "css"]</span></span><br><span class="line"><span class="built_in">console</span>.log(instance2.id) <span class="comment">// 11</span></span><br></pre></td></tr></table></figure><p> 子类的实例中更改父类继承下来的引用类型属性如<code>books</code>,根本不会影响到其他实例,并且子类实例化过程中又能将参数传递到父类的构造函数中。</p><p> 在使用构造函数继承时执行了一遍父类的构造函数,而在实现子类原型的类式继承时又调用了一遍父类构造函数。因此父类构造函数调用了两遍,所以这还不是最完美的方式。</p><hr /><h3 id="洁净的继承者原型式继承"><a class="markdownIt-Anchor" href="#洁净的继承者原型式继承"></a> 洁净的继承者——原型式继承</h3><p> 借助原型<code>prototype</code>可以根据己有的对象创建一个新的对象,同时不必创建新的自定义对象类型。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">inheritobject</span>(<span class="params">obj</span>)</span>{</span><br><span class="line"> <span class="comment">// 声明—个过渡函数对象</span></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">F</span>(<span class="params"></span>)</span>{}</span><br><span class="line"> <span class="comment">// 过渡对象的原型继承父对象</span></span><br><span class="line"> F.prototype = obj</span><br><span class="line"> <span class="comment">// 返回过渡对象的—个实例,该实例的原型继承了父对象</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> F()</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> book = {</span><br><span class="line"> <span class="attr">name</span>:<span class="string">"js book"</span>,</span><br><span class="line"> <span class="attr">alikeBook</span>:[<span class="string">"css book"</span>, <span class="string">"html book"</span>]</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> newBook = inheritobject(book)</span><br><span class="line">newBook.name = <span class="string">"ajax book"</span></span><br><span class="line">newBook.alikeBook.push(<span class="string">"xml book"</span>)</span><br><span class="line"><span class="keyword">var</span> otherBook = inheritobject(book)</span><br><span class="line">otherBook.name = <span class="string">"flash book"</span></span><br><span class="line">otherBook.alikeBook.push(<span class="string">"as book"</span>)</span><br><span class="line"><span class="built_in">console</span>.log(newBook.name) <span class="comment">//ajax book</span></span><br><span class="line"><span class="built_in">console</span>.log(newBook.alikeBook) <span class="comment">//["css book", "html book", "xml book","as book"]</span></span><br><span class="line"><span class="built_in">console</span>.log(otherBook.name) <span class="comment">//flash book</span></span><br><span class="line"><span class="built_in">console</span>.log(otherBook.alikeBook) <span class="comment">//["css book", "html book", "xml book","as book"]</span></span><br><span class="line"><span class="built_in">console</span>.log(book.name) <span class="comment">//js book</span></span><br><span class="line"><span class="built_in">console</span>.log(book.alikeBook) <span class="comment">//["css book", "html book", "xml book","as book"]</span></span><br></pre></td></tr></table></figure><p> 它是对类式继承的一个封装,其实其中的过渡对象就相当于类式继承中的子类,只不过在原型式中作为一个过渡对象出现的,目的是为了创建要返回的新的实例化对象。</p><h4 id="优点"><a class="markdownIt-Anchor" href="#优点"></a> 优点:</h4><p> 这种方式由于F过渡类的构造函数中无内容,所以开销比较小,使用起来也比较方便。</p><h4 id="缺点"><a class="markdownIt-Anchor" href="#缺点"></a> 缺点:</h4><p> 类式继承中的问题在这里也会出现。创建的新对象会影响到父类中的属性对象。</p><hr /><h3 id="如虎添翼寄生式继承"><a class="markdownIt-Anchor" href="#如虎添翼寄生式继承"></a> 如虎添翼——寄生式继承</h3><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">inheritobject</span>(<span class="params">obj</span>)</span>{</span><br><span class="line"> <span class="comment">// 声明—个过渡函数对象</span></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">F</span>(<span class="params"></span>)</span>{}</span><br><span class="line"> <span class="comment">// 过渡对象的原型继承父对象</span></span><br><span class="line"> F.prototype = obj</span><br><span class="line"> <span class="comment">// 返回过渡对象的—个实例,该实例的原型继承了父对象</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> F()</span><br><span class="line">}</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="keyword">var</span> book = {</span><br><span class="line"> <span class="attr">name</span>: <span class="string">"js book"</span>,</span><br><span class="line"> <span class="attr">alikeBook</span>: [<span class="string">"css book"</span>, <span class="string">"html book"</span>]</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">createBook</span>(<span class="params">obj</span>)</span>{</span><br><span class="line"> <span class="comment">// 通过原型继承方式创建新对象</span></span><br><span class="line"> <span class="keyword">var</span> o = <span class="keyword">new</span> inheritobject(obj)</span><br><span class="line"> <span class="comment">// 拓展新对象</span></span><br><span class="line"> o.getName = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">this</span>.name)</span><br><span class="line"> }</span><br><span class="line"> o.setName = <span class="function"><span class="keyword">function</span>(<span class="params">name</span>)</span>{</span><br><span class="line"> <span class="built_in">this</span>.name = name</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 返回拓展后的新对象</span></span><br><span class="line"> <span class="keyword">return</span> o</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> newBook = createBook(book)</span><br><span class="line">newBook.getName() <span class="comment">// js book</span></span><br><span class="line">newBook.setName(<span class="string">'java book'</span>)</span><br><span class="line">newBook.getName() <span class="comment">// java book</span></span><br><span class="line"><span class="built_in">console</span>.log(newBook.alikeBook); <span class="comment">// [ 'css book', 'html book' ]</span></span><br><span class="line">newBook.alikeBook.push(<span class="string">'js book'</span>)</span><br><span class="line"><span class="comment">// 也会更改父类的属性对象</span></span><br><span class="line"><span class="built_in">console</span>.log(newBook.alikeBook); <span class="comment">// [ 'css book', 'html book', 'js book' ]</span></span><br><span class="line"><span class="built_in">console</span>.log(book.alikeBook); <span class="comment">// [ 'css book', 'html book', 'js book' ]</span></span><br></pre></td></tr></table></figure><p> 寄生式继承就是对原型继承的第二次封装,并且在这第二次封装过程中对继承的对象进行了拓展,这样新创建的对象不仅仅有父类中的属性和方法而且还添加新的属性和方法。寄生式继承这种增强新创建对象的继承思想也是寄托于原型继承模式。</p><hr /><h3 id="终极继承者寄生组合式继承"><a class="markdownIt-Anchor" href="#终极继承者寄生组合式继承"></a> 终极继承者——寄生组合式继承</h3><p> 组合式继承,将类式继承同构造函数继承组合使用,但是这种方式有一个问题,就是子类不是父类的实例,而子类的原型是父类的实例,所以才有了寄生组合式继承。</p><p> <strong>寄生式继承</strong>依托于<strong>原型继承</strong>与<strong>构造函数继承</strong>进行组合,形成<strong>寄生组合式继承</strong>。但是这里寄生式继承有些特殊,这里它处理的不是对象,而是类的原型。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 这里返回的是父类原型对象的一个副本</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">inheritobject</span>(<span class="params">obj</span>) </span>{</span><br><span class="line"> <span class="comment">// 声明一个过渡函数对象</span></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">F</span>(<span class="params"></span>) </span>{ }</span><br><span class="line"> <span class="comment">// 过渡对象的原型继承父对象</span></span><br><span class="line"> F.prototype = obj</span><br><span class="line"> <span class="comment">// 返回过渡对象的—个实例,该实例的原型继承了父对象</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> F()</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"> 传递参数 subClass 子类</span></span><br><span class="line"><span class="comment"> 传递参数 superClass 父类 </span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">inheritPrototype</span>(<span class="params">subClass, superClass</span>) </span>{</span><br><span class="line"> <span class="comment">// 复制一份父类的原型副本保存在变量中</span></span><br><span class="line"> <span class="keyword">var</span> p = inheritobject(superClass.prototype)</span><br><span class="line"> <span class="comment">// 修正,因为重写子类原型导致子类的 constructor 属性被修改</span></span><br><span class="line"> <span class="comment">// 对复制对象 p 做一次增强,修复其 constructor 属性指向不正确的问题</span></span><br><span class="line"> p.constructor = subClass</span><br><span class="line"> <span class="comment">// 设置子类的原型</span></span><br><span class="line"> <span class="comment">// 将得到的复制对象 p 赋值给子类的原型,这样子类的原型就继承了父类的原型并且没有执行父类的构造函数</span></span><br><span class="line"> subClass.prototype = p</span><br><span class="line">}</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="function"><span class="keyword">function</span> <span class="title">superClass</span>(<span class="params">name</span>) </span>{</span><br><span class="line"> <span class="built_in">this</span>.name = name</span><br><span class="line"> <span class="built_in">this</span>.colors = [<span class="string">"red"</span>, <span class="string">"blue"</span>, <span class="string">"green"</span>]</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 定义父类原型方法</span></span><br><span class="line">superClass.prototype.getName = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">this</span>.name)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义子类</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">subClass</span>(<span class="params">name, time</span>) </span>{</span><br><span class="line"> <span class="comment">// 构造函数式继承</span></span><br><span class="line"> superClass.call(<span class="built_in">this</span>, name)</span><br><span class="line"> <span class="comment">// 子类新增属性</span></span><br><span class="line"> <span class="built_in">this</span>.time = time</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 寄生式继承父类原型</span></span><br><span class="line">inheritPrototype(subClass, superClass)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 子类新增原型方法</span></span><br><span class="line">subClass.prototype.getTime = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">this</span>.time)</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 创建两个测试方法</span></span><br><span class="line"><span class="keyword">var</span> instance1 = <span class="keyword">new</span> subClass(<span class="string">"js book"</span>, <span class="number">2014</span>)</span><br><span class="line"><span class="keyword">var</span> instance2 = <span class="keyword">new</span> subClass(<span class="string">"css book"</span>, <span class="number">2013</span>)</span><br><span class="line"><span class="built_in">console</span>.log(instance1.colors); <span class="comment">// [ 'red', 'blue', 'green' ]</span></span><br><span class="line">instance1.colors.push(<span class="string">"black"</span>)</span><br><span class="line"><span class="built_in">console</span>.log(instance1.colors); <span class="comment">// [ 'red', 'blue', 'green', 'black' ] </span></span><br><span class="line"><span class="built_in">console</span>.log(instance2.colors); <span class="comment">// [ 'red', 'blue', 'green' ]</span></span><br><span class="line"><span class="built_in">console</span>.log(instance1 <span class="keyword">instanceof</span> subClass); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(instance1 <span class="keyword">instanceof</span> superClass); <span class="comment">// true</span></span><br><span class="line"></span><br><span class="line">instance1.getTime() <span class="comment">// 2014</span></span><br><span class="line">instance1.getName() <span class="comment">// js book</span></span><br><span class="line">instance2.getTime() <span class="comment">// 2013</span></span><br><span class="line">instance2.getName() <span class="comment">// css book</span></span><br></pre></td></tr></table></figure><p> 组合式继承中,通过构造函数继承的属性和方法是没有问题的,所以这里主要探究<strong>通过寄生式继承重新继承父类的原型</strong>。<strong>需要继承的仅仅是父类的原型,不再需要调用父类的构造函数</strong>,换句话说:</p><ol><li><strong>在构造函数继承中我们己经调用了父类的构造函数。因此我们需要的就是父类的原型对象的一个副本,而这个副本我们通过原型继承便可得到。</strong></li><li><strong>但是这么直接赋值给子类会有问题的,因为对父类原型对象复制得到的复制对象<code>p</code>中的<code>constructor</code>指向的不是<code>subClass</code>子类对象,因此在寄生式继承中要对复制对象<code>p</code>做一次增强,修复其<code>constructor</code>属性指向不正确的问题。</strong></li><li><strong>最后将得到的复制对象<code>p</code>赋值给子类的原型,这样子类的原型就继承了父类的原型并且没有执行父类的构造函数</strong>。</li></ol><p> 这种方式继承如<strong>下图</strong>所示,其中<strong>最大的改变就是对子类原型的处理,被赋予父类原型的一个引用</strong>,这是一个对象,因此这里有一点要<strong>注意,就是子类再想添加原型方法必须通过<code>prototype.</code>对象,通过点语法的形式一个一个添加方法了,否则直接赋予对象就会覆盖掉从父类原型继承的对象了</strong>。</p><p><img src="/img/extends.jpg" alt="寄生组合式继承原型链图片" /></p><hr /><h3 id="多继承"><a class="markdownIt-Anchor" href="#多继承"></a> 多继承</h3><p> 先看一个很流行的用来继承单对象属性的<code>extend</code>方法。</p><figure class="highlight javascript"><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">var</span> extend = <span class="function"><span class="keyword">function</span> (<span class="params">target, source</span>) </span>{</span><br><span class="line"> <span class="comment">// 遍历源对象中的属性</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> property <span class="keyword">in</span> source) {</span><br><span class="line"> <span class="comment">// 将源对象中的属性复制到目标对象中</span></span><br><span class="line"> target[property] = source[property]superClass</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 返回目标对象</span></span><br><span class="line"> <span class="keyword">return</span> targetsuperClass</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p> <code>extend</code>方法的实现就是对对象中的属性的一个复制过程,这个<code>extend</code>方法是一个浅复制过程,他只能复制值类型的属性,对于引用类型的属性它无能为力。而在<code>jquery</code>等一些框架中实现了深复制,就是将源对象中的引用类型的属性再执行一遍<code>extend</code>方法而实现的。</p><p> 既然上面的方法可以实现对一个对象属性的复制继承,那么如果传递多个对象呢?</p><figure class="highlight javascript"><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">// 多继承 属性复制</span></span><br><span class="line"><span class="keyword">var</span> mix = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> i = <span class="number">1</span>, <span class="comment">// 从第二个参数起为被继承的对象</span></span><br><span class="line"> len = <span class="built_in">arguments</span>.length, <span class="comment">// 获取参数长度</span></span><br><span class="line"> target = <span class="built_in">arguments</span>[<span class="number">0</span>], <span class="comment">// 第—个对象为目标对象</span></span><br><span class="line"> arg <span class="comment">// 缓存参数对象</span></span><br><span class="line"> <span class="comment">// 遍历被继承的对象</span></span><br><span class="line"> <span class="keyword">for</span> (i < len; i++) {</span><br><span class="line"> <span class="comment">// 缓存当前对象</span></span><br><span class="line"> arg = <span class="built_in">arguments</span>[i]</span><br><span class="line"> <span class="comment">// 遍历被继承对象中的属性</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> property <span class="keyword">in</span> arg) {</span><br><span class="line"> <span class="comment">// 将被继承对象中的属性复制到目标对象中</span></span><br><span class="line"> target[property] = arg[property]</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 返回目标对象</span></span><br><span class="line"> <span class="keyword">return</span> target</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p> <code>mix</code>方法的作用就是将传入的多个对象的属性复制到源对象中,这样即可实现对多个对象的属性的继承。也可以将它绑定到原生对象<code>Object</code>上,这样所有的对象就可以拥有这个方法。</p><figure class="highlight javascript"><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="built_in">Object</span>.prototype.mix = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> i = <span class="number">0</span>, <span class="comment">// 从第—个参数起为被继承的对象</span></span><br><span class="line"> len = <span class="built_in">arguments</span>.length, <span class="comment">// 获取参数长度</span></span><br><span class="line"> arg <span class="comment">// 缓存参数对象</span></span><br><span class="line"> <span class="comment">// 遍历被继承的对象</span></span><br><span class="line"> <span class="keyword">for</span> (; i < len; i++) {</span><br><span class="line"> <span class="comment">// 缓存当前对象</span></span><br><span class="line"> arg = <span class="built_in">arguments</span>[i]</span><br><span class="line"> <span class="comment">// 遍历被继承对象中的属性</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> property <span class="keyword">in</span> arg) {</span><br><span class="line"> <span class="comment">// 将被继承对象中的属性复制到目标对象中</span></span><br><span class="line"> <span class="built_in">this</span>[property] = arg[property]</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> book1 = {</span><br><span class="line"> <span class="attr">name</span>: <span class="string">'Javascript设计模式'</span>,</span><br><span class="line"> <span class="attr">alike</span>: [<span class="string">'css'</span>, <span class="string">'html'</span>, <span class="string">'Javascript'</span>]</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> book2 = {</span><br><span class="line"> <span class="attr">color</span>: <span class="string">'blue'</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> otherBook = <span class="keyword">new</span> <span class="built_in">Object</span>()</span><br><span class="line"></span><br><span class="line">otherBook.mix(book1, book2)</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"> name: 'Javascript设计模式',</span></span><br><span class="line"><span class="comment"> alike: [ 'css', 'html', 'Javascript' ],</span></span><br><span class="line"><span class="comment"> mix: [Function],</span></span><br><span class="line"><span class="comment"> color: 'blue'</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="built_in">console</span>.log(otherBook)</span><br></pre></td></tr></table></figure><hr /><h2 id="总结"><a class="markdownIt-Anchor" href="#总结"></a> 总结</h2><p> <strong>继承即是对原有对象的封装</strong>,从中创建私有属性、私有方法、特权方法、共有属性、共有方法等,对于每种属性与每种方法特点是不一样的,有的<strong>不论对类如何实例化,它只创建一次,那么这类属性或者方法我们称之为静态的</strong>。有的<strong>只被类所拥有,那么这类属性和方法又是静态类方法与静态类属性</strong>。当然可被继承的方法与属性无外乎两类,一类在构造函数中,这类属性与方法在对象实例化时被复制一遍。另一类在类的原型对象中,这类属性与方法在对象实例化时被所有实例化对象所共用。</p><p> 提到类的实例化我们就引出了继承,当然如果实例化的是对象那么则为<strong>对象继承</strong>,如果实例化的是类(当然类也是一种对象,只不过是用来创建对象的),那么就是一种<strong>类的继承</strong>。对于<strong>类的继承</strong>我们根据继承的方式又分为很多种,<strong>通过原型链继承的方式我们称之为类式继承,通过构造函数继承的方式我们称之为构造函数式继承,那么将这两种方式组合起来的继承方式我们称之为组合继承,由于类式继承过程中会实例化父类,这样如果父类构造函数极其复杂,那么这种方式对构造函数的开销是不值得的,此时有了一种新的继承方式,通过在一个函数内的过渡对象实现继承并返回新对象的方式我们称之为寄生式继承,此时我们在结合构造函数时继承,这样再融合构造函数继承中的优点并去除其缺点,得到的继承方式我们称之为寄生组合式继承。</strong></p><p>当然有时候<strong>子类对父类实现继承可以通过拷贝方法与属性的方式来实现,这就有了多继承,即将多个父类(对象)的属性与方法拷贝给子类实现继承</strong>。</p>]]></content>
<summary type="html"><p> 通过下面的代码块可以看到,每个类都有3个部分,第一部分是构造函数内的,这是供实例化对象复制用的,第二部分是构造函数外的,直接通过点语法添加的,这是供类使用的,实例化对象是访问不到的,第三部分是类的原型中的,实例化对象可以通过其原型链间接地访问到,也是为供所有实例化对象所</summary>
<category term="前端" scheme="https://jerrywebleeblog.top/categories/%E5%89%8D%E7%AB%AF/"/>
<category term="javascript" scheme="https://jerrywebleeblog.top/tags/javascript/"/>
<category term="设计模式" scheme="https://jerrywebleeblog.top/tags/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"/>
<category term="面向对象" scheme="https://jerrywebleeblog.top/tags/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/"/>
</entry>
<entry>
<title>Git常用命令及常见场景下的Git操作</title>
<link href="https://jerrywebleeblog.top/2021/05/23/10/58/20210523Git%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4%E5%8F%8A%E5%B8%B8%E8%A7%81%E5%9C%BA%E6%99%AF%E4%B8%8B%E7%9A%84Git%E6%93%8D%E4%BD%9C/"/>
<id>https://jerrywebleeblog.top/2021/05/23/10/58/20210523Git%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4%E5%8F%8A%E5%B8%B8%E8%A7%81%E5%9C%BA%E6%99%AF%E4%B8%8B%E7%9A%84Git%E6%93%8D%E4%BD%9C/</id>
<published>2021-05-23T02:58:30.000Z</published>
<updated>2021-06-10T13:31:37.941Z</updated>
<content type="html"><![CDATA[<h3 id="git-四大分区"><a class="markdownIt-Anchor" href="#git-四大分区"></a> Git 四大分区</h3><ul><li>工作区(Working Area)</li><li>暂存区(Stage)</li><li>本地仓库(Local Repository)</li><li>远程仓库(Remote Repository)</li></ul><p><img src="/img/git1.png" alt="git" /></p><hr /><h3 id="git-操作流程图"><a class="markdownIt-Anchor" href="#git-操作流程图"></a> Git 操作流程图</h3><p><img src="/img/git2.png" alt="git操作流程图" /></p><blockquote><p>原图引自:<a href="https://blog.csdn.net/qq_35414779/article/details/82630079">Git 从原理到解决冲突</a></p></blockquote><hr /><h3 id="git-常用命令列表"><a class="markdownIt-Anchor" href="#git-常用命令列表"></a> Git 常用命令列表</h3><table><thead><tr><th style="text-align:center"><code>命令</code></th><th style="text-align:left"><code>含义</code></th></tr></thead><tbody><tr><td style="text-align:center"><code>git init</code></td><td style="text-align:left">初始化</td></tr><tr><td style="text-align:center"><code>git clone [url]</code></td><td style="text-align:left">复制远程仓库到本地</td></tr><tr><td style="text-align:center"><code>git remote add [origin] [url]</code></td><td style="text-align:left">将本地仓库关联到远程仓库</td></tr><tr><td style="text-align:center"><code>git remote rm [name]</code></td><td style="text-align:left">删除远程仓库</td></tr><tr><td style="text-align:center"><code>git remote set-url --push [name] [newUrl]</code></td><td style="text-align:left">修改远程仓库</td></tr><tr><td style="text-align:center"><code>git pull [remoteName] [localBranchName]</code></td><td style="text-align:left">拉取远程仓库</td></tr><tr><td style="text-align:center"><code>git push [remoteName] [localBranchName]</code></td><td style="text-align:left">推送到远程仓库</td></tr><tr><td style="text-align:center"><code>git push origin [localBranchName]:master</code></td><td style="text-align:left">提交本地分支<code>localBranchName</code>作为远程的<code>master</code>分支</td></tr><tr><td style="text-align:center"><code>git push origin [localBranchName]:[localBranchName]</code><br />或者<br /><code>git push origin [localBranchName]</code></td><td style="text-align:left">提交本地分支<code>localBranchName</code>作为远程的<code>localBranchName</code>分支</td></tr><tr><td style="text-align:center"><code>git branch</code></td><td style="text-align:left">查看本地分支</td></tr><tr><td style="text-align:center"><code>git branch -a</code></td><td style="text-align:left">查看本地分支和远程分支</td></tr><tr><td style="text-align:center"><code>git branch -r</code></td><td style="text-align:left">查看远程分支</td></tr><tr><td style="text-align:center"><code>git branch [name]</code></td><td style="text-align:left">创建本地分支,创建后并不会切换到该分支</td></tr><tr><td style="text-align:center"><code>git checkout -b [name]</code></td><td style="text-align:left">创建本地分支并切换到该分支</td></tr><tr><td style="text-align:center"><code>git checkout [name]</code></td><td style="text-align:left">切换到该分支</td></tr><tr><td style="text-align:center"><code>git merge [name]</code></td><td style="text-align:left">合并该分支到当前分支</td></tr><tr><td style="text-align:center"><code>git push origin [name]</code></td><td style="text-align:left">将本地分支推送到远程分支</td></tr><tr><td style="text-align:center"><code>git push origin :heads/[name]</code></td><td style="text-align:left">删除<code>name</code>远程分支</td></tr><tr><td style="text-align:center"><code>git tag</code></td><td style="text-align:left">查看所有<code>tag</code>信息</td></tr><tr><td style="text-align:center"><code>git tag [name]</code></td><td style="text-align:left">创建<code>tag</code>标签</td></tr><tr><td style="text-align:center"><code>git tag -d [name]</code></td><td style="text-align:left">删除<code>tag</code>标签</td></tr><tr><td style="text-align:center"><code>git tag -r</code></td><td style="text-align:left">查看远程 tag 标签</td></tr><tr><td style="text-align:center"><code>git push origin [tag]</code></td><td style="text-align:left">推送本地<code>tag</code>到远程仓库</td></tr><tr><td style="text-align:center"><code>git push origin :refs/tags/[name]</code></td><td style="text-align:left">删除远程标签</td></tr><tr><td style="text-align:center"><code>git commit -v</code></td><td style="text-align:left">当你用<code>-v</code>参数的时候可以看 commit 的差异</td></tr><tr><td style="text-align:center"><code>git pull origin --tags</code></td><td style="text-align:left">合并远程<code>tag</code>到本地</td></tr><tr><td style="text-align:center"><code>git push origin --tags</code></td><td style="text-align:left">推送本地 tag 到远程仓库</td></tr><tr><td style="text-align:center"><code>git tag -a [name] -m ['yourMessage']</code></td><td style="text-align:left">创建带注释的<code>tag</code></td></tr><tr><td style="text-align:center"><code>git status</code></td><td style="text-align:left">查看当前项目状态</td></tr><tr><td style="text-align:center"><code>git add .</code></td><td style="text-align:left">暂存修改</td></tr><tr><td style="text-align:center"><code>git commint -a/-m ['yourMessage']</code></td><td style="text-align:left">提交修改</td></tr><tr><td style="text-align:center"><code>git commit --amend ['yourMessage']</code></td><td style="text-align:left">对最近的一次提交注释信息进行修改,并重新提交</td></tr><tr><td style="text-align:center"><code>git remote show origin</code></td><td style="text-align:left">显示远程库<code>origin</code>里的资源</td></tr><tr><td style="text-align:center"><code>git checkout --track origin/dev</code></td><td style="text-align:left">切换到远程<code>dev</code>分支</td></tr><tr><td style="text-align:center"><code>git branch -D master develop</code></td><td style="text-align:left">删除本地库<code>develop</code>(未合并分支的强制删除)</td></tr><tr><td style="text-align:center"><code>git branch -d [branchName]</code></td><td style="text-align:left">删除已经合并过的分支</td></tr><tr><td style="text-align:center"><code>git push origin --delete [remoteBranchName]</code></td><td style="text-align:left">删除远程分支</td></tr><tr><td style="text-align:center"><code>git rm [fileName]</code></td><td style="text-align:left">从<code>git</code>中删除指定文件(从暂存区和工作区中删除)</td></tr><tr><td style="text-align:center"><code>git config --list</code></td><td style="text-align:left">查看配置列表</td></tr><tr><td style="text-align:center"><code>git ls-files</code></td><td style="text-align:left">查看已经被提交的文件</td></tr><tr><td style="text-align:center"><code>git ls-files -s</code></td><td style="text-align:left">查看保存在暂存区的文件,和 hash 值</td></tr><tr><td style="text-align:center"><code>git cat-file -p [暂存区文件hash值]</code></td><td style="text-align:left">显示保存在暂存区的文件的具体内容</td></tr><tr><td style="text-align:center"><code>git log</code></td><td style="text-align:left">查看你<code>commit</code>的日志</td></tr><tr><td style="text-align:center"><code>git log --pretty=oneline</code></td><td style="text-align:left">显示提交信息到一行</td></tr><tr><td style="text-align:center"><code>git diff</code></td><td style="text-align:left">查看尚未暂存的更新</td></tr><tr><td style="text-align:center"><code>git diff --cached/--staged</code></td><td style="text-align:left">查看哪写文件已暂存还没有提交,并显示文件具体的修改内容</td></tr><tr><td style="text-align:center"><code>git rm --cached [fileName]</code></td><td style="text-align:left">移除文件(只从暂存区中删除)</td></tr><tr><td style="text-align:center"><code>git rm -f [fileName]</code></td><td style="text-align:left">强行移除修改后文件(从暂存区和工作区中删除)</td></tr><tr><td style="text-align:center"><code>git diff --cached 或 $ git diff --staged</code></td><td style="text-align:left">查看尚未提交的更新</td></tr><tr><td style="text-align:center"><code>git stash push</code></td><td style="text-align:left">将文件给<code>push</code>到一个临时空间中</td></tr><tr><td style="text-align:center"><code>git stash pop</code></td><td style="text-align:left">将文件从临时空间<code>pop</code>下来</td></tr><tr><td style="text-align:center"><code>git stash list</code></td><td style="text-align:left">查看未完成的任务保存在栈中的任务列表</td></tr><tr><td style="text-align:center"><code>git pull</code></td><td style="text-align:left">本地与服务器端同步</td></tr><tr><td style="text-align:center"><code>git fetch</code></td><td style="text-align:left">相当于是从远程获取最新版本到本地,不会自动<code>merge</code></td></tr><tr><td style="text-align:center"><code>git commit -a -m ["log_message"]</code></td><td style="text-align:left">(<code>-a</code>是提交所有改动,<code>-m</code>是加入 log 信息) 本地修改同步至服务器端</td></tr><tr><td style="text-align:center"><code>git branch [branchName] master</code></td><td style="text-align:left">从主分支 master 创建<code>[branchName]</code>分支</td></tr><tr><td style="text-align:center"><code>git branch -m [oldBranchName] [newBranchName]</code></td><td style="text-align:left">将<code>[oldBranchName]</code>修改为<code>[newBranchName]</code></td></tr><tr><td style="text-align:center"><code>git checkout [branchName]/master</code></td><td style="text-align:left">切换到<code>[branchName]/master</code>分支</td></tr><tr><td style="text-align:center"><code>git config --global --unset[ user.name]</code></td><td style="text-align:left">删除全局配置的用户名</td></tr><tr><td style="text-align:center"><code>git config --global --unset [user.email]</code></td><td style="text-align:left">删除全局配置的 emai</td></tr><tr><td style="text-align:center"><code>mv [oldFileName] [newFileName]</code></td><td style="text-align:left">文件重命名</td></tr><tr><td style="text-align:center"><code>git reflog</code></td><td style="text-align:left">查看之前所有的提交记录,包括已经被删除的,在<code>git log</code>中不显示的</td></tr><tr><td style="text-align:center"><code>git stash apply stash [栈hash]</code></td><td style="text-align:left">根据存储在栈中的 hash 值取出未完成的任务</td></tr><tr><td style="text-align:center"><code>git remote set-head origin -d</code></td><td style="text-align:left">删除<code>origin/HEAD</code>指针,无影响</td></tr></tbody></table><p><code>git checkout [newBranch]</code>使用注意:每次切换分支前,确保当前分支必须得是干净的;在切换分支时,如果当前分支上有未暂存的修改(第一次)或者有未提交的暂存(第一次),分支可以切换成功,但是这种操作可能会污染其他分支.</p><hr /><h3 id="git-命令重命名简化"><a class="markdownIt-Anchor" href="#git-命令重命名简化"></a> git 命令重命名(简化)</h3><ul><li><p><code>git lg</code> – 格式化展示提交信息</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">git config --global alias.lg <span class="string">"log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %C(bold blue)%s%Creset %Cgreen(%cr) <%an>%Creset' --abbrev-commit --date=relative"</span></span><br></pre></td></tr></table></figure></li><li><p><code>git lga</code> – 格式化展示提交信息(实现的操作同上,命令名为<code>lga</code>)</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">git config --global alias.lga <span class="string">"log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %C(bold blue)%s%Creset %Cgreen(%cr) <%an>%Creset' --abbrev-commit --date=relative"</span></span><br></pre></td></tr></table></figure></li></ul><hr /><h3 id="常见场景-git-操作"><a class="markdownIt-Anchor" href="#常见场景-git-操作"></a> 常见场景 Git 操作</h3><h4 id="将当前修改的内容提交到新的分支上"><a class="markdownIt-Anchor" href="#将当前修改的内容提交到新的分支上"></a> 将当前修改的内容提交到新的分支上</h4><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></pre></td><td class="code"><pre><span class="line"><span class="comment"># 步骤1:在当前分支上的修改暂存起来</span></span><br><span class="line">git stash</span><br><span class="line"><span class="comment"># 步骤2:暂存修改后,在本地新建分支(new_branch为新分支的名字)</span></span><br><span class="line">git checkout -b new_branch</span><br><span class="line"><span class="comment"># 步骤3:将暂存的修改放到新建分支中</span></span><br><span class="line">git stash pop</span><br><span class="line"><span class="comment"># 步骤4:</span></span><br><span class="line">git add .</span><br><span class="line">git commit -m [<span class="string">'commit message'</span>]</span><br><span class="line"><span class="comment"># 步骤5:将提交的内容push到远程服务器</span></span><br><span class="line">git push</span><br></pre></td></tr></table></figure><p><code>git stash</code>的作用是把工作区(必须是工作区中已经被<code>git</code>追踪到的文件)和索引中的内容暂时存到一个堆上,而且这个堆是和分支不相关的。切换分支后,依然可以看到并使用。</p><p>当正在进行项目中某一部分的工作处于一个比较杂乱的状态,而你想转到其他分支上进行一些工作。但你不想提交进行了一半的工作,否则以后你无法回到这个工作点。解决这个问题的办法就是<code>git stash</code>命令。</p><p>“‘储藏”可以获取你工作目录的中间状态——也就是你修改过的被追踪的文件和暂存的变更——并将它保存到一个未完结变更的堆栈中,随时可以重新应用。</p><h4 id="实际项目中的创建新分支及合并操作"><a class="markdownIt-Anchor" href="#实际项目中的创建新分支及合并操作"></a> 实际项目中的创建新分支及合并操作</h4><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="comment"># 步骤1:创建子分支</span></span><br><span class="line">git checkout -b [newBranch]</span><br><span class="line"><span class="comment"># 步骤2:完成该分支的需求</span></span><br><span class="line"><span class="comment"># 步骤3:添加提交</span></span><br><span class="line">git add .</span><br><span class="line">git commit -m [<span class="string">'commit message'</span>]</span><br><span class="line"><span class="comment"># 返回主分支合并子分子</span></span><br><span class="line">git checkout master</span><br><span class="line">git merge [newBranch]</span><br><span class="line"><span class="comment"># 推送到远程仓库</span></span><br><span class="line">git push</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">git pull</span><br><span class="line">git checkout [newBranch]</span><br><span class="line">git push origin [newBranch] / git push -u origin [newBranch]</span><br><span class="line"></span><br><span class="line"><span class="comment"># 如果远程分支没有创建关联,使用下面的代码创建远程分支并关联到本地分支</span></span><br><span class="line">git branch --set-upstream [newBranch] origin/[newBranch]</span><br></pre></td></tr></table></figure><hr /><blockquote><p>详细内容请参考<a href="https://git-scm.com/docs">git 文档</a>;如有错误请在右侧导航处邮件联系,或者在下方评论区指出.</p></blockquote>]]></content>
<summary type="html"><h3 id="git-四大分区"><a class="markdownIt-Anchor" href="#git-四大分区"></a> Git 四大分区</h3>
<ul>
<li>工作区(Working Area)</li>
<li>暂存区(Stage)</li>
<li>本</summary>
<category term="前端" scheme="https://jerrywebleeblog.top/categories/%E5%89%8D%E7%AB%AF/"/>
<category term="Git" scheme="https://jerrywebleeblog.top/tags/Git/"/>
</entry>
<entry>
<title>JavaScript设计模式——原型设计模式</title>
<link href="https://jerrywebleeblog.top/2021/05/22/00/21/20210522js%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F_%E5%8E%9F%E5%9E%8B%E6%A8%A1%E5%BC%8F/"/>
<id>https://jerrywebleeblog.top/2021/05/22/00/21/20210522js%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F_%E5%8E%9F%E5%9E%8B%E6%A8%A1%E5%BC%8F/</id>
<published>2021-05-21T16:21:20.000Z</published>
<updated>2021-05-23T03:02:41.863Z</updated>
<content type="html"><![CDATA[<p><strong>所谓设计模式,是复现问题模型的思想的一种具体表现。一个问题模型可能有多种表达形式,但是如何将这类相似模型用代码的形式表现出来用以处理实际问题,这就产生了设计模式,设计模式是问题模型的具象化</strong>。</p><p>javascript没有提供传统面向对象语言中类式继承,而是通过<strong>原型委托</strong>的方式来实现对象与对象之间的继承。</p><p>面向接口编程是设计模式中最重要的思想,但是在JavaScript中,面向接口编程的过程跟主流的静态类型语言不一样。</p><hr /><h2 id="动态类型语言和静态类型语言"><a class="markdownIt-Anchor" href="#动态类型语言和静态类型语言"></a> 动态类型语言和静态类型语言</h2><p>编程语言按照数据类型大体可以分为两类:<strong>静态类型语言</strong>和<strong>动态类型语言</strong>。</p><h3 id="静态类型语言"><a class="markdownIt-Anchor" href="#静态类型语言"></a> 静态类型语言:</h3><p>在编译时便已确定变量的类型。</p><h4 id="优点"><a class="markdownIt-Anchor" href="#优点"></a> 优点:</h4><ol><li>编译时就能发现类型不匹配的错误,编辑器可以帮助我们提前避免程序运行期间有可能发生的一些错误。</li><li>在程序中明确地规定了数据类型,编译器还可以针对性的对程序进行优化,提高执行速度。</li></ol><h4 id="缺点"><a class="markdownIt-Anchor" href="#缺点"></a> 缺点:</h4><ol><li>迫使程序员依照强契约来编写程序。</li><li>类型的声明增加更多代码,编程中这些细节会将程序员的经历从思考业务逻辑上分散开。</li></ol><h3 id="动态类型语言"><a class="markdownIt-Anchor" href="#动态类型语言"></a> 动态类型语言:</h3><p>其变量类型要到程序运行时,待变量被赋予某个值后,才会具有某种类型。</p><h4 id="优点-2"><a class="markdownIt-Anchor" href="#优点-2"></a> 优点:</h4><ol><li>代码量少,简洁,程序员可以将更多逻辑放在业务逻辑上面,专注逻辑表达,对阅读程序有帮助。</li></ol><h4 id="缺点-2"><a class="markdownIt-Anchor" href="#缺点-2"></a> 缺点:</h4><ol><li>无法保证变量的类型。</li></ol><hr /><h2 id="多态"><a class="markdownIt-Anchor" href="#多态"></a> 多态</h2><p>同一操作作用于不同的对象上面,可以产生不同的解释和不同的执行结果。</p><p>多态背后的思想,是将“做什么”和“谁去做”以及“怎样去做”分离开,也就是将“不变的事物”与“可能改变的事物”分离开。要实现这一点,归根结底要先消除类型之间的耦合关系。</p><p>多态性实际上指的是对象的多态性。</p><p>使用<strong>继承</strong>得到多态效果,继承一般包括实现继承和接口继承。</p><p><strong>多态的最根本作用就是通过把过程化的条件分支语句转化为对象的多态性,从而消除这些条件分支语句</strong></p><p>利用对象的多态性,不必考虑各个对象接到消息后应该做什么,对象应该做什么并不是临时决定的,而是事先已经约定好的,每个对象该做什么,已经成为了该对象的一个方法,被安装在对象内部,每个对象负责他们自己的行为。所以这些都想可以根据同一个消息有条不紊的分别执行自己的方法。</p><p><strong>将行为分布在各个对象种,并让这些对象各自负责自己的行为,这正是面向对象设计的优点。</strong></p><hr /><h2 id="封装"><a class="markdownIt-Anchor" href="#封装"></a> 封装</h2><p>封装的目的是将数据隐藏,一般而言是封装数据和封装实现,更广义的封装,还包括封装类型和封装变化。</p><h3 id="封装数据"><a class="markdownIt-Anchor" href="#封装数据"></a> 封装数据</h3><p>在java种提供了 <code>private</code>,<code>public</code>,<code>protected</code>等关键字来提供不同的访问权限。但是JavaScript种没有该关键字,只能依赖于变量的作用域来实现封装特性,而且只能模拟出<code>private</code>,<code>public</code>两种封装性。</p><figure class="highlight javascript"><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="keyword">var</span> myObject = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">var</span> _name = <span class="string">'Jerry'</span> <span class="comment">// 私有变量</span></span><br><span class="line"> <span class="keyword">return</span> {</span><br><span class="line"> <span class="attr">getName</span>:<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{ <span class="comment">// 共有方法</span></span><br><span class="line"> <span class="keyword">return</span> _name</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">})()</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(myObject.getName()) <span class="comment">// 输出:Jerry</span></span><br><span class="line"><span class="built_in">console</span>.log(myObject._name) <span class="comment">// 输出:undefined</span></span><br></pre></td></tr></table></figure><h3 id="封装实现"><a class="markdownIt-Anchor" href="#封装实现"></a> 封装实现</h3><p>封装使得对象内部的变化对其他对象而言是透明的,也就是不可见的。对象对他自己的行为负责。封装使得对象之间的耦合变得松散。对象之间只能通过对外的接口来通信。当我们修改一个对象时,可以随意的修改他的内部实现,只要对外的接口没有变化,就不会影响到程序的其他功能。</p><h3 id="封装类型"><a class="markdownIt-Anchor" href="#封装类型"></a> 封装类型</h3><p>封装类型是<strong>静态类型语言</strong>种的一种重要的封装方式。</p><h3 id="封装变化"><a class="markdownIt-Anchor" href="#封装变化"></a> 封装变化</h3><p><strong>找到变化并封装之</strong></p><p>通过封装变化的方式,把系统中稳定不变的部分和容易变化的部分隔离开,在系统演变的过程中,我们只需要替换那些容易变化的部分,如果这些是已经封装好的,替换起来也相对容易。可以最大程度的保证程序的稳定性和可扩展性。</p><hr /><h2 id="原型模式和基于原型继承的javascript对象系统"><a class="markdownIt-Anchor" href="#原型模式和基于原型继承的javascript对象系统"></a> 原型模式和基于原型继承的JavaScript对象系统</h2><p>在以类为中心的面向对象编程语言种,类和对象的关系可以 想象成铸模和铸件的关系,对象总是从类中创建而来。而在原型编程思想种,类并不是必须的,对象未必需要从类中创建而来,一个对象是通过克隆另一个对象所得到的。</p><p>原型不单是一种设计模式,也被称为一种编程泛型。</p><h3 id="使用克隆的原型模式"><a class="markdownIt-Anchor" href="#使用克隆的原型模式"></a> 使用克隆的原型模式</h3><p>从设计模式的角度讲,原型模式是用于创建对象的一种模式,如果我们想要创建一个对象,一种方法是先指定它的类型,然后通过类来创建这个对象。原型模式选择了另外一种方式,我们不再关心对象的具体类型,而是找到一个对象,然后通过克隆来创建一个一模一样的对象。</p><p>原型模式实现的关键,是语言本身是否提供了clone方法,ES5提供了<code>Object.create()</code>方法,可以用来克隆对象,代码如下:</p><figure class="highlight javascript"><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">var</span> Plane = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="built_in">this</span>.blood = <span class="number">100</span></span><br><span class="line"> <span class="built_in">this</span>.attackLevel = <span class="number">1</span></span><br><span class="line"> <span class="built_in">this</span>.defenseLevel = <span class="number">1</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> plane = <span class="keyword">new</span> Plane()</span><br><span class="line">plane.blood = <span class="number">500</span></span><br><span class="line">plane.attackLevel = <span class="number">10</span></span><br><span class="line">plane.defenseLevel = <span class="number">7</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(plane);</span><br><span class="line"><span class="keyword">var</span> clonePlane = <span class="built_in">Object</span>.create(plane)</span><br><span class="line"><span class="built_in">console</span>.log(clonePlane.__proto__)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 在不支持Object.create()方法的浏览器中,可以使用</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">Object</span>.create = <span class="built_in">Object</span>.create || <span class="function"><span class="keyword">function</span> (<span class="params">obj</span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> F = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> F.prototype = obj</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> F()</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="克隆是创建对象的手段"><a class="markdownIt-Anchor" href="#克隆是创建对象的手段"></a> 克隆是创建对象的手段</h3><p>原型模式的真正目的并非在于需要得到一个一模一样的对象,而是提供了一种便捷的方式去创建某个类型的对象,克隆只是创建这个对象的过程和手段。</p><p>JavaScript 就是使用原型模式来搭建整个面向对象系统的。在JavaScript 语言中不存在类的概念,对象也并非从类中创建出来的,所有的JavaScript 对象都是从某个对象上克隆而来的。</p><h3 id="javascript中的原型继承"><a class="markdownIt-Anchor" href="#javascript中的原型继承"></a> JavaScript中的原型继承</h3><ol><li>所有的数据都是对象。</li><li>要得到一个对象,不是通过实例化类,而是找到一个对象作为原型并克隆它。</li><li>对象会记住它的原型。</li><li>如果对象无法响应某个请求,它会把这个请求沿着原型链继续查找。</li></ol><p>JavaScript 的函数既可以作为普通函数被调用,也可以作为构造器被调用。当使用new 运算符来调用函数时,此时的函数就是一个构造器。 用new 运算符来创建对象的过程,实际上也只是先克隆<code>Object.prototype</code> 对象,再进行一些其他额外操作的过程。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Person</span>(<span class="params">name</span>) </span>{</span><br><span class="line"> <span class="built_in">this</span>.name = name</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">Person.prototype.getName = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">this</span>.name</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> person1 = <span class="keyword">new</span> Person(<span class="string">'Jerry'</span>)</span><br><span class="line"><span class="keyword">var</span> objectFactory = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> obj = <span class="keyword">new</span> <span class="built_in">Object</span>(),</span><br><span class="line"> Constructor = [].shift.call(<span class="built_in">arguments</span>) <span class="comment">// 删除参数数组的第一个值赋值给Constructor</span></span><br><span class="line"> <span class="comment">// console.log(Constructor);</span></span><br><span class="line"> obj.__proto__ = Constructor.prototype <span class="comment">// 指向正确的原型,把Person函数的getName()方法给obj</span></span><br><span class="line"> <span class="keyword">var</span> ret = Constructor.apply(obj, <span class="built_in">arguments</span>) <span class="comment">// 借用外部传入的构造器给obj空对象设置name属性</span></span><br><span class="line"> <span class="built_in">console</span>.log(obj); <span class="comment">// Person { name: 'Jerry' }</span></span><br><span class="line"> <span class="built_in">console</span>.log(ret); <span class="comment">// undefined</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">typeof</span> ret === <span class="string">'object'</span> ? ret : obj</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> person2 = objectFactory(Person, <span class="string">'Jerry'</span>)</span><br><span class="line"><span class="built_in">console</span>.log(person1);</span><br><span class="line"><span class="built_in">console</span>.log(person2);</span><br></pre></td></tr></table></figure><p>ES6带来了新的语法Class。这让JavaScript看起来像是一门基于类的语言,但其背后仍是通过<strong>原型机制</strong>来创建对象。</p>]]></content>
<summary type="html"><p><strong>所谓设计模式,是复现问题模型的思想的一种具体表现。一个问题模型可能有多种表达形式,但是如何将这类相似模型用代码的形式表现出来用以处理实际问题,这就产生了设计模式,设计模式是问题模型的具象化</strong>。</p>
<p>javascript没有提供传统面</summary>
<category term="前端" scheme="https://jerrywebleeblog.top/categories/%E5%89%8D%E7%AB%AF/"/>
<category term="javascript" scheme="https://jerrywebleeblog.top/tags/javascript/"/>
<category term="设计模式" scheme="https://jerrywebleeblog.top/tags/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"/>
<category term="面向对象" scheme="https://jerrywebleeblog.top/tags/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/"/>
</entry>
</feed>