JS 学习笔记--4---运算符
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、练习只中的代码 采用块注释查看
1 //alert("运算符练习"); 2 /* 3 // 自增和自减运算符 4 //自增运算和其他运算组合使用的时候,变量本身前自导和后自导运算优先级是不一样的 5 //但是对变量本身来说运算的结果是一样的,只是组合表达式的值不一样 6 var box=100; 7 box++;//后导自增 8 alert(box);//101 9 ++box;//前导自增 10 alert(box);//102 11 var age=box++;//先赋值后自增 12 alert(age);//102 13 alert(box);//103 14 age=++box;//先自增后赋值 15 alert(box);//104 16 alert(age)//104 17 // 自增自减运算符 是会改变变量的类型的 先将非number类型的数据转换为number类型数据 18 var age='88a'; 19 alert(typeof age); 20 age++; 21 alert(age);//NaN 22 alert(typeof age);//number 23 24 var age=true; 25 alert(typeof age);//boolean 26 age++;// boolean中的 true 转换成number后为1,然后自增为2 27 alert(age);//2 28 alert(typeof age);//number 29 30 var box={ 31 valueOf:function(){ 32 return 23; 33 } 34 } 35 alert(typeof box);// object 36 alert(box++);//23 先输出然后再自增 37 alert(box);//24 38 alert(typeof box);// number 39 40 41 // +、- 运算符 和上面的自增自减运算符一样 只是取正负的问题 42 //同样是先转换成number类型然后再操作 优先级一般比其他运算符高 43 var box=89; 44 alert(typeof box);//number 45 alert(+box);//89 46 var age=-23; 47 alert(-age);//23 对原来的变量进行了一个取反 48 49 var box='89'; 50 alert(typeof +box);//number 51 alert(typeof box);//string 52 box++; 53 alert(box);//90 54 alert(typeof box);//number 55 56 var box='abc'; 57 alert(+box);//NaN 不能够转换成number类型的数值就返回的是NaN,NaN和进行任何运算还是NaN 58 alert(typeof box);//string 59 alert(typeof +box);//number 60 61 var box=34; 62 alert(4+-box);//-30 alert(4+(-box))//对box先取反 然后再和4相加 63 64 */ 65 /*----------- 二元运算符 66 //加法运算 当运算符两边没有字符串作为表达式时,会将其他的类型进行一个类型转换 67 //object类型也是根据其返回值进行计算 如果有字符串涉及到运算时 是进行字符串的拼接 68 var box=true; 69 alert(box+23);//24 70 71 var age='abc'; 72 alert(age+23);//abc23 73 74 var h=null; 75 alert(h+23);//23 null 类型转换成number类型为0 76 77 var obc = {}; 78 alert(obc+23);//[object Object]23 79 80 var box={toString:function(){return 3;}}; 81 alert(box+34);//37 82 83 alert("abcd"+23+12);//abcd2312 从左到右计算 先进行的是字符串的拼接 84 alert(23+12+'abc');//35abc 从左到右计算 先进行的是加法运算然后再进行字符串的拼接 85 86 alert(Infinity+Infinity);//Infinity 87 alert(-Infinity+-Infinity);//-Infinity 88 alert(Infinity+-Infinity);//NaN 89 //减法和乘法在计算时和加法基本上是一样的 只是在和字符串进行计算时是转换成0/NaN 90 alert(34-'abc');//NaN 91 alert(34*'');//0 92 93 //除法 94 alert(Infinity/Infinity);//NaN 95 alert(45/'');//Infinity 96 alert(45/null);//Infinity 97 alert(34/'abc');//NaN 98 alert(34/{});//NaN 99 100 //取余 同样是先进行隐试转换 不过对分母为0的数取模得到的是NaN 101 alert(Infinity%Infinity);//NaN 102 alert(-11%3);//-2 103 alert(23%'');//NaN 104 alert(23%null);//NaN 105 alert(23%true);//0 true转换为1 106 alert(23%{});//NaN 107 alert(23%'abc');//NaN 108 alert(23%-3);//2 109 alert(''%23);//0 110 111 */ 112 113 /* 关系运算符 114 //当操作数是非数值是应该遵循的一些规则: 115 //1)、都是数值是进行数值比较 2)、两个操作数都是字符串时则比较对应的字符编码值 116 //3)、两个操作数有一个是数值时就将另外一个操作数转换成数值 然后再进行数值比较 117 //4)、两个操作数,一个是对象时,先调用valueOf()和toString()方法,然后再进行结果比较,否则,如果这两个方法不存在(没有显示的写明返回值)的话,比较结果始终为false 118 119 alert('3'>'2');//true 120 alert('3'>22);//false 是将 '3' 转换成了数值来进行比较 121 alert('3'>'a');//比较的是ascii码 122 alert(3>'a');//false 123 alert(3>{});//false 如果对象没有toString或者valueOf方法 永远都是false 124 alert({}>'a');////false 125 alert('abc'>'abcd');//false 126 alert('ab'>'ac')//false 127 128 alert('2'==2);//true '2'将会转换成数值 2 129 alert('2'===2);//false 进行全等比较的时候 不仅要比较大小 还要比较类型是否相等 130 alert(undefined==null);//true 就简单的值上面来说是相等的 131 alert(undefined===null);//false 类型不一样 132 alert(false==0);//true false会自动的转换成0 133 alert(2=={});//false 和一个对向基本上相比基本上是false 除非其中的两个方法有返回值比较 134 alert(2==NaN);//false NaN和任何对象相比都是false的 135 alert({}=={});//false 两个对象相同的时候 除非他们的引用相同 136 alert(NaN==NaN);//false 137 var box={}; 138 var he=box; 139 alert(box==he);//true 因为他们的引用是内存中同一块内存 140 alert(box===he); 141 142 */ 143 144 /* 逻辑运算符 返回的不一定是布尔值 有可能是操作数 145 //第一个操作数为对象的时候 返回第二个操作数 146 alert({}&&5>4);//true 147 alert({}&&5);//5 148 //第二个操作数为对象的时候,如果第一个操作数是true,就返回第二个操作数,否则为false 149 alert(5>4&&{});// object Object 150 alert(5<4&&{});// false 151 alert(5>4&&{toString:function(){return 'a';}});//a 152 //在逻辑与时 如果第一个操作数为false 就不会执行第二个操作数,哪怕第二个操作数会报异常 153 //可以得出 在第一个操作数为true的时候 第二个操作数如果是null或者undefined就 154 //返回null或者undefined,否则返回false 155 alert(5>4&&null);//null 156 alert(5<4&&null);//false 157 alert(4>3&&undefined);//undefined 158 alert(5>6&&undefined);//false 159 alert(4&&5);//视为两个都是对象 160 161 162 //逻辑或 163 //1)、如果第一个操作数是对象的话,则返回第一个操作数(因为隐试转换使用为true) 164 //2)、如果第一个操作数为false,则返回第二个操作数,[逻辑值/null/undefined/对象]等 165 //3)、第一个操作数为null或者undefined的时候,返回第二个操作数[这两个隐试准换为false] 166 //4)、逻辑或同样是短路操作,如果第一个操作数返回为true,就不执行第二个操作数 167 //5)、第一个操作数是 NaN 的时候 返回 第二个操作数 168 alert(NaN||NaN);//NaN 169 alert(NaN||5);//5 170 alert({}||5>3);//object Object 171 alert(4<3||5);//5 172 alert({}||5);//object Object 173 alert(null||null);//null 174 alert(null||4);//4 175 alert(null||6>4);//true 176 alert(undefined||{});//object Object 177 alert(undefined||undefined);//undefined 178 alert(undefined||5>3);//true 179 alert(5<3||undefined);//undefined 180 alert(5<4||null);//null 181 //1)、操作数是一个 对向 的时候,转换成布尔值为true,取反为false 182 // 2)、操作数是一个 空字符串 时候,转换成布尔值为false,取反为true 183 // 3)、操作数是一个 非空字符串 的时候,转换成布尔值为true,取反为false 184 // 4)、操作数是一个 非0数值 的时候,转换成布尔值为true,取反为false 185 // 5)、操作数是一个数值 0 的时候,转换成布尔值为false,取反为true 186 // 6)、操作数是一个 null/NaN/undefined 的时候,转换成布尔值为false,取反为true 187 alert(!{});//false 对象转换成布尔值为true 188 alert(!'');//true 189 alert(!"bs");//false; 190 alert(!0);//true 191 alert(!8);//false 192 alert(!NaN);//true 隐试转换为布尔值是 false 193 alert(!null);//true 转换为布尔值为false 194 alert(!undefined);//true 转换为布尔值为false 195 //上面的所有都等价于下面通过Boolean()转换函数转换后再进行取反 196 alert(!Boolean({}));//false 197 */