javascript —— 运算符

算术运算符

javascript中的算术操纵重要经由历程算术运算符来完成,算术运算符包括一元算术运算符和二元算术运算符两种。

一元算术运算符

一元算术运算符用于一个零丁的操纵数,并发生一个新值。在javascript中,一元运算符具有很高的优先级,而且都是右连系(right-associative)

一元算术运算符包括一元加法(+)、一元减法(-)、递增(++)和递减(–)

一元加(+)

一元加运算符以一个加号(+)示意,放在数值前面,对数值不会发生任何影响

var num = 25;
num = +num; //25

在对非数值运用一元加运算符时,会挪用Number()转型函数对这个值举行转换

var s1 = '01';
var s2 = '1.1';
var s3 = 'z';
var b = false;
var f = 1.1;
var o = {
    valueOf:function(){
        return -1;
    }
};

s1 = +s1;//1
s2 = +s2;//1.1
s3 = +s3;//NaN
b = +b;//0
f = +f;//1.1
o = +o;//-1

在new Date()前面运用一元加标记,可以把日期字符串,转换为日期毫秒数

console.log(new Date());//on Jul 11 2016 20:25:54 GMT+0800 (中国标准时候)
console.log(+new Date());//1468239954076

一元减(-)

一元减运算符重要用于示意负数

var num = 25;
num = -num;//-25

当一元减运算符用于非数值时,会对该值运用Number()转型函数举行转换,再将获得的数值转换成负数

var s1 = '01';
var s2 = '1.1';
var s3 = 'z';
var b = false;
var f = 1.1;
var o = {
    valueOf:function(){
        return -1;
    }
};

s1 = -s1;//-1
s2 = -s2;//-1.1
s3 = -s3;//NaN
b = -b;//0
f = -f;//-1.1
o = -o;//1

一元加和一元减运算符重要用于基础的算术运算,也可以用于转换数据范例

递增(++)

递增++运算符对其操纵数举行增量(加1)操纵,操纵数是一个左值(lvalue)(变量、数组元素或对象属性)。运算符经由历程Number()转型函数将操纵数转换为数字,然后给数字加1,并将加1后的数值从新赋值给变量、数字元素或许对象属性

var age = 29;
++age;
//相当于
var age = 29;
age = age +1;

递增++运算符的返回值依赖于它相关于操纵数的位置。当运算符在操纵数之前,称为前增量(pre-increment)运算符,它对操纵数举行增量盘算,并返回盘算后的值。当运算符在操纵数以后,称为后增量(post-increment)运算符,它对操纵数举行增量盘算,但返回未做增量盘算的(unincremented)值

var i = 1, j = ++i;
//i=2 j=2

var i = 1, j = i++;
//i=2 j=1

递减(–)

递减–运算符的操纵数也是一个左值,它经由历程Number()转型函数把操纵数转换为数字,然后减1,并将盘算后的值从新赋值给操纵数

和递增++运算符一样,递减–运算符的返回值依赖于它相对操纵数的位置,当递减运算符在操纵数之前,操纵数减1并返回减1以后的值。当递减运算符在操纵数以后,操纵数减1并返回减1之前的值

var age = 29;
--age;
//相当于
var age = 29;
age = age - 1;

前增量操纵符与实行语句优先级雷同,全部语句会从左向右求值

var num1 = 2;
var num2 = 20;
var num3 = --num1 + num2;//21
var num4 = num1 + num2;//21

后增量操纵符在包括它们的语句被求值以后才实行

var num1 = 2;
var num2 = 20;
var num3 = num1-- + num2;//22
var num4 = num1 + num2;//21

二元算术运算符

二元算术运算符包括加法(+)、减法(-)、乘法(*)、除法(/)和求余(%)

加法(+)

在多半程序设计语言中,加法一般是简朴的数字运算符,但在ECMAScript中,加法运算有大批的特别行动,不仅可以举行数值加法运算,也可以举行字符串衔接

【1】假如个中一个操纵数是对象,则对象会转换为原始值:日期对象经由历程toString()要领实行转换,其他对象经由历程valueOf()要领实行转换。由于多半对象valueOf()要领没法返回一个原始值,因而会经由历程toString()要领来实行转换

[注重]除了单数值数组会转换为数字外,其他原生对象都邑经由历程toString()要领转换为字符串情势

【2】在举行了对象到原始值的转换后,假如个中一个操纵数是字符串的话,另一个操纵数也会转换成字符串,举行字符串衔接,不然,两个操纵数都将转换成数字或NaN,举行加法操纵

