1、JS 中包含的运算符有:一元运算符、二元运算符、三元运算符、算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、其他的运算符等。
2、表达式:简单来讲就是一句代码(分号隔开),解释器会把它翻译成一个具体的值。
包含简单表达式(一个具体的字面量或者变量名)和复杂表达式(多个简单表达式组合而已)
3、一元运算符:++(--)自增和自减,+(-) 正负运算符
前自增(减)和后自增(减)的区别:单独增对某一个变量进行前导或者后导自增自减运算没有相应 的区别,但是如果将变量的自增自减再和其他运算符组成一个复杂的运算符就有区别了,前 自导是先对变量本身的值进行改变,然后再进行其他运算,后自导是先将变量和其他运算符 进行运算然后再改变变量自身的值比如:var box=101; var age=++box; alert(age); alert(box); age=box++; alert(age); alert(box);输出结果是 102,102,102,103,看 出两次都对box进行了自增运算,但是由于前导和后导的关系 age 的值是不一样的。
自增、自减运算符可以用于所有的类型: 运用时系统会进行隐试的转换成number类型,然后执行 自增或者自减操作,如果是对象同样是先调用valueOf方法然后再调用toString方法
+(-)运算符:和上面的自增自减一样 如果非number类型时,同样会有一个隐试的类型转换,然 后再进行取正负的操作
4、二元操作符:+、-、*、/、% 二元操作符和其他高级语言基本上没有多少区别
加法(+):注意可以用于字符串的连接,如果运算符的两边都是number类型数值 就做加法运算, 用于对象是同样是先调用valueOf方法然后再调用toString方法,然后和返回值进行操作; 如果有字符串涉及到运算时,是进行字符串的拼接,从左到右依次运算 alert("abcd"+23+12);//abcd2312 从左到右计算 先进行的是字符串的拼接 alert(23+12+'abc');//35abc 从左到右计算 先进行的是加法运算然后再进行字符串的拼接 Infinity+-Infinity);//NaN
减法(-):减法运算和加法运算一样的,只是在和字符串进行计算的时候是将字符串转换为NaN
乘法(*):运算时将空字符串转换成 0;其他的和加法一样
除法(/): alert(Infinity/Infinity);//NaN alert(45/'');//Infinity alert(45/null);//Infinity alert(34/'abc');//NaN alert(34/{});//NaN
求模(%):和上面同样的,只是当隐试转换后分母若为0,其结果为NaN
5、关系运算符:用于进行比较的运算符,除了同用的还包括全等(===)和不全等(!==)
关系运算符大多返回的是一个布尔类型值:true或者false;
null 和 undefined 一般会自动转换为0,但在比较运算上是不会进行自动转换的,而字符串在 进行比较的时候会自动转换
当操作数是非数值是应该遵循的一些规则: 1)、都是数值是进行数值比较 2)、两个操作数都是字符串时则比较对应的字符编码值
3)、两个操作数有一个是数值时就将另外一个操作数转换成数值 然后再进行数值比较 4)、两个操作数,一个是对象时,先调用valueOf()和toString()方法,然后再 进行结果比较,否则,如果这两个方法不存在(没有显示的写明返回值)的话,比较结果始终为false
在相等和不相等的比较上,如果操作数是非数值,遵循的一些规则: 1)、一个操作数是布尔值或者字符串,则比较之前先将其转换成数值,然后再进行数值比较
2)、一个操作数是对象的时候,先调用其中的方法,然后再和其中的返回值进行比较 3)、在不需要任何转换的情况下,undefined和null是相等的,但是全等则不是相等的 4)、只要其中一个操作数为 NaN,则返回的是false,并且 NaN和自身也不相等 5)、如果比较的两个操作数是对象,则比较的是他们的引用是否相等,即是否是同一个对象 6)、在全等和不全等的判断上,必须要值和类型都相等才返回 true,否则返回为false 7)、注,由于undefined和null在比较的时候不会自动转换成0,故和0不相等
6、逻辑运算符 : &&、||、!!,一般和关系运算符套用[考虑到隐试准换为Boolean类型就OK] 逻辑运算符不一定返回的是布尔值
逻辑与:只有两边都为true的时候才返回true, 1)、如果第一个操作数是对象,则返回第二个操作数的结果或者本身 alert({}&&5>4)//true alert({}&&5)//5
2)、如果第二个操作数为对象/null/undefined的时候,只有当第一个操作数为真的时候才返回对象/null/undefined,否则始终返回的是false
3)、因为逻辑与时短路操作,故只要第一个操作数为false,就不会执行第二个操作数
逻辑或: 如果两边进行比较的操作数不是布尔值的时候,应该遵循的一些规则:
1)、如果第一个操作数是对象的话,则返回第一个操作数(因为隐试转换使用为true)
2)、如果第一个操作数为false,则返回第二个操作数,[逻辑值/null/undefined/对象]等
3)、第一个操作数为null或者undefined的时候,返回第二个操作数[这两个隐试准换为false]
4)、逻辑或同样是短路操作,如果第一个操作数返回为true,就不执行第二个操作数
5)、第一个操作数是 NaN 的时候 返回 第二个操作数
注:可以用逻辑或来为避免为变量赋值为null或者undefined :var box=null||5;//box=5
逻辑非:逻辑非可以用于任何值的运算,无论什么数据类型,这个运算符都会返回一个布尔值, 具体流程是 先转换成布尔值,然后再取反;等价于 !Boolean(x);
规则: 1)、操作数是一个 对向 的时候,转换成布尔值为true,取反为false
2)、操作数是一个 空字符串 时候,转换成布尔值为false,取反为true
3)、操作数是一个 非空字符串 的时候,转换成布尔值为true,取反为false
4)、操作数是一个 非0数值 的时候,转换成布尔值为true,取反为false
5)、操作数是一个数值 0 的时候,转换成布尔值为false,取反为true
6)、操作数是一个 null/NaN/undefined 的时候,转换成布尔值为false,取反为true
使用一次逻辑运算符时,是相当于将操作数转换成布尔值后再取反,而使用两次逻辑非运算符 时,是相当于将取反后的布尔值再取反,相当于Boolean()转型函数。 一般的NaN/null/undefined/对向是不会自动转换成布尔值的,可以用Boolean()函数或者两个 逻辑非运算符,就可以将操作数手动的转换成布尔值了
7、位运算符:运行效率最高,也比较底层 按位非(~) 位与(&) 位或(|) 异或(^) 左移(<<) 右移(>>) 无符号右移(>>>)
8、赋值运算符 左边的值赋给右边的变量,赋值运算符可以和其他的运算符进行组合使用 +=
9、字符串运算符:加号 进行字符串的拼接
10、逗号运算符
(1)、多个变量的声明:var a=2,b=4,c=8;
(2)、变量声明,将最后一个值赋给变量 var box=(3,5,6,7);//box=5
(3)、数组的声明赋值 var box=[3,4,5,6,7];
(4)、对象的声明和赋值 var box={2:'e',4:'c',5:'t'};
11、三元运算符(条件运算符) 和C语言C#语言中的三元运算符是相同的。
12、运算符优先级: 括号是王道,或者是数组的下标访问优先权最高; 其次是一元运算符和取非运算符,然后是算术运算符,和字符串的拼接 然后是左右移运算符,关系运算符(先大小,后相等),位运算符(&,^,|, 逻辑运算符,三元运算符,最后是赋值运算符优先权最低
13、练习只中的代码 采用块注释查看
//alert("运算符练习");
/*
// 自增和自减运算符
//自增运算和其他运算组合使用的时候,变量本身前自导和后自导运算优先级是不一样的
//但是对变量本身来说运算的结果是一样的,只是组合表达式的值不一样
var box=100;
box++;//后导自增
alert(box);//101
++box;//前导自增
alert(box);//102
var age=box++;//先赋值后自增
alert(age);//102
alert(box);//103
age=++box;//先自增后赋值
alert(box);//104
alert(age)//104
// 自增自减运算符 是会改变变量的类型的 先将非number类型的数据转换为number类型数据
var age='88a';
alert(typeof age);
age++;
alert(age);//NaN
alert(typeof age);//number var age=true;
alert(typeof age);//boolean
age++;// boolean中的 true 转换成number后为1,然后自增为2
alert(age);//2
alert(typeof age);//number var box={
valueOf:function(){
return 23;
}
}
alert(typeof box);// object
alert(box++);//23 先输出然后再自增
alert(box);//24
alert(typeof box);// number // +、- 运算符 和上面的自增自减运算符一样 只是取正负的问题
//同样是先转换成number类型然后再操作 优先级一般比其他运算符高
var box=89;
alert(typeof box);//number
alert(+box);//89
var age=-23;
alert(-age);//23 对原来的变量进行了一个取反 var box='89';
alert(typeof +box);//number
alert(typeof box);//string
box++;
alert(box);//90
alert(typeof box);//number var box='abc';
alert(+box);//NaN 不能够转换成number类型的数值就返回的是NaN,NaN和进行任何运算还是NaN
alert(typeof box);//string
alert(typeof +box);//number var box=34;
alert(4+-box);//-30 alert(4+(-box))//对box先取反 然后再和4相加 */
/*----------- 二元运算符
//加法运算 当运算符两边没有字符串作为表达式时,会将其他的类型进行一个类型转换
//object类型也是根据其返回值进行计算 如果有字符串涉及到运算时 是进行字符串的拼接
var box=true;
alert(box+23);//24 var age='abc';
alert(age+23);//abc23 var h=null;
alert(h+23);//23 null 类型转换成number类型为0 var obc = {};
alert(obc+23);//[object Object]23 var box={toString:function(){return 3;}};
alert(box+34);//37 alert("abcd"+23+12);//abcd2312 从左到右计算 先进行的是字符串的拼接
alert(23+12+'abc');//35abc 从左到右计算 先进行的是加法运算然后再进行字符串的拼接 alert(Infinity+Infinity);//Infinity
alert(-Infinity+-Infinity);//-Infinity
alert(Infinity+-Infinity);//NaN
//减法和乘法在计算时和加法基本上是一样的 只是在和字符串进行计算时是转换成0/NaN
alert(34-'abc');//NaN
alert(34*'');//0 //除法
alert(Infinity/Infinity);//NaN
alert(45/'');//Infinity
alert(45/null);//Infinity
alert(34/'abc');//NaN
alert(34/{});//NaN //取余 同样是先进行隐试转换 不过对分母为0的数取模得到的是NaN
alert(Infinity%Infinity);//NaN
alert(-11%3);//-2
alert(23%'');//NaN
alert(23%null);//NaN
alert(23%true);//0 true转换为1
alert(23%{});//NaN
alert(23%'abc');//NaN
alert(23%-3);//2
alert(''%23);//0 */ /* 关系运算符
//当操作数是非数值是应该遵循的一些规则:
//1)、都是数值是进行数值比较 2)、两个操作数都是字符串时则比较对应的字符编码值
//3)、两个操作数有一个是数值时就将另外一个操作数转换成数值 然后再进行数值比较
//4)、两个操作数,一个是对象时,先调用valueOf()和toString()方法,然后再进行结果比较,否则,如果这两个方法不存在(没有显示的写明返回值)的话,比较结果始终为false alert('3'>'2');//true
alert('3'>22);//false 是将 '3' 转换成了数值来进行比较
alert('3'>'a');//比较的是ascii码
alert(3>'a');//false
alert(3>{});//false 如果对象没有toString或者valueOf方法 永远都是false
alert({}>'a');////false
alert('abc'>'abcd');//false
alert('ab'>'ac')//false alert('2'==2);//true '2'将会转换成数值 2
alert('2'===2);//false 进行全等比较的时候 不仅要比较大小 还要比较类型是否相等
alert(undefined==null);//true 就简单的值上面来说是相等的
alert(undefined===null);//false 类型不一样
alert(false==0);//true false会自动的转换成0
alert(2=={});//false 和一个对向基本上相比基本上是false 除非其中的两个方法有返回值比较
alert(2==NaN);//false NaN和任何对象相比都是false的
alert({}=={});//false 两个对象相同的时候 除非他们的引用相同
alert(NaN==NaN);//false
var box={};
var he=box;
alert(box==he);//true 因为他们的引用是内存中同一块内存
alert(box===he); */ /* 逻辑运算符 返回的不一定是布尔值 有可能是操作数
//第一个操作数为对象的时候 返回第二个操作数
alert({}&&5>4);//true
alert({}&&5);//5
//第二个操作数为对象的时候,如果第一个操作数是true,就返回第二个操作数,否则为false
alert(5>4&&{});// object Object
alert(5<4&&{});// false
alert(5>4&&{toString:function(){return 'a';}});//a
//在逻辑与时 如果第一个操作数为false 就不会执行第二个操作数,哪怕第二个操作数会报异常
//可以得出 在第一个操作数为true的时候 第二个操作数如果是null或者undefined就
//返回null或者undefined,否则返回false
alert(5>4&&null);//null
alert(5<4&&null);//false
alert(4>3&&undefined);//undefined
alert(5>6&&undefined);//false
alert(4&&5);//视为两个都是对象 //逻辑或
//1)、如果第一个操作数是对象的话,则返回第一个操作数(因为隐试转换使用为true)
//2)、如果第一个操作数为false,则返回第二个操作数,[逻辑值/null/undefined/对象]等
//3)、第一个操作数为null或者undefined的时候,返回第二个操作数[这两个隐试准换为false]
//4)、逻辑或同样是短路操作,如果第一个操作数返回为true,就不执行第二个操作数
//5)、第一个操作数是 NaN 的时候 返回 第二个操作数
alert(NaN||NaN);//NaN
alert(NaN||5);//5
alert({}||5>3);//object Object
alert(4<3||5);//5
alert({}||5);//object Object
alert(null||null);//null
alert(null||4);//4
alert(null||6>4);//true
alert(undefined||{});//object Object
alert(undefined||undefined);//undefined
alert(undefined||5>3);//true
alert(5<3||undefined);//undefined
alert(5<4||null);//null
//1)、操作数是一个 对向 的时候,转换成布尔值为true,取反为false
// 2)、操作数是一个 空字符串 时候,转换成布尔值为false,取反为true
// 3)、操作数是一个 非空字符串 的时候,转换成布尔值为true,取反为false
// 4)、操作数是一个 非0数值 的时候,转换成布尔值为true,取反为false
// 5)、操作数是一个数值 0 的时候,转换成布尔值为false,取反为true
// 6)、操作数是一个 null/NaN/undefined 的时候,转换成布尔值为false,取反为true
alert(!{});//false 对象转换成布尔值为true
alert(!'');//true
alert(!"bs");//false;
alert(!0);//true
alert(!8);//false
alert(!NaN);//true 隐试转换为布尔值是 false
alert(!null);//true 转换为布尔值为false
alert(!undefined);//true 转换为布尔值为false
//上面的所有都等价于下面通过Boolean()转换函数转换后再进行取反
alert(!Boolean({}));//false
*/
练习代码