JavaScript高级程序设计(第3版)学习笔记4 js运算符和操作符


Posted in Javascript onOctober 11, 2012

在ECMAScript中,有非常丰富的运算符和操作符,在这篇文章中将按通常的分类来稍微整理一下,不过在整理之前,先说明一下:

1、虽然标题是运算符和操作符,然而在我看来并没有多少严格区分的必要,在英文中,貌似也是用一个Operator来表示,所以在下文中我可能会混用。甚至,一些不属于运算符和操作符范畴的,我也整理在这里,只要我觉得必要。

2、对于运算符的优先级,你无需一一牢记——我相信你知道最简单的”先乘除,后加减”,至于其它的,如果你不确定,加上括号好了。在ECMAScript中,优先级相同的从左向右运算。

3、对于一些编程语言通用的运算符,比如常用算术运算符(+-*/),我只会简单的列举一下,不会展开,但是请注意,并不是说这些不重要,相反,这些通用运算符甚至处于一个非常基础的地位,只是我觉得你应该早已经熟悉,没必要在这里花时间强调。

4、那么,这里重点关注什么呢?就是一些在ECMAScript中比较特殊的操作符,或者我认为值得花时间强调的一些地方。

运算符与操作符

类别 操作符  描述 说明
一元操作符 ++  自增1 1、自增(减)有前置和后置两种类型,前置先自增(减)再参与其它运算,后置先参与其它运算再自增(减)。 2、在ES中,自增(减)不仅适用于整数,它们可以作用于任意值,对于不是Number类型的值,会先按前一篇文章中的规则隐式转换为Number,然后再自增(减),此时变量类型也会变成Number类型。
--  自减1
+  一元加 一元加最主要的应用就是将操作数转变为Number类型,相当于调用Number()转换。 
-  一元减 一元减则是在一元加的基础之上再取其相反数。
算术操作符 +  加 1、除了加(+)之外,如果操作数不是Number类型,会自动调用Number()转换为Number类型再进行计算。 2、对于加减(+-),除了作为算术运算符。还可以作为一元操作符(见上)。当然,由于字符串操作中对加号(+)的重载,还可以用于将任意数值(的字符串)相连,这也是第1点中为什么要除了加(+),它在含有非Number类型值时,会将所有操作数转换为字符串相连接。 3、与一般类C语言不同,在ES中,除(/)和取模(%)并不会区分整数和浮点数,比如 5 / 2 = 2.5 而不是2,5.3 % 3 = 2.3 而不是2。 4、任意运算,只要操作数含NaN,结果就是NaN。但并不是结果为NaN就一定有一个操作数为NaN,比如0/0也返回NaN。 5、对于含无穷Infinity的运算,规定比较多,这里就不列举了,可以参考原书,或者自行测试。
-  减
*  乘
/  除
%  取模
逻辑操作符 (布尔操作符) !  逻辑非 首先将操作数转换为Boolean类型值,然后再取反。可以使用双重非!!将一个数值转换为相应的Boolean值。 
&&  逻辑与 1、当两个操作数相应的Boolean值均为true时,返回true 2、短路:当第一个操作数相应的Boolean值为false时,会直接返回false,不会再计算第二个操作数。这常常被应用在判断一个变量(属性)是否有定义,如:if(object && object.name && object.name = 'linjisong'){ } 这里会首先判断object存在,不存在的话就不会解析object.name从而阻止错误的发生,同样,也只有object.name存在,才会去比较这个值。
||  逻辑或 1、当两个操作数相应的Boolean值至少有一个为true时,返回true 2、短路:当第一个操作数相应的Boolean值为true时,会直接返回true,不会再计算第二个操作数。 3、逻辑或,除了用于一般的判断之外,还常常被应用在提供默认值的情况,如:function Fn(obj){ obj = obj || {};} 这里如果调用Fn未传入obj,则会自动给obj赋值为undefined,然后因为undefined的相应Boolean值为false,所以会将一个空对象{}赋值给obj,如果调用传入了obj,则因为任意对象的Boolean值为true,所以就不会取后面的{},从而达到给obj一个默认值{}的效果。 这种方式还被应用在大型JS库的多个相对独立的文件中://jsLibvar jsLib;//file1(function (jsLib){ jsLib = jsLib || {};})(jsLib); //file2(function (jsLib){ jsLib = jsLib || {}; })(jsLib); 使用这种方式,无论先加载哪个文件,都会判断jsLib是否已经定义,如果未定义就提供一个默认值,这样做可以使得相对独立模块可以不用考虑加载顺序。
关系操作符 (比较操作符)  小于 1、只要有一个操作数是Number类型或Boolean类型值,就将两个操作数转换成Number类型值(如果需要转换)执行数值比较。 2、字符串比较,会逐个比较字符编码值。 3、操作符是对象时,调用valueOf()(如果没有,就调用toString()),再将结果按上面规则比较。 4、任意数和NaN比较返回false。
 小于或等于