//单数值数组和valueOf()返回值为数值的自定义对象会转换为数值
console.log(1 + []);//1
var o = {
    valueOf: function(){
        return -1;
    }
}
console.log(1 + o);//0
//其他原生对象则转换为字符串
console.log(1 + {});//'1[object Object]'
console.log(1 + [1,2]);//'11,2'
console.log(1 + new Date());//'1Thu Jun 16 2016 10:27:13 GMT+0800 (中国标准时候)'
console.log(1 + /0/);//'1/0/'

假如举行算术加法运算,undefined转换为NaN,null转换为0,false转换为0,true转换为1

console.log('' + undefined);//'undefined'
console.log('' + null);//'null'
console.log('' + false);//'false'
console.log('' + true);//'true'

因而,应用加号运算符的特征,可以应用”+恣意范例值转换为字符串

减法(-)

相关于加法,减法就简朴的多,只涉及到数字的减法运算。运用Number()转型函数将非数值范例转换为数值或NaN

console.log(1 - {});//NaN
console.log(1 - [1,2]);//NaN
console.log(1 - /0/);//NaN
console.log(1 - []);//1

加法有一个特别的地方,在于时候Date对象举行加法运算时运用toString()转换为字符串,而在其他数学运算,包括减法、乘法、除法、求余等运算中,都是运用Number()转换函数将时候Date对象运用valueOf()转换为数字

console.log(new Date() + 1);//'Thu Jun 16 2016 11:11:49 GMT+0800 (中国标准时候)1'
console.log(new Date() - 1);//1466046941641

undefined转换为NaN,null转换为0,false转换为0,true转换为1

console.log(1 - undefined);//NaN
console.log(1 - null);//1
console.log(1 - false);//1
console.log(1 - true);//0

乘法(*)

乘法操纵符由一个星号(*)示意,用于盘算两个数值的乘积,会经由历程Number()转型函数将非数值范例转换为数值或NaN

+ Infinity * 0;//NaN
- Infinity * 0;//NaN
Infinity * 非0数值;//Infinity或-Infinity
Infinity * Infinity;//Infinity

除法(/)

除法操纵符由一个斜线(/)示意,实行第一个操纵数除以第二个操纵数的运算,也会经由历程Number()转型函数将非数值范例转换为数值或NaN

Infinity / Infinity;//NaN
0 / 0;//NaN
非0数值 / 0;//Infinity或-Infinity
Infinity / 0;//Infinity
Infinity / 非0数值;//Infinity

求模(%)

求模(余数)操纵符是由一个百分号(%)示意,是第一个操纵数除以第二个操纵数的余数

//r是余数,n是被除数,d是除数,
//q是整数,在n/d为负时为负,在n/d为正时为正,它应该在不凌驾n和d的商的前提下尽量大
r = n - (d * q)

求模结果与第一个操纵数的标记保持一致

console.log(5 % 2);//1
console.log(5 % -2);//1
console.log(-5 % 2);//-1
console.log(-5 % -2);//-1

关联运算符

关联运算符用于测试两个值之间的关联,依据关联是不是存在而返回true或false,关联表达式老是返回一个布尔值,一般在if、while或for语句中运用关联表达式,用以控制程序的实行流程

javascript供应了===、!==、==、!=、<、<=、>、>=8个关联运算符,分为4类引见关联运算符

恒等运算符

恒等运算符’===’,也叫严厉相称运算符,起首盘算其操纵数的值,然后比较这两个值,比较历程没有任何范例转换,比较历程以下:

【1】假如两个值的范例不雷同,则返回false

console.log(1 === '1');//false
console.log(1 === [1]);//false

【2】假如两个值都是Undefined、Null、Boolean、Number、String雷同原始范例的值,值雷同,就返回true,不然,返回false

console.log(undefined === undefined);//true
console.log(null === null);//true
console.log(true === true);//true
console.log(false === false);//true
console.log(1 === 1);//true
console.log(2.5 === 2.5);//true

[注重]不论什么进制的数字,在举行关联比较时,终究都转换为十进制举行运算

console.log(10 === 0xa);//true

在数字Number范例中,有一个值比较特别,是NaN(not a number),它与任何值都不相称;另外,数字Number范例中存在着+0和-0,虽然其标记差别,但值相称

console.log(NaN === NaN);//false
console.log(+0 === -0);//true

两个雷同字符串值表现为:雷同的长度和雷同的字符对应雷同的位置

console.log('abc' === 'abc');//true
console.log('abc' === 'acb');//false

【3】假如两个值援用统一个对象,则返回true,不然,返回false

[注重]更细致的诠释是,javascript对象的比较是援用的比较,而不是值的比较。对象和其自身是相称的,但和其他任何对象都不相称。假如两个差别的对象具有雷同数目的属性,雷同的属性名和值,它们依然是不相称的

