将介绍JavaScript中 '+'加号运算符在一元、二元运算时的表现。

目录

1.一元运算符

2. 二元运算符

1. 一元运算符

语法: + Expression

说明:'+'号运算符作为一元运算符时,Expression将进行ToNumber()操作。

ToNumber( argument )转换方式:

argument类型 返回值
Undefined return NaN
Null return +0
Boolean true return 1; false return 0;
Number return value
String 若字符串为纯数字时返回转换后的数字;非纯数字返回NaN
Symbol 抛出 TypeError 异常
Object

进行以下步骤:

1.先进行ToPrimitive(argument, hint Number)得到rs;
2.然后返回 ToNumber(rs)的结果。

示例:

// Undefined
+ undefined; // => NaN // Null
+ null; // => 0 // Boolean
+ true; // => 1
+ false; // => 0 // String
+ '1'; // => 1
+ '-1'; // => -1
+ 'a1'; // => NaN // Object
+ {}; // => NaN
+ { valueOf: function () { return 0 } }; // => 0

  

2. 二元运算符

语法: AdditiveExpression + MultiplicativeExpression

2.1 解析步骤

首先看下ECMAScript 2015(ES6)关于加法运算符的说明:

AdditiveExpression : AdditiveExpression + MultiplicativeExpression

  1. Let lref be the result of evaluating AdditiveExpression.

  2. Let lval be GetValue(lref).

  3. ReturnIfAbrupt(lval).

  4. Let rref be the result of evaluating MultiplicativeExpression.

  5. Let rval be GetValue(rref).

  6. ReturnIfAbrupt(rval).

  7. Let lprim be ToPrimitive(lval).

  8. ReturnIfAbrupt(lprim).

  9. Let rprim be ToPrimitive(rval).

  10. ReturnIfAbrupt(rprim).

  11. If Type(lprim) is String or Type(rprim) is String, then

    1. Let lstr be ToString(lprim).

    2. ReturnIfAbrupt(lstr).

    3. Let rstr be ToString(rprim).

    4. ReturnIfAbrupt(rstr).

    5. Return the String that is the result of concatenating lstr and rstr.

  12. Let lnum be ToNumber(lprim).

  13. ReturnIfAbrupt(lnum).

  14. Let rnum be ToNumber(rprim).

  15. ReturnIfAbrupt(rnum).

  16. Return the result of applying the addition operation to lnum and rnum. See the Note below 12.7.5.

链接:http://www.ecma-international.org/ecma-262/6.0/#sec-addition-operator-plus

简单概括为下面4个步骤:

1) 值进行GetValue()操作。

2) 值进行ToPrimitive()操作,

3) 若一方为String类型,2个值都进行ToString()转换,最后进行字符串连接操作。

4) 若都不是String类型,2个值都进行ToNumber()转换,最后进行算数加法运算。

2.2 ToPrimitive(value)方法说明

在上面的步骤中,重点说明是其中的ToPrimitive()方法,除了在'+'号运算符用到此方法外,ToNumber()、ToString()等也都用到此方法。

2.2.1 方法签名

语法:ToPrimitive ( input [, PreferredType] )

参数:

①参 input :传入的值。

②参数 PreferredType :可选,需要被转换的类型。'+'加号作为一元运算符时,此值为“number”;而作为二元运算符时,未传递此值,以默认的“default”代替。

2.2.2 解析说明

ToPrimitive()的详细解析过程可以看这里:http://www.ecma-international.org/ecma-262/6.0/#sec-toprimitive

简化为以下步骤:

1) 若input类型为原始值(如:Undefined、Null、Boolean、Number、String、Symbol),直接返回input的本身。

2) 若input类型为object(如:Array、Object、Date),将根据第②个参数 PreferredType 的值进行以下操作:

就像之前讲的,'+'加号作为一元运算符时, 传递参数 PreferredType 的值为“number”;而作为二元运算符时,未传递此值时以默认的“default”代替。

在上面的图中,只看到 PreferredType 的值为“number” 或 “string” 时才进行解析,那么默认的“default”表示什么呢?

重点来了:Date类型内部重写了@@toPrimitive()方法,将“default”设置为“string”,而其他内置的对象都将“default”设置为“number”。

Date.prototype[@@toPrimitive]:http://www.ecma-international.org/ecma-262/6.0/#sec-date.prototype-@@toprimitive

2.3 示例

1) String + String

说明:进行字符串连接操作

'a' + 'b'; // => 'ab'
'1' + '2'; // => '12'

2) Number + Number

说明:进行算数的加法操作

1 + 2; // => 3

3) Number + String or String + Number

说明:Number类型的值先进行ToString()转换,随后再与另一个String类型的值进行拼接操作

1 + '0'; // => '10'
1 + '0a'; // => '10a'
'1' + 2; // => 12

4) Array + String or Array + Number

说明:Array类型进行ToPrimitive()转换时,先执行valueOf(),因其返回一个object类型的值,所以又执行了toString()方法。

var tmpList = ['a', 'b', 'c'];
tmpList.valueOf(); // => ["a", "b", "c"] 输出自身
tmpList.toString(); // a,b,c // 1.Array + String
tmpList + 'd'; // => a,b,cd // 2.重写Array的valueOf()方法,使其返回一个非object
Array.prototype.valueOf = function (e) {
return this.join('-');
}
tmpList + 'd'; // => a-b-cd

  

5) Date + String or Date + Number

说明:上面已经讲过,Date类型重写了ToPrimitive(),所以先调用toString(),若返回值为object,再调用valueOf()。

