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的模块化:封装(闭包),继承(原型) 介绍
Jul 22 Javascript
转换字符串为json对象的方法详解
Nov 29 Javascript
html的DOM中document对象forms集合用法实例
Jan 21 Javascript
JavaScript中逗号运算符介绍及使用示例
Mar 13 Javascript
jquery表单验证插件(jquery.validate.js)的3种使用方式
Mar 28 Javascript
JavaScript实现图片滑动切换的代码示例分享
Mar 06 Javascript
基于BootStarp的Dailog
Apr 28 Javascript
jquery的checkbox,radio,select等方法小结
Aug 30 Javascript
原生javascript实现图片放大镜效果
Jan 18 Javascript
js实现倒计时效果(小于10补零)
Mar 08 Javascript
vue中实现拖动调整左右两侧div的宽度的示例代码
Jul 22 Javascript
关于JS中的作用域中的问题思考分享
Apr 06 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
php通过rmdir删除目录的简单用法
2015/03/18 PHP
php JWT在web端中的使用方法教程
2018/09/06 PHP
更正确的asp冒泡排序
2007/05/24 Javascript
jQuery探测位置的提示弹窗(toolTip box)详细解析
2013/11/14 Javascript
jquery防止重复执行动画避免页面混乱
2014/04/22 Javascript
使用JavaScript 实现的人脸检测
2015/03/24 Javascript
JavaScript实现的背景自动变色代码
2015/10/17 Javascript
jQuery动态添加可拖动元素完整实例(附demo源码下载)
2016/06/21 Javascript
Canvas实现放射线动画效果
2017/02/15 Javascript
HTML中使背景图片自适应浏览器大小实例详解
2017/04/06 Javascript
jQuery结合jQuery.cookie.js插件实现换肤功能示例
2017/10/14 jQuery
element-ui循环显示radio控件信息的方法
2018/08/24 Javascript
Vue入门学习笔记【基本概念、对象、过滤器、指令等】
2019/04/13 Javascript
使用React手写一个对话框或模态框的方法示例
2019/04/25 Javascript
JS实现横向跑马灯效果代码
2020/04/20 Javascript
vue scroll滚动判断的实现(是否滚动到底部、滚动方向、滚动节流、获取滚动区域dom元素)
2020/06/11 Javascript
详解Typescript里的This的使用方法
2021/01/08 Javascript
vue3.0 项目搭建和使用流程
2021/03/04 Vue.js
[48:24]完美世界DOTA2联赛循环赛LBZS vs Forest 第一场 10月30日
2020/10/31 DOTA
Python合并多个装饰器小技巧
2015/04/28 Python
使用PyCharm配合部署Python的Django框架的配置纪实
2015/11/19 Python
python中import学习备忘笔记
2017/01/24 Python
Python列表list解析操作示例【整数操作、字符操作、矩阵操作】
2017/07/25 Python
Python使用Tkinter实现机器人走迷宫
2018/01/22 Python
python 将数据保存为excel的xls格式(实例讲解)
2018/05/03 Python
Python Datetime模块和Calendar模块用法实例分析
2019/04/15 Python
基于django传递数据到后端的例子
2019/08/16 Python
python 图片二值化处理(处理后为纯黑白的图片)
2019/11/01 Python
关于Tensorflow使用CPU报错的解决方式
2020/02/05 Python
英国皇室御用百货:福南梅森(Fortnum & Mason)
2017/12/03 全球购物
Holland & Barrett爱尔兰:英国领先的健康零售商
2019/03/31 全球购物
函授自我鉴定范文
2014/02/06 职场文书
民事代理词范文
2015/05/25 职场文书
增值税发票丢失证明
2015/06/19 职场文书
MySQL EXPLAIN输出列的详细解释
2021/05/12 MySQL
Python中for后接else的语法使用
2021/05/18 Python