console.log([] === []);//false
console.log({} === {});//false    
console.log(function(){} === function(){});//false
var a = {};
b = a;
console.log(a === b);//true

恒不等运算符(!==)又叫严厉不即是运算符,操纵数的比较历程与恒等运算符雷同,结果取反。假如’===’的比较结果是true,则’!==’的比较结果是false;假如’===’的比较结果是false,则’!==’的比较结果是true

console.log(1 !== '1');//true
console.log(1 !== 1);//false
console.log(true !== false);//true
console.log({} !== {});//true

相称运算符

相称运算符’==’和恒等运算符相似,但相称运算符的比较并不严厉,假如两个操纵数不是统一范例,相称运算符会尝试举行一些范例转换,然后再举行比较

当两个操纵数范例雷同时,比较划定规矩和恒等运算符划定规矩雷同

console.log(undefined == undefined);//true
console.log(10 == 0xa);//true
console.log(NaN == NaN);//false
console.log([] == []);//false

当两个操纵数范例差别时,相称运算符’==’会恪守以下划定规矩:

【1】假如一个值是对象范例,另一值是原始范例,则对象范例会先运用valueOf()转换成原始值,假如结果还不是原始值,则再运用toString()要领转换,再举行比较

[注重]日期类只许可运用toString()要领转换为字符串。相似地,时候Date对象举行加法运算时运用toString()转换为字符串,而在其他数学运算,包括减法、乘法、除法、求余等运算中,都是运用Number()转换函数将时候Date对象运用valueOf()转换为数字

【2】在对象转换为原始值以后,假如两个操纵数都是字符串,则举行字符串的比较

console.log(new Date() == 'Sat Jun 25 2016 11:07:20 GMT+0800 (中国标准时候)');//true

【3】在对象转换为原始值以后,假如至少有一个操纵数不是字符串,则两个操纵数都将经由历程Number()转型函数转换成数字举行数值比较

console.log(true == 1);//true
console.log(true == 0);//false
console.log(false == '1');//false
console.log(false == '0');//true
console.log(true == 'true');//false,相当于1 == NaN

console.log([1] == 1);//true,相当于1 == 1
console.log([1] == '1');//true,相当于'1' == '1'
console.log([] == 0);//true,相当于0 == 0
console.log([] == '0');//false,相当于'' == '0'

console.log([] == true);//false,相当于0 == 1
console.log([1] == true);//true,相当于1 == 1
var a = {
    valueOf:function(){
        return 1;
    },
    toString:function(){
        return '2';
    }
} 
console.log( a == '1');//true,相当于1 == 1

var a = {
    valueOf:function(){
        return {};
    },
    toString:function(){
        return '1';
    }
} 
console.log( a == 1);//true,相当于1 == 1

[注重]假如一个值是null,另一个值是undefined,则返回true。虽然Number(null)是0,但null和0并不相称

console.log(null == undefined);//true
console.log(null == 0);//false

[注重]空字符串或空格字符串会转成0

console.log(null == []);//false
console.log(null == '');//false
console.log([] == ' ');//false,相当于'' == ' '
console.log([] == '');//true,相当于'' == ''
console.log(0 == '');//true

不相称运算符(!=)的操纵数比较历程与相称运算符雷同,结果取反。假如’==’的比较结果是true,则’!=’的比较结果是false;假如’==’的比较结果是false,则’!=’的比较结果是true

console.log(1 != '1');//false,相当于1 != 1
console.log(true != '1');//false,相当于1 != 1
console.log('true' != 1);//true,相当于NaN != 1
console.log([1] != '1');//false,相当于'1' != '1'
console.log([1] != true);//false,相当于1 != 1

大于运算符

大于运算符(>)用于比较两个操纵数,假如第一个操纵数大于第二个操纵数,则大于运算符的盘算结果为true,不然为false

大于运算符的操纵数多是恣意范例,但是,只要数字和字符串才真正实行比较操纵,因而那些不是数字和字符串的操纵数都将举行范例转换,范例转换划定规矩以下:

【1】假如操纵数是对象,则这个对象将先运用valueOf()转换成原始值,假如结果还不是原始值,则再运用toString()要领转换

[注重]实际上,在原生对象中,运用valueOf()要领转换为原始值的,只要转换为数字Number范例的时候Date对象,其他对象都经由历程toString()要领转换为字符串

【2】在对象转换为原始值以后,假如两个操纵数都是字符串,则根据字母表的递次对两个字符串举行比较,这里提到的字母表递次是指构成这个字符串的16位unicode字符的索引递次

