JavaScript Item37—— 面向对象高级程序设计

Posted zealifree005

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript Item37—— 面向对象高级程序设计相关的知识,希望对你有一定的参考价值。

1. JS是基于原型的程序

建立一个简单的面向对象的类。有属性,有方法。

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-title" style="box-sizing: border-box;">Aaa</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.name = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'小明'</span>;

Aaa.prototype.showName = <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span></span>
    alert( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.name );
;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> a1 = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Aaa();
a1.showName();</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

在JS的自身的对象中,也是new一个对象,然后调用方法,比如:

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> arr = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Array</span>();
arr.push();
arr.sort();</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

在JS源码 : 系统对象也是基于原型的程序。比如:

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-title" style="box-sizing: border-box;">Array</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.lenglth = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;

<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Array</span>.prototype.push = <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span></span>;
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Array</span>.prototype.sort = <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span></span>;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

尽量不要去修改或者添加系统对象下面的方法和属性,这样会改变系统的方法。

<code class="hljs delphi has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> arr = [<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>];
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Array</span>.prototype.push = <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"></span>
<span class="hljs-title" style="box-sizing: border-box;">arr</span>.<span class="hljs-title" style="box-sizing: border-box;">push</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(4,5,6)</span>;</span>
alert( arr );</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

这样修改后,push方法就失效了,覆盖了JS本省的push方法。

那么如何自己重写Array的push方法呢?

<code class="hljs actionscript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> arr = [<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>];
Array.prototype.push = <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//this : 1,2,3</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//arguments : 4,5,6</span>

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> i=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;i<arguments.length;i++)
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>[<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.length] = arguments[i]
    

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.length;
;

arr.push(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>);

alert( arr );*/

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//pop shift unshift splice sort</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>

2.JS中的包装对象

我们知道js的基本数据类型有 string, number, boolean, null, undefined, object.但是当你看到下面的代码时,你发现了什么?

<code class="hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">var <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span> = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'hello'</span>;

alert( typeof <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span> );<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//String</span>

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>.charAt(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>.indexOf(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'e'</span>);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

除了对象可以调用方法,为什么基本数据类型也可以?这是因为在js中,string, number, boolean都有自己的包装对象。String Number Boolean

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> str = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'hello'</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//通过构造函数构造的数据类型就是对象了,可以直接调用方法了</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//alert( typeof str );</span>

alert(str.charAt(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>));

<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>.prototype.charAt = <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span></span>;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

那基本类型调用方法时,发生了什么呢?

<code class="hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">var <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span> = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'hello'</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>.charAt(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//基本类型会找到对应的包装对象类型,然后包装对象把所有的属性和方法给了基本类型,然后包装对象消失,包装类型就和快递员一样。</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

比如要实现字符串的一个lastValue方法:

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> str = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'hello'</span>;

<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>.prototype.lastValue = <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.charAt(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.length-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);
;

alert( str.lastValue() ); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//o</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

str通过原型继承,使本身具有了lastValue()方法,所以可以直接调用,我们再来看个例子:

<code class="hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">var <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span> = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'hello'</span>;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>.number = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>;

alert( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>.number );  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//undefined</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

这里为什么是undefined,因为这里包装类型并没有把number共享给str,只是自己有,而复制完消失,str.name没有接受到值,变成undefined。

3. JS中的原型链

在js中,实例对象与原型之间的连接,叫做原型链,原型链之间的连接叫__proto__( 隐式连接 )

原型链的最外层是Object。

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-title" style="box-sizing: border-box;">Aaa</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span></span>


Aaa.prototype.num = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> a1 = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Aaa();
alert(a1.num);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

比如我们一般的定义一个对象Aaa,并在原型上定义了一个属性num,新new的a1是怎么访问到原型上的属性的呢?

这里就是a1有一个__proto__属性,指向Aaa.prototype原型对象,顾可以访问到。

假如这样呢?

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-title" style="box-sizing: border-box;">Aaa</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.num = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>;

Aaa.prototype.num = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> a1 = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Aaa();
alert(a1.num);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//20</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

这里有两个num,弹出的是哪一个呢?这就是原型链的规则,先从本身对象找,本身对象没有到原型对象上找,。。。。。一直找下去,何处是尽头?知道找到object的原型,如果没有就报错,因为object的原型是null,这个原型连接起来的链就是一条原型链。看例子

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-title" style="box-sizing: border-box;">Aaa</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//this.num = 20;</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Aaa.prototype.num = 10;</span>
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Object</span>.prototype.num = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">30</span>;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> a1 = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Aaa();
alert(a1.num);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

4. 面向对象的一些常用属性和方法

  • hasOwnProperty() : 看是不是对象自身下面的属性
<code class="hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">var arr = [];
arr.num = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>;
<span class="hljs-constant" style="box-sizing: border-box;">Array</span>.prototype.num2 = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>;

<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//alert</span>(  arr.hasOwnProperty(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'num'</span>)  );  <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//true</span>

alert(  arr.hasOwnProperty(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'num2'</span>)  );  <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//false</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>
  • constructor : 查看对象的构造函数 
    • 每个原型都会自动添加constructor属性
    • For in 的时候有些属性是找不到的
    • 避免修改construtor属性
<code class="hljs delphi has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-title" style="box-sizing: border-box;">Aaa</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">
</span>

<span class="hljs-title" style="box-sizing: border-box;">var</span> <span class="hljs-title" style="box-sizing: border-box;">a1</span> = <span class="hljs-title" style="box-sizing: border-box;">new</span> <span class="hljs-title" style="box-sizing: border-box;">Aaa</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span>;</span>

alert( a1.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">constructor</span> );  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Aaa</span>

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> arr = [];
alert( arr.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">constructor</span> == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Array</span> );  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//true</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

每个对象的原型的构造函数都自动指向本身,可以修改为别的,但是不建议修改:

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-title" style="box-sizing: border-box;">Aaa</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span></span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Aaa.prototype.constructor = Aaa;   //每一个函数都会有的,都是自动生成的</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Aaa.prototype.constructor = Array;</span>

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> a1 = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Aaa();</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>
alert( a1.hasOwnProperty == Object.prototype.hasOwnProperty );  //true

说明hasOwnProperty 属性是通过原型链,在Object.prototype原型上的。

有时候我们会不经意的就把原型修改了,这个时候我们就要把原型修正一下:

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-title" style="box-sizing: border-box;">Aaa</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span></span>


Aaa.prototype.name = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'小明'</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//采用这种原型继承,constructor没有改变</span>
Aaa.prototype.age = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>;

Aaa.prototype = <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//采用json格式的对象,这就是相当于一个Object对象赋值,所以constructor变为了Object。</span>
    constructor : Aaa,
    name : <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'小明'</span>,
    age : <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>
;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> a1 = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Aaa();
alert( a1.constructor );</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>

采用for in循环,是循环不到原型上constructor属性的。

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-title" style="box-sizing: border-box;">Aaa</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span></span>


Aaa.prototype.name = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>;
Aaa.prototype.constructor = Aaa;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> attr <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> Aaa.prototype )
    alert(attr);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//只有name</span>
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;"&g

以上是关于JavaScript Item37—— 面向对象高级程序设计的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript Item37—— 面向对象高级程序设计

javascript模拟面向对象一种比较好的写法

Javascript面向对象篇

VueJS/Javascript:预期的数组得到了对象

Effective JavaScript Item 37 认识this的隐式指向

python面向对象---- item系列