第三章:基本概念(操作符)
2017-03-15 09:08
183 查看
操作符
递增和递减操作符
一元加和减操作符
位操作符
按位非
按位与
按位或
按位异或
左移
右移有符号右移无符号右移
布尔操作符
乘性操作符
加性操作符
加法
减法操作符
关系比较符
相等操作符
相等和不相等
全等和不全等
条件操作符
赋值操作符
逗号操作符
当递增递减操作符应用于字符串、布尔值或者对象时。可以理解成在上一篇文章中提到过的,先将变量通过Number()函数转换为数值,再进行计算。这里就简单举3个object的例子:
o1和o2的结果是在预想中的,在执行自增运算时,先是求Number(o1),由于o1是对象,故先调用valueOf()方法再得到有效值”1”后,再执行Number(“1”)返回数值1自增得到2。o2的结果是因为没有重写valueOf方法,或者说valueOf方法的返回值执行Number后是NaN,所以再调用toString()最终得到3。o4的执行结果我也是可以理解的,两个都是NaN故最终结果是NaN。但是o3的结果就令我非常困惑了。书上的原话是执行valueOf得到NaN会再去调用toString。(后来我看到减法操作,发现如果有valueOf方法则使用valueOf方法的返回结果)那么按照我的理解o3最终是会得到3的。但是实验告诉我结果是NaN。我用的是Chrome浏览器,是不是书上说的已经过时了,还是我理解的不对。希望有人看到这个能评论讨论一下这个内容。这里再顺便说下如果在alert(++o4)之前alert(o4)是会输出2xx的,因为会自动调用在o4自增前o4还是个object,会自动调用toString()方法。而自增后o4已经变成一个Number类型了。
按位非操作其实就相当于取反减一。但其速度会优于取反减一操作。
逻辑非(!):只有一个操作数,可以应用任何值,无论这个值是什么都会返回布尔值(注意和下面两个操作符的区别)。其实它的功能总结起来就是先用Boolean()函数对这个值取结果,然后再进行逻辑非运算。所以连续两个逻辑非’!!’的效果和Boolean()是一模一样的。
逻辑与(&&):有两个操作数。在有一个操作数不是布尔值的时候,其返回结果就不一定是布尔值。
因为逻辑与操作符是短路操作符(逻辑或操作符也是),所以上述的结果其实很好理解了。首先会对第一个操作数进行Boolean()操作。如果是false,那么对不起直接返回第一个操作数的原型(原来是什么就返回什么),第二个到底是什么就不管了(即使第二个操作数未定义)。如果第一个是true。再去对第二个操作数进行Boolean()操作,如果还是true,那就返回第二个操作数的原型。那如果第二个操作数是false。那么也会返回第二个操作数的原型。所以总结下来就是( 以下是我的个人总结,如有不对欢迎指出。):
第一个操作数使用Boolean()计算是false,则返回第一个操作数原型。
第一个操作数使用Boolean()计算是true,则返回第二个操作数原型。
逻辑或(||):有两个操作数。在有一个操作数不是布尔值的时候,其返回结果就不一定是布尔值。类比上面的逻辑与操作符有总结如下:
第一个操作数使用Boolean()计算是true,则返回第一个操作数原型。
第一个操作数使用Boolean()计算是false,则返回第二个操作数原型。
小tips:上述逻辑或的特性常用于给函数赋默认值,如下:
Infinity * Infinity = Infinity
Infinity / Infinity = NaN
Infinity % Infinity = NaN
10 / Infinity = 0
10 / 0 = Infinity
0 / 0 = NaN
如果都是字符串,比较对应的字符编码值。(按高到低)
如果一个是数值,则将另外一个操作数通过Number()转换为数值进行比较。
如果一个操作数是对象,调用valueOf方法。如果没有valueOf方法则调用toString()方法。再按照前三条规则比较。
如果是布尔值则通过Number()转换成数值,再按照前三条。
如果一个是字符串,一个是数值,则将字符串转成数值比较(可能得到NaN)。
如果一个是对象,一个不是,则调用该对象的valueOf方法(如果valueOf返回的还是对象则调用toString),通过返回的值的类型再按照上面规则进行比较。
null 和 undefined相等,且不能将其转换成其他值。
如果操作数中有NaN, 相等永远为false。不等永远为true。(NaN != NaN)
如果都是对象,则比较他们是不是同一个对象。如果指向同一个对象返回true。
*=
/=
%=
+=
-=
<<=
>>=
>>>=
递增和递减操作符
一元加和减操作符
位操作符
按位非
按位与
按位或
按位异或
左移
右移有符号右移无符号右移
布尔操作符
乘性操作符
加性操作符
加法
减法操作符
关系比较符
相等操作符
相等和不相等
全等和不全等
条件操作符
赋值操作符
逗号操作符
操作符
定义:操作符能用于操作数据值,包括算术运算符、位操作符、关系操作符和相等操作符。操作符能适用于很多值,例如字符串、数字值、布尔值,甚至对象。在应用于对象时,相应的操作符通常会调用对象的valueOf()和(或)toString()方法,以便取得可以操作的值。递增和递减操作符
(+ +,- -)应用于数值时,和java中没有区别。要注意的是操作符的位置分为前置和后置。前置递增使变量的值在语句被求以前改变(可以理解成返回递增后的值)。举个例子:var age = 29; //以下几个都是单独存在: var anotherage = ++age + 1;//31 age的值会在(++age) + 1之前改变(想象++age已经计算完毕), 所以最终得到了31。这种在科学领域称为副效应。 var anotherage = age++ + 1;//输出30 刚好与前置递增相反。 var anotherage = age++ + age + 1;//输出60 第一个age++返回了29,第二个age已经是30,再加1得到60 var anotherage = ++age + age + 1;//输出61 var anotherage = age + ++age + 1;//输出60 上面的现象与java中一模一样
当递增递减操作符应用于字符串、布尔值或者对象时。可以理解成在上一篇文章中提到过的,先将变量通过Number()函数转换为数值,再进行计算。这里就简单举3个object的例子:
var o1 = { valueOf : function () { return "1"; }, toString : function () { return "2"; } } var o2 = { toString : function () { return "2"; } } var o3 = { valueOf : function () { return "1xx"; }, toString : function () { return "2"; } } var o4 = { valueOf : function () { return "1xx"; }, toString : function () { return "2xx"; } } alert(++o1);//2 alert(++o2);//3 alert(++o3);//NaN alert(++o4);//NaN
o1和o2的结果是在预想中的,在执行自增运算时,先是求Number(o1),由于o1是对象,故先调用valueOf()方法再得到有效值”1”后,再执行Number(“1”)返回数值1自增得到2。o2的结果是因为没有重写valueOf方法,或者说valueOf方法的返回值执行Number后是NaN,所以再调用toString()最终得到3。o4的执行结果我也是可以理解的,两个都是NaN故最终结果是NaN。但是o3的结果就令我非常困惑了。书上的原话是执行valueOf得到NaN会再去调用toString。(后来我看到减法操作,发现如果有valueOf方法则使用valueOf方法的返回结果)那么按照我的理解o3最终是会得到3的。但是实验告诉我结果是NaN。我用的是Chrome浏览器,是不是书上说的已经过时了,还是我理解的不对。希望有人看到这个能评论讨论一下这个内容。这里再顺便说下如果在alert(++o4)之前alert(o4)是会输出2xx的,因为会自动调用在o4自增前o4还是个object,会自动调用toString()方法。而自增后o4已经变成一个Number类型了。
一元加和减操作符
注意这里说的是一元操作符,一元加操作符对于Number类型不会有任何变化(如果是减操作符就是取相反数)。如果是其他类型则执行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; //value becomes numeric 1 s2 = +s2; //value becomes numeric 1.1 s3 = +s3; //value becomes NaN b = +b; //value becomes numeric 0 f = +f; //no change, still 1.1 o = +o; //va 4000 lue becomes numeric -1
位操作符
当对数值应用位操作符时,后台会发生如下转换过程:64位的数值被转换成32位数值,然后执行位操作,最后再将32位的结果转换为64位数值。这样表面看起来就好像是在操作32位数值。但这样会导致一个严重的副效应,再在特殊的NaN和Infinity值应用位操作时,这2个值会被当成0来对待。按位非 (‘~’)
var num1 = 25; //binary 00000000000000000000000000011001 var num2 = ~num1; //binary 11111111111111111111111111100110 alert(num2); //-26
按位非操作其实就相当于取反减一。但其速度会优于取反减一操作。
按位与 (‘&’)
按位与有2个操作数。与运算是在两个值都为1的时候才为1,这里省略例子。按位或 (‘|’)
按位或有2个操作数。或运算是在两个值都为0的时候才为0,这里省略例子。按位异或 (‘^’)
按位异或有2个操作数。异或运算是在两个值都不相同的时候才为1,这里省略例子。左移(‘<<’)
左移运算就是把32位下的后31位(除去符号位)进行左移,右边多出来的空位填0。例子如下:var a = 2; alert(a << 2);//得到8相当于乘以2^n
右移(有符号右移’>>’,无符号右移’>>>’)
通常来说右移相当于除以2操作。有符号右移与左移类似。无符号右移对于正数来说和有符号右移没有区别。但是对负数进行无符号右移时,由于负数存的是补码,此时会将其当做正数处理,所以一般会造成得到的结果非常大。布尔操作符
布尔操作符有3个(!, &&, ||),和java中用法相同。以下分别对三个操作符进行说明:逻辑非(!):只有一个操作数,可以应用任何值,无论这个值是什么都会返回布尔值(注意和下面两个操作符的区别)。其实它的功能总结起来就是先用Boolean()函数对这个值取结果,然后再进行逻辑非运算。所以连续两个逻辑非’!!’的效果和Boolean()是一模一样的。
逻辑与(&&):有两个操作数。在有一个操作数不是布尔值的时候,其返回结果就不一定是布尔值。
alert("12" && true);//true alert("" && "34");//"" alert("12" && "34");//"34" alert(true && "34");//"34" alert(null && "34");//"null" alert(NaN && null);//NaN alert(undefined && null);//undefined alert(false && null);//false
因为逻辑与操作符是短路操作符(逻辑或操作符也是),所以上述的结果其实很好理解了。首先会对第一个操作数进行Boolean()操作。如果是false,那么对不起直接返回第一个操作数的原型(原来是什么就返回什么),第二个到底是什么就不管了(即使第二个操作数未定义)。如果第一个是true。再去对第二个操作数进行Boolean()操作,如果还是true,那就返回第二个操作数的原型。那如果第二个操作数是false。那么也会返回第二个操作数的原型。所以总结下来就是( 以下是我的个人总结,如有不对欢迎指出。):
第一个操作数使用Boolean()计算是false,则返回第一个操作数原型。
第一个操作数使用Boolean()计算是true,则返回第二个操作数原型。
逻辑或(||):有两个操作数。在有一个操作数不是布尔值的时候,其返回结果就不一定是布尔值。类比上面的逻辑与操作符有总结如下:
第一个操作数使用Boolean()计算是true,则返回第一个操作数原型。
第一个操作数使用Boolean()计算是false,则返回第二个操作数原型。
alert("12" || true);//"12" alert("" || "34");//"34" alert("12" || "34");//"12" alert(true || "34");//true alert(null || "34");//"34" alert(NaN || null);//null alert(undefined || null);//null alert(false || null);//null
小tips:上述逻辑或的特性常用于给函数赋默认值,如下:
function getAjaxResponse(url,method) { method = method || "get"; ... } /*上述做法当调用getAjaxResponse("hello world!")时, *由于method未传,在函数中为undefined, */利用逻辑或的特性可以为method赋值"get"
乘性操作符
乘性操作符包括乘除和取余。总结一句话就是如果操作数不是数值类型,利用Number()隐性转换。如果操作数中包含NaN,那么结果是NaN。如果包含Infinity:Infinity * Infinity = Infinity
Infinity / Infinity = NaN
Infinity % Infinity = NaN
10 / Infinity = 0
10 / 0 = Infinity
0 / 0 = NaN
加性操作符
加法
普通数值操作就不说了,以下是几个特例console.log(+0 + +0);//"0" console.log(-0 + -0);//"-0" alert不会体现 /* *如果操作数不是数字,当其中有一个为字符串时, *转成字符串进行拼接。(前一章有提到)(书上说是toString, *但实验结果说明valueOf优先于toString)。 *如果两者都不是字符串,则通过Number()获取两个结果进行加法运算。 */ var a; var b = "123"; var c = 123; alert(a + b);//"undefined123" alert(a + c);//NaN 这里认为是数值加法运算
var a = { valueOf: function () { return 1; }, toString: function () { return 2; } } var b = { valueOf: function () { return 4; }, toString: function () { return 8; } } var c = "hello"; alert(a);//输出2 前面章节提到过 alert(a + c);//输出 "1hello" 这里会先调用valueOf alert(a && c);//输出 "hello" a不是空对象为true alert(a || c);//输出 2 这里会先调用toString alert(a + b);//输出5
减法操作符
减法同加法没有什么区别,唯一的区别是减法没有截取字符串一说。以下是例子:当遇到操作数不是数值的时候,会隐性的调用Number()方法转成数值。var a = { valueOf: function () { return 1; }, toString: function () { return 2; } } var b = { toString: function () { return 8; } } var c = "hello"; var d = "1"; var e = "1xx"; alert(a - c);//输出 NaN (1-NaN) 这里会先调用valueOf alert(a - b);//输出-7 alert(a - d);//输出0 alert(a - e);//输出NaN (1-NaN)
关系比较符(>, <, >=, <=)
如果两个操作数都是数值,执行数字比较。如果都是字符串,比较对应的字符编码值。(按高到低)
如果一个是数值,则将另外一个操作数通过Number()转换为数值进行比较。
如果一个操作数是对象,调用valueOf方法。如果没有valueOf方法则调用toString()方法。再按照前三条规则比较。
如果是布尔值则通过Number()转换成数值,再按照前三条。
var a = "123"; var d = "123xx"; var b = { valueOf: function () { return 2; }, toStrong: function () { return "2"; } } var c = { toStrong: function () { return "2"; } } alert(a > b);//true 先是valueOf返回数值2 再将"123"转为数值123 比较得到true alert(a > c);//false 先是toString返回字符串"2" "123" < "2" alert(d > 1 || d <= 1);//false 先是Number()返回NaN NaN不管怎么比较都是false
相等操作符
相等和不相等(==, !=)
如果一个操作数是布尔值,先转成数值再进行比较。如果一个是字符串,一个是数值,则将字符串转成数值比较(可能得到NaN)。
如果一个是对象,一个不是,则调用该对象的valueOf方法(如果valueOf返回的还是对象则调用toString),通过返回的值的类型再按照上面规则进行比较。
null 和 undefined相等,且不能将其转换成其他值。
如果操作数中有NaN, 相等永远为false。不等永远为true。(NaN != NaN)
如果都是对象,则比较他们是不是同一个对象。如果指向同一个对象返回true。
全等和不全等(===, !==)
全等比较符除了在比较前不转换类型外,其他都与相等操作符一样。(null !== undefined)条件操作符
和java中一样。例如:var max = (num1 > num2) ? num1 : num2;
赋值操作符
此处简单略过,使用类似 += -=其实主要目的是简化赋值操作。不会带来性能的提升。有以下几个赋值操作:*=
/=
%=
+=
-=
<<=
>>=
>>>=
逗号操作符
使用逗号操作符多用于声明多个变量。除此之外,逗号操作符还可以用于赋值。用于赋值时,逗号操作符总会返回表达式中的最后一项。例子如下:var num1=1, num2=2, num3=3; var num = (1, 2, 3, 4, 5);//num最终为5
相关文章推荐
- 第三章 基本概念(第三部分:操作符)
- JavaScript高级程序设计第三章基本概念——操作符
- 【C】【笔记】《C和指针》 第一章 快速上手 第二章 基本概念 第三章 数据 第四章 语句 第五章 操作符和表达式
- 第三章 基本概念
- JavaScript高级程序设计之基本概念之相等操作符第3.5.7讲笔记
- JavaScript高级程序设计第三章基本概念——总结
- 第三章(基本概念——语法,数据类型,流程控制语句,函数)
- 《avascript 高级程序设计(第三版)》 ---第三章 基本概念2
- 读书笔记 - js高级程序设计 - 第三章 基本概念
- JavaScript高级程序设计第三章基本概念
- JavaScript高级程序设计之基本概念之相等操作符第3.5.8讲笔记
- 《机器学习实战》第三章:决策树(1)基本概念
- 第三章 基本概念
- Augular4 第三章(上) 路由基本概念,路由的配置,路由的参数传递
- JavaScript高级程序设计第三章基本概念——函数
- 《Erlang 程序设计》练习答案 -- 第三章 基本概念
- 第三章 基本概念(中) --《Javascript高级程序设计》
- JavaScript 基本概念之操作符、语句、函数
- 第3章 基本概念(4)操作符:一元操作符......
- JS高级程序设计学习笔记之第三章基本概念(语法,数据类型,流控制语句,函数)——查漏补缺