console.log('b' > 'a');//true
console.log('B' > 'a');//false

console.log({} > '[a]');//true,相当于'[object Object]' > '[a]'
console.log({} > '[p]');//false,相当于'[object Object]' > '[p]'

console.log(['a'] > ['b']);//false,相当于'a' > 'b'
console.log([2] > [11]);//true,相当于'2' > '11'

【3】在对象转换为原始值以后,假如至少有一个操纵数不是字符串,则两个操纵数都转换成数字举行比较

[注重]在即是操纵符中,时候Date()对象只许可经由历程toString()要领转换为字符串,而不许可经由历程valueOf()要领转换为数字;而在大于操纵符中,时候Date()对象许可优先运用valueOf()要领转换为数字

console.log(new Date() > 100);//true,相当于1466826928667 > 100
console.log(true > [0]);//true,相当于 1 > 0

console.log(2 > 1);//true
console.log(11 > '2');//true,相当于11 > 2

console.log(NaN > 1);//false
console.log(1 > NaN);//false
console.log({} > true);//false,相当于 NaN > 1

关于数字和字符串来讲,加号运算符和比较运算符的行动有所差别,加号运算符更偏幸字符串,假如它的一个操纵数是字符串,就举行字符串衔接。而比较运算符则更偏幸数字,只要在两个操纵数都是字符串时,才举行字符串的比较

console.log(1 + 2);//3
console.log('1' + '2');//'12'
console.log('1' + 2);//'12',相当于 '1' + '2'

console.log(2 > 1);//true
console.log('2' > '1');//true
console.log('2' > 1);//true,相当于 2 > 1

小于即是运算符(<=)并不依赖于小于或即是运算符的比较划定规矩,而是遵照大于运算符的比较划定规矩,结果取反。假如’>’的比较结果是true,则'<=’的比较结果是false;假如’>’的比较结果是false,则'<=’的比较结果是true

console.log(1 <= '0');//false,相当于1 <= 0
console.log(true <= '0');//false,相当于1 <= 0
console.log('true' <= 0);//false,相当于NaN <= 0
console.log([1] <= '0');//false,相当于'1' <= '0'
console.log([0] <= true);//true,相当于0 <= 1
console.log(1 <= 1);//true

小于运算符

小于运算符(<)用于比较两个操纵数,假如第一个操纵数小于第二个操纵数,则小于运算符的盘算结果为true,不然为false

小于运算符与大于运算符的范例转换划定规矩相似,就不再赘述

一样地,大于即是运算符(>=)并不依赖于大于或即是运算符的比较划定规矩,而是遵照小于运算符的比较划定规矩,结果取反。假如'<‘的比较结果是true,则’>=’的结果是false;假如'<‘的比较结果是false,则’>=’的结果是true

逻辑运算符

逻辑运算符对操纵数举行布尔运算,常常和关联运算符一样合营运用。逻辑运算符将多个关联表达式组合起来构成一个更庞杂的表达式。逻辑运算符分为逻辑非’!’、逻辑与’&&’、逻辑或’||’3种。

逻辑非

逻辑非操纵符由一个叹号(!)示意,可以运用于ECMAScript中的任何值。不管这个值是什么数据范例,这个操纵符都邑返回一个布尔值。逻辑非操纵符起首会将它的操纵数转换成一个布尔值,然后再对其求反

逻辑非对操纵数转为布尔范例的转换范例与Boolean()转型函数雷同,只不过末了再将其结果取反。而假如同时运用两个逻辑非操纵符,实际上就会模仿Boolean()转型函数的行动

console.log(!!undefined);//false
console.log(!!null);//false
console.log(!!0);//false
console.log(!!-0);//false
console.log(!!NaN);//false
console.log(!!'');//false
console.log(!!false);//false

console.log(!!{});//true
console.log(!![]);//true

console.log(!!new Boolean(false));//true
console.log(!!false);//false
console.log(!!new Boolean(null));//true
console.log(!!null);//false

逻辑与

逻辑与运算符由两个和号(&&)示意,有两个操纵数,只要在两个操纵数都为true时,结果才返回true,不然返回false

//逻辑与(&&)的真值表
第一个操纵数        第二个操纵数        结果
true              true               true
true              false              false
false             true               false
false             false              false

逻辑与操纵可以运用于任何范例的操纵数,而不仅仅是布尔值。假如个中一个操纵数不是布尔值,则逻辑与操纵不一定返回布尔值

逻辑与操纵属于短路操纵,假如第一个操纵数可以决议结果,那末就不会再对第二个操纵数求值