var dt = new Date();
dt.valueOf(); // => 1503501745901
dt.toString(); // Wed Aug 23 2017 23:22:25 GMT+0800 (中国标准时间) // 1.Date + String : dt直接使用了dt.toString()方法
dt + 'd'; // => Wed Aug 23 2017 23:22:25 GMT+0800 (中国标准时间)d // 2.重写Date的toString()方法,使其返回一个object的值
Date.prototype.toString = function (e) {
return { year: this.getFullYear() };
}
// 略过了 dt.toString(),调用了 dt.valueOf()
dt + 'd'; // => 1503501745901d
End
菜单加载中...

JavaScript 加号运算符详解的更多相关文章

  1. JS中的加号+运算符详解

    加号+运算符 在 JavaScript 中,加法的规则其实很简单,只有两种情况: 把数字和数字相加 把字符串和字符串相加 所有其他类型的值都会被自动转换成这两种类型的值. 为了能够弄明白这种隐式转换是 ...

  2. javascript算术运算符详解

    算术运算符 +.-.*./.%.++.-- ++.--分为前缀形式和后缀形式 前缀形式先加减1在执行 后缀形式先执行再加减1 注意 +号用来连接两个字符串 只要+连接的操作数中有一个是字符串型,JS就 ...

  3. 从mixin到new和prototype:Javascript原型机制详解

    从mixin到new和prototype:Javascript原型机制详解   这是一篇markdown格式的文章,更好的阅读体验请访问我的github,移动端请访问我的博客 继承是为了实现方法的复用 ...

  4. JavaScript严格模式详解

    转载自阮一峰的博客 Javascript 严格模式详解   作者: 阮一峰 一.概述 除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict m ...

  5. [转]javascript console 函数详解 js开发调试的利器

    javascript console 函数详解 js开发调试的利器   分步阅读 Console 是用于显示 JS和 DOM 对象信息的单独窗口.并且向 JS 中注入1个 console 对象,使用该 ...

  6. javascript 节点属性详解

    javascript 节点属性详解 根据 DOM,html 文档中的每个成分都是一个节点 DOM 是这样规定的:整个文档是一个文档节点每个 html 标签是一个元素节点包含在于 html 元素中的文本 ...

  7. (" use strict")Javascript 严格模式详解

    Javascript 严格模式详解 转载别人的博客内容,浏览了一遍,没有全部吸收,先保存一下链接 http://www.ruanyifeng.com/blog/2013/01/javascript_s ...

  8. 【HANA系列】SAP HANA XS使用JavaScript数据交互详解

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA XS使用Jav ...

  9. JavaScript运行机制详解

    JavaScript运行机制详解   var test = function(){ alert("test"); } var test2 = function(){ alert(& ...

随机推荐

  1. iconfont字体图标的使用方法--超简单!

    我之前因为项目用bootstrap比较多,所以使用font awesome字体图标比较多,后来接触到了iconfont,发现想要的什么图标都有,还可以自定义图标,非常强大!之前看了一波教程,觉得繁琐, ...

  2. 浅谈web服务器的编写之http协议

    本书是介绍怎么编写一个Web服务器,而Web服务器是基于HTTP(HyperText Transfer Protocol)协议实现的,所以要实现一个Web服务器就必须了解HTTP协议,本章主要介绍HT ...

  3. redhat设置开机自动连接网络

    一.设置开机自动连接网络1.用root账号登录2.打开etcsysconfignetwork-scrpts目录3.vi ifcfg-eth04.将ONBOOT改为yes 二.没有图形界面如何连接网络1 ...

  4. bzoj2002: [Hnoi2010]Bounce 弹飞绵羊 [分块][LCT]

    Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...

  5. 机器学习 —— 基础整理(四)特征提取之线性方法:主成分分析PCA、独立成分分析ICA、线性判别分析LDA

    本文简单整理了以下内容: (一)维数灾难 (二)特征提取--线性方法 1. 主成分分析PCA 2. 独立成分分析ICA 3. 线性判别分析LDA (一)维数灾难(Curse of dimensiona ...

  6. java调用wkhtmltopdf生成pdf文件,美观,省事

    最近项目需要导出企业风险报告,文件格式为pdf,于是搜了一大批文章都是什么Jasper Report,iText ,flying sauser ,都尝试了一遍,感觉不是我想要的效果, 需要自己调整好多 ...

  7. WMware虚拟机NAT模式配置网络设置Linux虚拟机固定IP

    一.主机配置 1.查看本机ip 2.给vmnet8设置固定IP和网段 3.根据vmnet8网段设置VMware NAT模式网段 4.点击NAT设置网关 二.启动虚拟机 网络设置如下: 这个地址值在这个 ...

  8. Ztree _ 横向显示子节点、点击文字勾选、去除指定元素input的勾选状态

    前些天项目需要树结构表现数据,需求ztree就能满足所以直接使用ztree只是踩了些小坑... 1.ztree子节点横向显示(下图): 效果说明:第三级子节点按需求横向显示其他竖向显示,每行最多显示5 ...

  9. 【原创】09. easyui-tabs 配合 iframe 使用,请求两次等问题

    描述 需要把已经做好的几个设备管理页面.转为子菜单管理:直接使用 easyui-tabs 配合 iframe 是最省时省力的. 存在问题 当点击 "设备管理" 会出现子页面多次加载 ...

  10. Linux基本命令整理_sheng

    Linux版本 Linux系统是一个多用户.多任务的分时操作系统. Linux版本分为内核版本和发行版本. 常见的Linux发行版有: RedHat(分为用于企业的Red Hat Enterprise ...