首頁  >  文章  >  web前端  >  理解Javascript中的“+”運算符

理解Javascript中的“+”運算符

巴扎黑
巴扎黑原創
2017-04-15 09:06:011591瀏覽
<p>在網路上或面試題中常常會看到一些「奇怪」的語句,例如</p> <pre class="brush:php;toolbar:false">{}+{} // "[object Object][object Object]" {}+[] // 0 []+{} // "[object Object]" []+[] // ""</pre> <p>在Javascript中<code>+</code>運算子是個重載運算符,可用於拼接字符串,以及把兩個「數字」相加。至於是哪一種情況要看運算子兩邊參數的類型。  <br>在日常的發展中我們也不會碰到這麼麻煩的事,但要弄清楚總是好的。在規範中巴拉巴拉地說了一堆,簡單來說就是:</p> <p>1. 對於原生類型,參數中只要有一方是字串,則按字串連接處理,否則按數字相加處理,不是數字的會先轉成數字再相加。 </p> <p>原生型別有:undefined, null, boolean, number, string。 </p> <p>以下是一些範例:</p> <pre class="brush:php;toolbar:false">0 + '1'     // '01' null + 1    // 1 true + 1    // 2 false + 1   // 0 undefined + 2   // NaN,  因为undefined转成Number是NaN</pre> <p>2. 對於參考類型,則需要先轉換成原生類型,再按上述規則相加。如何轉換在規範中有詳細的說明,但規範看起來有點費力。 簡單來說就是:預設都轉換成字串,要搞特殊的話,請重寫<code>valueOf()</code>方法。 </p> <p>來個例子:</p> <pre class="brush:php;toolbar:false">function Complex(a, b) {   this.a = a;   this.b = b; } Complex.prototype.valueOf() {   return this.a; } new Complex(2, 3) + new Complex(4, 5); // 6</pre> <p>但由於Js不支援真正的運算子重載,也就是無法相加得到自訂類型的對象, 所以以上範例在實作程式碼中非常少用。 </p> <p>不過目前的知識已經足夠回答原先的問題了。但慢著,<code>{}+[]</code> 為什麼和 <code>[]+{}</code>不一樣? 這其實是文法問題。前者相當於:</p> <pre class="brush:php;toolbar:false">{} +[]</pre> <p>其實是兩個句子, <code>[]</code> 轉換成數字是 0。很容易驗證<code>({}+[]) === '[object Object]'</code></p> <pre class="brush:php;toolbar:false">+[]  // 0</pre> <p>有人可能要問,那<code>new Date()</code> 的<code>valueOf()</code> 不是轉換成數字嗎?為什麼相加結果還是字串型呢? </p> <pre class="brush:php;toolbar:false">new Date().valueOf(); // 1491904757087 1 + new Date(); // "1Tue Apr 11 2017 18:02:16 GMT+0800 (CST)"</pre> <p>這是Date類別做了特殊處理, @@toPrimitive, 預設情況下對 <code>Date</code> 的相加以字串方式連接,但比較時則會轉換成數字。 </p> <pre class="brush:php;toolbar:false">new Date() < new Date(&#39;2018-01-01&#39;) // true, 现在是2017</pre><p>將引用類型轉換成原生類型在許多運算元中都有用到,例如<code><</code>, <code>>, 所以有必要對其研究一番, 以下js程式碼大概描述了其行為。 <pre class="brush:php;toolbar:false">/**  * @param input     即要转换的对象  * @preferredType   期望转换成的类型,可以是string或number  */ function ToPrimitive(input, preferredType) {   if (typeof input !== 'object') {     return input;   // 本来就是原生类型   }   var hint = preferredType || 'default';   if (typeof input['@@toPrimitive'] === 'function') {   // @@toPrimitive是个内部方法,这里只是示例说明其工作原理     return input['@@toPrimitive'](input, hint);   // 这就是为什么Date能特殊处理的原因   }   if (hint === 'string') {     return input.toString();   }   return input.valueOf(); }</pre><p>詳細的請參考規格</p><p class="article fmt article__content"><br></p><p>在網路上或面試題目中常會看到一些「奇怪」的語句,例如</p><pre class="brush:php;toolbar:false">{}+{} // "[object Object][object Object]" {}+[] // 0 []+{} // "[object Object]" []+[] // ""</pre><p>在Javascript中<code>+</code>運算子是個重載運算符,可用來拼接字串,以及把兩個「數字」相加。至於是哪一種情況要看運算子兩邊參數的類型。  <br>在日常的發展中我們也不會碰到這麼麻煩的事,但要弄清楚總是好的。在規範中巴拉巴拉地說了一堆,簡單來說就是:</p><p>1. 對於原生類型,參數中只要有一方是字串,則按字串連接處理,否則按數字相加處理,不是數字的會先轉成數字再相加。 </p><p>原生型別有:undefined, null, boolean, number, string。 </p><p>以下是一些範例:</p><pre class="brush:php;toolbar:false">0 + '1'     // '01' null + 1    // 1 true + 1    // 2 false + 1   // 0 undefined + 2   // NaN,  因为undefined转成Number是NaN</pre><p>2. 對於參考類型,則需要先轉換成原生類型,再按上述規則相加。如何轉換在規範中有詳細的說明,但規範看起來有點費力。 簡單來說就是:預設都轉換成字串,要搞特殊的話,請重寫<code>valueOf()</code>方法。 </p><p>來個例子:</p><pre class="brush:php;toolbar:false">function Complex(a, b) {   this.a = a;   this.b = b; } Complex.prototype.valueOf() {   return this.a; } new Complex(2, 3) + new Complex(4, 5); // 6</pre><p>但由於Js不支援真正的運算子重載,也就是無法相加得到自訂類型的對象, 所以以上範例在實作程式碼中非常少用。 </p><p>不過目前的知識已經足夠回答原先的問題了。但慢著,<code>{}+[]</code> 為什麼和 <code>[]+{}</code>不一樣? 這其實是文法問題。前者相當於:</p><pre class="brush:php;toolbar:false">{} +[]</pre><p>其實是兩個句子, <code>[]</code> 轉換成數字是 0。很容易驗證<code>({}+[]) === '[object Object]'</code></p><pre class="brush:php;toolbar:false">+[]  // 0</pre><p>有人可能要問,那<code>new Date()</code> 的<code>valueOf()</code> 不是轉換成數字嗎?為什麼相加結果還是字串型呢? </p><pre class="brush:php;toolbar:false">new Date().valueOf(); // 1491904757087 1 + new Date(); // "1Tue Apr 11 2017 18:02:16 GMT+0800 (CST)"</pre><p>這是Date類別做了特殊處理, @@toPrimitive, 預設情況下對 <code>Date</code> 的相加以字串方式連接,但比較時則會轉換成數字。 </p><pre class="brush:php;toolbar:false">new Date() < new Date(&#39;2018-01-01&#39;) // true, 现在是2017</pre><p>將引用類型轉換成原生類型在許多運算元中都有用到,例如<code><</code>, <code>>, 所以有必要對其研究一番, 以下js程式碼大概描述了其行為。 <pre class="brush:php;toolbar:false">/**  * @param input     即要转换的对象  * @preferredType   期望转换成的类型,可以是string或number  */ function ToPrimitive(input, preferredType) {   if (typeof input !== 'object') {     return input;   // 本来就是原生类型   }   var hint = preferredType || 'default';   if (typeof input['@@toPrimitive'] === 'function') {   // @@toPrimitive是个内部方法,这里只是示例说明其工作原理     return input['@@toPrimitive'](input, hint);   // 这就是为什么Date能特殊处理的原因   }   if (hint === 'string') {     return input.toString();   }   return input.valueOf(); }</pre><p class="col-md-8"><br></p><p class="comments-box-content"><br></p>#</pre></pre>

以上是理解Javascript中的“+”運算符的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn