最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

理解Javascript中的“+”运算符

来源:懂视网 责编:小采 时间:2020-11-27 20:23:07
文档

理解Javascript中的“+”运算符

理解Javascript中的+运算符:在网上或面试题中经常会看到一些奇怪的语句,比如{}+{} // "[object Object][object Object]" {}+[] // 0 []+{} // "[object Object]" []+[] // ""在Javascript中+运算符是个重载运
推荐度:
导读理解Javascript中的+运算符:在网上或面试题中经常会看到一些奇怪的语句,比如{}+{} // "[object Object][object Object]" {}+[] // 0 []+{} // "[object Object]" []+[] // ""在Javascript中+运算符是个重载运

在网上或面试题中经常会看到一些“奇怪”的语句,比如

{}+{}
// "[object Object][object Object]"

{}+[]
// 0

[]+{}
// "[object Object]"

[]+[]
// ""

在Javascript中+运算符是个重载运算符,可用来拼接字符串,以及把两个“数字”相加。至于是哪种情况要看运算符两边参数的类型。
在日常的开发中我们也不会碰到这么麻烦的事,但弄弄清楚总是好的。在规范 中巴拉巴拉地说了一堆,简单来说就是:

1. 对于原生类型,参数中只要有一方是字符串,则按字符串连接处理,否则按数字相加处理,不是数字的会先转成数字再相加。

原生类型有:undefined, null, boolean, number, string。

下面是一些示例:

0 + '1' // '01'
null + 1 // 1
true + 1 // 2
false + 1 // 0
undefined + 2 // NaN, 因为undefined转成Number是NaN

2. 对于引用类型,则需要先转换成原生类型,再按以上规则相加。如何转换在规范中有详细的说明,但规范看起来是有点费劲。 简单来说就是:默认情况下都转化成字符串,要搞特殊的话,请重写valueOf()方法。

来个例子:

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

但由于Js不支持真正的操作符重载,即不能相加得到自定义类型的对象, 所以以上示例在实践代码中非常少用。

不过目前的知识足够回答原先的问题了。但是慢着,{}+[] 为什么和 []+{}不一样? 这其实是个语法问题。前者相当于:

{}
+[]

其实是两个句子, [] 转换成数字是 0。很容易验证 ({}+[]) === '[object Object]'

+[] // 0

有人可能要问,那 new Date()valueOf() 不是转换成数字吗?为什么相加结果还是字符串类型呢?

new Date().valueOf();
// 1491904757087

1 + new Date();
// "1Tue Apr 11 2017 18:02:16 GMT+0800 (CST)"

这是Date类做了特殊处理, @@toPrimitive, 默认情况下对 Date 的相加以字符串方式连接,但比较时则会转换成数字。

new Date() < new Date('2018-01-01')
// true, 现在是2017

将引用类型转换成原生类型在很多操作符中都有用到,比如 <, >, 所以有必要对其研究一番, 以下js代码大概描述了其行为。

/**
 * @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();
}

详细的请参考规范

在网上或面试题中经常会看到一些“奇怪”的语句,比如

{}+{}
// "[object Object][object Object]"

{}+[]
// 0

[]+{}
// "[object Object]"

[]+[]
// ""

在Javascript中+运算符是个重载运算符,可用来拼接字符串,以及把两个“数字”相加。至于是哪种情况要看运算符两边参数的类型。
在日常的开发中我们也不会碰到这么麻烦的事,但弄弄清楚总是好的。在规范 中巴拉巴拉地说了一堆,简单来说就是:

1. 对于原生类型,参数中只要有一方是字符串,则按字符串连接处理,否则按数字相加处理,不是数字的会先转成数字再相加。

原生类型有:undefined, null, boolean, number, string。

下面是一些示例:

0 + '1' // '01'
null + 1 // 1
true + 1 // 2
false + 1 // 0
undefined + 2 // NaN, 因为undefined转成Number是NaN

2. 对于引用类型,则需要先转换成原生类型,再按以上规则相加。如何转换在规范中有详细的说明,但规范看起来是有点费劲。 简单来说就是:默认情况下都转化成字符串,要搞特殊的话,请重写valueOf()方法。

来个例子:

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

但由于Js不支持真正的操作符重载,即不能相加得到自定义类型的对象, 所以以上示例在实践代码中非常少用。

不过目前的知识足够回答原先的问题了。但是慢着,{}+[] 为什么和 []+{}不一样? 这其实是个语法问题。前者相当于:

{}
+[]

其实是两个句子, [] 转换成数字是 0。很容易验证 ({}+[]) === '[object Object]'

+[] // 0

有人可能要问,那 new Date()valueOf() 不是转换成数字吗?为什么相加结果还是字符串类型呢?

new Date().valueOf();
// 1491904757087

1 + new Date();
// "1Tue Apr 11 2017 18:02:16 GMT+0800 (CST)"

这是Date类做了特殊处理, @@toPrimitive, 默认情况下对 Date 的相加以字符串方式连接,但比较时则会转换成数字。

new Date() < new Date('2018-01-01')
// true, 现在是2017

将引用类型转换成原生类型在很多操作符中都有用到,比如 <, >, 所以有必要对其研究一番, 以下js代码大概描述了其行为。

/**
 * @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();
}

文档

理解Javascript中的“+”运算符

理解Javascript中的+运算符:在网上或面试题中经常会看到一些奇怪的语句,比如{}+{} // "[object Object][object Object]" {}+[] // 0 []+{} // "[object Object]" []+[] // ""在Javascript中+运算符是个重载运
推荐度:
标签: js 理解 javascript
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top