javascript的运算符
JavaScript有十种算术运算符: 加(+),减(-),乘(*),除(/),指数(**),余数(%),自增(++),自减(--),数值(+单个变量),负数值(-单个变量)
加法运算符
加法运算符(+)有两种(运行时决定):一是执行相加,二是执行连接
运算子的不同导致了不同的语法行为,这种现象称为“重载”
除了加法运算符,其他的算术运算符(比如减法,乘法,除法)都不会发生重载,它们的运算规则是: 所有的运算子一律转为数值,然后再进行相应的数学运算
如果加号两边的运算子都不是字符串,比如(true+true),执行的是相加; 如果加号两边的运算子有任意一个是字符串,执行的是连接
// 输出2 将true转换为数字执行相加
console.log(true+true);
// 输出21 执行连接
console.log(2+'1');
如果运算子是对象,必须先转成原始类型的值,然后再相加。
// 定义一个对象obj,obj有个属性p,属性值为1
var obj = { p:1 };
// 输出 [object Object]2
console.log(obj+2);
对象相加的运算规则是:
- 首先调用对象的valueOf()
- 如果valueOf()方法返回的是基本数据类型,则直接与另一个运算子相加;
- 如果valueOf()方法返回的是引用数据类型,则调用对象的toString(),然后与另一个运算子相加
- 特例: 如果运算子是Date对象的实例,那么会优先执行toString()方法
// 例子1
// 定义一个对象
var obj = { x:2 };
// 输出 [object Object]3
console.log(obj+3);
console.log('-----------------');
// 例子2 对象的valueOf()方法返回对象
// 根据对象相加的运算规则自定义valueOf()和toString()
var obj1 = {
x:2,
toString: function(){
console.log('toStirng方法被调用了');
return 'hello';
},
valueOf: function(){
console.log('valueOf方法被调用了');
// 这里valueOf()返回一个对象,所以会继续调用toString方法
return {};
}
}
// 输出 valueOf方法被调用了
// 输出 toStirng方法被调用了
// 输出 hello4
console.log(obj1 + 4);
console.log('-----------------');
// 例子3 对象的valueOf()返回基本数据类型
// 对象的valueOf() 返回基本数据类型
var obj2 = {
x:2,
toString: function(){
console.log('toString方法被调用了');
return 'toString';
},
valueOf: function(){
console.log('valueOf方法被调用了');
// 这里valueOf方法返回一个基本数据类型,所以相加过程中不会再调用toString 方法了
return '3';
}
}
// 输出 valueOf方法被调用了
// 因为有个运算子是字符串,所以执行的是相加,输出35
console.log(obj2 + 5);
console.log('-----------------');
// 例子4 如果对象是Date对象的类型,并且toString方法返回基本数据类型
var obj3 = new Date();
obj3.valueOf = function(){
console.log('valueOf方法被调用了');
return 1;
};
obj3.toString = function(){
console.log('toString方法被调用了');
return 'hello'
};
// 输出 toString方法被调用了
// 输出 hello3
console.log(obj3 + 3);
console.log('-----------------');
// 例子4 对象是Date对象的实例,并且toString返回的是引用数据类型
var obj4 = new Date();
obj4.valueOf = function(){
console.log('valueOf方法被调用了');
return 1;
}
obj4.toString = function(){
console.log('toString方法被调用了');
return {};
}
// 输出 toString方法被调用了
// 输出 valueOf方法被调用了
// 输出 6
console.log(obj4 + 5);
// 例子3和例子4中,对象是一个Date对象的实例,并且自定义了valueOf方法和toString方法,结果toString方法优先执行了
余数运算符 %
余数运算符%返回前一个运算子被后一个运算子除所得的余数
- 运算结果的正负号由第一个运算子的正负号决定
- 得到负数的正确余数值,可以先使用绝对值函数
自增(++)和自减(--)运算符
自增和自减都是一元运算符,只需要一个运算子。
作用是将运算子首先转换为数值,然后加上1或减去1
注意点,自增和自减运算符,放在变量之后,会先返回变量操作前的值,再进行自增/自减操作;放在变量之前,会先进行自增/自减操作,再返回变量操作后的值
var a = 1;
// 2
console.log(++a);
var b = '1';
// 2
console.log(++b);
var c = 'a';
// NaN
console.log(++c);
自增和自减是仅有的两个具有副作用的运算符,因为这两个运算符会改变原始值
数值运算符 (+)
数值运算符同样是用+ ,但它是一元运算符(只需要一个操作数)
作用是可以将任何值转换为数值(与Number函数作用相同)
负数值运算符
负数值运算符(-),也同样具有将一个值转为数值的功能,只不过得到的值正负相反
数值运算符和负数值运算符都会返回一个新的值,而不会改变原始变量的值
指数运算符
指数运算符(**)完成指数运算,前一个运算子是底数,后一个运算子是指数
// 输出16
console.log(2**4);
赋值运算符(=)
赋值运算符用于给变量赋值
赋值运算符还可以与其他运算符结合,形成变体
这些复合的赋值运算符,都是先进行指定运算,然后将得到的值返回给左边的变量