>  大于
>=  大于或等于
==  相等 1、相等和不等(==、!=)在比较时,只要有必要,就会隐式类型转换。 2、全等和不全等(===、!==)在比较时,不会转换类型,如果类型不一致,直接为!==。 3、结合1、2,可以知道,a===b则一定有a==b,而a!=b则一定有a!==b。
!=  不等
===  全等
!==  不全等
赋值操作符 =  赋值  
复合算术赋值操作符  算术运算符加= 对应算术运算符,有+=、-=、*=、/=、%= 
复合按位赋值操作符  按位运算符加= 对应按位运算符,有~=、&=、|=、^=、>=、>>>=
按位操作符 ~  按位非 按位取反,也即返回反码
&  按位与 按位对齐,逐位操作,只有两个操作位均为1才返回1,否则该位返回0,最后将所有位操作结果组合返回
|  按位或 按位对齐,逐位操作,只有两个操作位均为0才返回0,否则该位返回1,最后将所有位操作结果组合返回 
^  按位异或 按位对齐,逐位操作,两个操作位不相同时返回1,否则该位返回0,最后将所有位操作结果组合返回
 左移 二进制数向左移位,左移不会改变符号位 
>>  有符号右移 二进制数向右移位,高位以符合位填充 
>>>  无符号右移 二进制数向右移位,直接右移,对于正数,结果和>>相同,对于负数,会把负数的二进制补码当成正数的二进制码处理
字符串操作符 +  字符串连接 相当于concat()函数,会先将所有操作数转换为字符串,然后再连接。注意,字符串一旦创建就不会变更,执行字符串连接时,在后台会有一个中间的连接和销毁过程,这也是老旧浏览器在大量字符串连接操作时运行缓慢的原因。
+=  字符串连接复合 a+=b,相当于a=a+b。 
对象操作符 .  属性访问符 简单的对象属性访问符。
[]  属性或(类)数组访问 通过[],可以访问名称是一个变量或含有特殊字符的属性。
new  调用构造函数创建对象 返回一个新创建的对象,在构造函数内部的this被指向这个新创建的对象。
delete  变量、属性删除 删除属性(变量可以看成是全局对象或执行环境的一个属性)。
void   返回undefined。
in  判断属性 对象属性或原型链上的属性。
instanceof  原型判断 比较同一个上下文中的对象是否为另一个对象的原型。
其它操作符 ?:  条件操作符 语法;var value = exp ? trueExp : falseExp。 相当于var value; if(exp){ value = trueExp;}else{value = falseExp;}
,  逗号操作符 主要用于声明多个变量,这也是很多JS库的流行做法。例如:var num1=1,num2=2,num3=3;
()  分组操作符 主要用途: 1、结合逗号操作符用于赋值。例如:var num = (5,1,4,8,0);这里num最后的值为0。 2、转换为表达式。比如eval('('+jsStr+')');又比如:function fn(){}//函数声明,不能直接调用(function fn(){})();//使用()将函数括起来,便可以直接调用3、用于调用函数。比如fn();。
typeof  类型操作符 返回一个字符串值:Undefined类型—>'undefined'、Null类型—>'object'、Boolean类型—>'boolean'、Number类型—>‘number'、String—>'string'、内置Function对象的实例—>'function'、其它Object类型—>'object'。(有些浏览器实现略有不同)

说明几点:

1、这里的分类并不十分严格,比如按位非(~)、逻辑非(!)、delete、void、typeof,都可以算是一元操作符,而自增(++)在很多资料中也被归为算术操作符之中。我在整理时则主要参考原书分类,也兼顾自然性。

2、加号(+)的用法比较灵活,需注意,特别是用于计算时,忽略了其中的字符串,会很容易犯错误。

3、typeof一般用来判断简单数据类型,如果是对象类型,因为大部分返回的都是object,没有多大实际用处,而instanceof的判断也需要满足同一个上下文的条件,否则也会出错,对于对象类别的判断会在后面讲述对象时再详细说明另外一种更为稳妥的方法。

4、先看下面的代码:

var numVal = 10.00, 
strVal = '10', 
strObj = new String('10'); 
console.info(numVal == strVal);//true 
console.info(typeof (strVal+strObj));//string