关于逻辑与而言:
假如第一个操纵数是false,则不管第二个操纵数是什么值,结果都是false,则返回第一个操纵数;
假如第一个操纵数为true,则结果的真假和第二个操纵数的真假雷同,则返回第二个操纵数

//除了false、undefined、null、+0、-0、NaN、''这7个假值,其他都是真值

console.log('t' && ''); //由于't'是真值,所以返回''
console.log('t' && 'f'); //由于't'是真值,所以返回'f'
console.log('t' && 1 + 2); //由于't'是真值,所以返回3
console.log('' && 'f'); //由于''是假值,所以返回''
console.log('' && ''); //由于''是假值,所以返回''
var i = 1;
var result = (true && i++);
console.log(result,i);//由于true是真值,所以实行i++,i是2,result是1

var i = 1;
var result = (false && i++);
console.log(result,i);//由于false是假值,所以不实行i++,i是1,result是false

逻辑与运算符可以多个连用,返回第一个布尔值为false的表达式的值

console.log(true && 'foo' && '' && 4 && 'foo' && true);// ''

逻辑或

逻辑或运算符由两个竖线(||)示意,有两个操纵数,只要在两个操纵数都是false时,结果才返回false,不然返回true

//逻辑或(||)的真值表
第一个操纵数        第二个操纵数        结果
true              true              true
true              false             true
false             true              true
false             false             false

一样地,逻辑或操纵也可以运用于任何范例的操纵数,而不仅仅是布尔值。假如个中一个操纵数不是布尔值,则逻辑或操纵不一定返回布尔值

逻辑或操纵也属于短路操纵,假如第一个操纵数可以决议结果,那末就不会再对第二个操纵数求值

关于逻辑或而言:
假如第一个操纵数是true,则不管第二个操纵数是什么值,结果都是true,则返回第一个操纵数;
假如第一个操纵数是false,则结果的真假和第二个操纵数的真假雷同,则返回第二个操纵数

console.log('t' || '');//由于't'是真值,所以返回"t"
console.log('t' || 'f');//由于't'是真值,所以返回"t"
console.log('' || 'f');//由于''是假值,所以返回"f"
console.log('' || '');//由于''是假值,所以返回""
var i = 1;
var result = (true || i++);
console.log(result,i);//由于true是真值,所以不实行i++,result是true,i是1

var i = 1;
var result = (false || i++);
console.log(result,i);//由于false是假值,所以实行i++,i是2,result是1

一样地,逻辑或运算符也可以多个连用,返回第一个布尔值为true的表达式的值

console.log(false || 0 || '' || 4 || 'foo' || true);// 4

前提运算符

前提运算符是javascript中唯一的一个三元运算符(三个操纵数),偶然直接称做三元运算符。一般这个运算符写成?:,当然在代码中每每不会这么简写,由于这个运算符具有三个操纵数,第一个操纵数在?之前,第二个操纵数在?和:之间,第三个操纵数在:以后

variable = boolean_expression ? true_value : false_value;

本质上,这就是基于对boolean_expression求值的结果,决议给变量variable赋什么值。假如求值结果是true,则给变量variable赋值true_value;假如求值结果是false,则给变量variable赋值false_value

前提运算符的操纵数可所以恣意范例,第一个操纵数当做布尔值,假如它是真值,那末将盘算第二个操纵数,并返回其盘算结果。不然,假如第一个操纵数是假值,那末将盘算第三个操纵数,并返回其盘算结果。第二个和第三个操纵数老是会盘算个中之一,不可能二者同时实行

实在运用if语句也会带来一样的结果,’?:’运算符只是供应了一种简写情势。下面是一个’?:’的典范运用场景,推断一个变量是不是有定义(并具有一个有意义的真值),假如有定义则运用它,假如无定义则运用一个默认值:

greeting = 'hello ' + (username ? username : 'there');

圆括号运算符

圆括号运算符也叫分组运算符,它有两种用法:假如表达式放在圆括号中,作用是求值;假如跟在函数背面,作用是挪用函数

把表达式放在圆括号当中,将返回表达式的值

console.log((1));  //1
console.log(('a')); //'a'
console.log((1+2)); // 3

把对象放在圆括号当中,则会返回对象的值,即对象自身

var o = {p:1};
console.log((o));// Object {p: 1}

将函数放在圆括号中,会返回函数自身。假如圆括号紧跟在函数的背面,就示意挪用函数,即对函数求值

function f(){return 1;}
console.log((f));// function f(){return 1;}
console.log(f()); // 1

[注重]圆括号运算符不能为空,不然会报错

    原文作者:whyneedname
    原文地址: https://segmentfault.com/a/1190000015651284
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