首页 >web前端 >js教程 >理解Javascript中的“+”运算符

理解Javascript中的“+”运算符

巴扎黑
巴扎黑原创
2017-04-15 09:06:011608浏览
<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