第一个输出的竟然是true,是不是出乎你的意料?在这里,由于==比较符发生了隐式类型转换,会将Number类型转换为String类型,然后Number类型的10.00因为小数点后没有不是0的数值,会被解析成整数10,从而比较的时候会相等。第二个输出是string,这其实还是比较容易理解的,strVal是字符串,strObj是字符串对象,两者相加,会把对象转换成字符串,所以最终结果也是字符串类型。
5、关于符号,重复一下几个流行的用法(这里不涉及正则表达式中的用法):
(1)使用一元加号(+)转换为Number类型。
(2)使用双重逻辑非(!!)转换为Boolean类型。
(3)使用逻辑与(&&)来检测对象是否存在并进行后续操作。
(4)使用逻辑或(||)来给函数参数提供默认值。
(5)使用分组(())来明确指定为表达式。
(6)使用花括号({})来定义对象字面量,JSON数据格式,代码块。
(7)使用中括号([])来定义数组字面量,JSON数据格式,访问数组,访问名称是变量或特殊字符的属性。
6、关于按位运算,虽然结果不是很直观,但是运行效率高,也有很多有趣的应用,比如不使用中间变量直接交换两个数值、判断奇数和偶数、MD5加密等等,有兴趣的朋友可以找相关资料自行研究。
Javascript 相关文章推荐
javascript 自动转到命名锚记
Jan 10 Javascript
node.js实现多图片上传实例
Jun 03 Javascript
javascript弹出带文字信息的提示框效果
Jul 19 Javascript
jQuery插件ajaxFileUpload异步上传文件
Oct 19 Javascript
深入理解javascript函数参数与闭包
Dec 12 Javascript
JS实现线性表的顺序表示方法示例【经典数据结构】
Apr 11 Javascript
JavaScript数据结构学习之数组、栈与队列
May 02 Javascript
详解Angular2 之 结构型指令
Jun 21 Javascript
Angular在模板驱动表单中自定义校验器的方法
Aug 09 Javascript
微信小程序富文本渲染引擎的详解
Sep 30 Javascript
vue-cli 3.0 自定义vue.config.js文件,多页构建的方法
Sep 19 Javascript
ES6 class的应用实例分析
Jun 27 Javascript
JavaScript高级程序设计(第3版)学习笔记3 js简单数据类型
Oct 11 #Javascript
JavaScript高级程序设计(第3版)学习笔记2 js基础语法
Oct 11 #Javascript
JavaScript高级程序设计(第3版)学习笔记 概述
Oct 11 #Javascript
javascript测试题练习代码
Oct 10 #Javascript
jQuery插件开发全解析
Oct 10 #Javascript
Jquery图形报表插件 jqplot简介及参数详解
Oct 10 #Javascript
关于jQuery UI 使用心得及技巧
Oct 10 #Javascript
You might like
Apache设置虚拟WEB
2006/10/09 PHP
PHP syntax error, unexpected $end 错误的一种原因及解决
2008/10/25 PHP
php缓冲 output_buffering的使用详解
2013/06/13 PHP
PHP与MYSQL中UTF8 中文排序示例代码
2014/10/23 PHP
PHP生成随机数的方法总结
2018/03/01 PHP
js获取图片长和宽度的代码
2009/11/24 Javascript
50个比较实用jQuery代码段
2011/09/18 Javascript
向当前style sheet中插入一个新的style实现方法
2013/04/01 Javascript
js捕获鼠标滚轮事件代码
2013/12/16 Javascript
js复制网页内容并兼容各主流浏览器的代码
2013/12/17 Javascript
jquery设置按钮停顿3秒不可用
2014/03/07 Javascript
12个超实用的JQuery代码片段
2015/11/02 Javascript
AngularJS ng-bind-html 指令详解及实例代码
2016/07/30 Javascript
JS动态生成年份和月份实例代码
2017/02/04 Javascript
javascript实现table单元格点击展开隐藏效果(实例代码)
2017/04/10 Javascript
浅谈vue-router2路由参数注意的问题
2017/11/08 Javascript
vue项目上传Github预览的实现示例
2018/11/06 Javascript
微信小程序获取用户信息的两种方法wx.getUserInfo与open-data实例分析
2019/05/03 Javascript
5个你不知道的JavaScript字符串处理库(小结)
2020/06/01 Javascript
微信小程序 接入腾讯地图的两种写法
2021/01/12 Javascript
理解python多线程(python多线程简明教程)
2014/06/09 Python
Python中实现常量(Const)功能
2015/01/28 Python
利用python批量给云主机配置安全组的方法教程
2017/06/21 Python
python实现kNN算法
2017/12/20 Python
Pandas中Series和DataFrame的索引实现
2019/06/27 Python
什么是反射?如何实现反射?
2016/07/25 面试题
生产文员岗位职责
2014/04/05 职场文书
毕业评语大全
2014/05/04 职场文书
授权委托书
2014/07/31 职场文书
四风查摆剖析材料
2014/10/10 职场文书
夫妻双方自愿离婚协议书
2014/10/24 职场文书
五一劳动节慰问信
2015/02/14 职场文书
2015年上半年计生工作总结
2015/03/30 职场文书
2015医院个人工作总结范文
2015/05/21 职场文书
详解Python类和对象内容
2021/06/22 Python
MySQL 原理优化之Group By的优化技巧
2022/08/14 MySQL