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

在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库的多个相对独立的文件中:
//jsLib
var 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加密等等,有兴趣的朋友可以找相关资料自行研究。

(0)

相关推荐

  • JavaScript 布尔操作符解析 && || !

    1.逻辑非 逻辑非用!表示,可以应用与ECMAScript的任何类型的值,逻辑非操作返回的是一个布尔值(true/false).该操作符首先会将它的操作数转换为一个布尔值,然后再对其求反. 下面说明下Boolean()转型函数的一组规则. 数据类型 转换为true的值 转换为false的值 Boolean true false String 任何非空字符串 ""(空字符串) Number 任何非零数字值(包括无穷大) 0和NaN Object 任何对象 null Undefined  

  • JavaScript中的操作符类型转换示例总结

    首先,我们先来做一些题目吧!为了统一,我不混着来写这些题目,面试题目中,经常将这些题目混起来,这样对你的迷惑度会更大,为了更方便演示,我在这里分模块写了一些题目,大家可以看下! 操作符字符串的隐性转换  乘法 console.dir("-------以下乘法---------"); console.dir(5*"5"); console.dir(5*"a"); console.dir(5*NaN); console.dir(5*null); co

  • JavaScript delete操作符应用实例

    今天在看prototype代码时发现了delete这个操作符 复制代码 代码如下: unset: function(key) { var value = this._object[key]; delete this._object[key]; return value; } 查了一下手册, delete 运算符 从对象中删除一个属性,或从数组中删除一个元素. delete expression expression 参数是一个有效的 JScript 表达式,通常是一个属性名或数组元素. 说明 如

  • JS 操作符整理[推荐收藏]

    Arithmetic Operators算术运算符 Operator Description Example Result + Addition 加 x=2y=2x+y 4 - Subtraction 减 x=5y=2x-y 3 * Multiplication 乘 x=5y=4x*y 20 / Division 除 15/55/2 32.5 % Modulus (division remainder) 余数 5%210%810%2 120 ++ Increment递增 x=5x++ x=6 -

  • 用方法封装javascript的new操作符(一)

    先看个例子: 复制代码 代码如下: var Class = { create : function () { return function () { this.initialize.apply(this, arguments); } } } var A = Class.create(); A.prototype = { initialize:function(){ //todo } test:"abc" } var a = new A(); 这是很多jser构建类和实例化对象的过程,

  • 解析JavaScript中delete操作符不能删除的对象

    ES3 中,delete在8.6.2.5及11.4.1有介绍,如下 有一些信息, 1.实现上delete操作符会调用引擎内部的[[Delete]]方法 2.[[Delete]]在8.6.2里定义 3.删除的属性有个DontDelete的特性,如果有,delete时直接返回false 搜索"DontDelete",会发现有很多,如下都不能delete 1, 激活对象的arguments对象 (10.1.6) 复制代码 代码如下: function func() {     delete

  • js 操作符实例代码

    复制代码 代码如下: var $mfunc=function(){ return { //此函数判断浏览器类型,为了简便,返回一个数字表示, //1.ie6;2.ie7; 3.ie8;4.ie5.5;5,Firefox;6.chrome;7.Opera;8.Safari;0.无法检测的浏览器 //其他浏览器可以自行添加 whichOS:function(){ var useragent=navigator.userAgent.toLowerCase(); return (/MSIE 6/i.te

  • javascript中加号(+)操作符的一些神奇作用

    javascript是一门神奇的语言,这没神奇的语言中有一个神奇的加操作符. 常用的加操作符我们可以用来做: 1.加法运算,例如:alert(1+2); ==>32.字符串连接,例如:alert("a"+"b");==>"ab" 高级一点的还有"+=",也是做以上两种操作的. 昨天在javascript丛林群里问了问题:怎么把"2000-09-11 19:22"这个日期格式字符串转换成毫秒数?

  • JS中==与===操作符的比较

    ===操作符: 要是两个值类型不同,返回false 要是两个值都是number类型,并且数值相同,返回true 要是两个值都是stirng,并且两个值的String内容相同,返回true 要是两个值都是true或者都是false,返回true 要是两个值都是指向相同的Object,Arraya或者function,返回true 要是两个值都是null或者都是undefined,返回true ==操作符: 如果两个值具有相同类型,会进行===比较,返回===的比较值 如果两个值不具有相同类型,也有

  • javascript高级程序设计(第三版)学习笔记(一) 正则表达式整理

    1.创建正则表达式 第一种方式:注意这里的正则表达式不能使用单引号或者双引号,如下 var pattern1 = /[abc]/i; // 匹配第一个"a"或"b"或"c",不区分大小写 第二种方式:使用RegExp构造函数创建,该构造函数传入两个参数,都是字符串,所以需要特别注意"\"符号的转换,所有元字符(下面有讲元字符)需要双重转义,如下 复制代码 代码如下: var patt1 = new RegExp("[

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

    在ECMAScript中,有非常丰富的运算符和操作符,在这篇文章中将按通常的分类来稍微整理一下,不过在整理之前,先说明一下: 1.虽然标题是运算符和操作符,然而在我看来并没有多少严格区分的必要,在英文中,貌似也是用一个Operator来表示,所以在下文中我可能会混用.甚至,一些不属于运算符和操作符范畴的,我也整理在这里,只要我觉得必要. 2.对于运算符的优先级,你无需一一牢记--我相信你知道最简单的"先乘除,后加减",至于其它的,如果你不确定,加上括号好了.在ECMAScript中,优

  • JavaScript高级程序设计 XML、Ajax 学习笔记

    第十五章 JavaScript与XML 1.浏览器对XML DOM的支持 1.1 DOM2级核心 ①在DOM2级在document.implementation中引入了createDocument()方法(IE6~8不支持). 可以创建一个空白XML. var xmldom = document.implemention.createDocument(namespaceUri,root,docype); ②要创建一个新的文档元素为<root>的XML文档,可用如下代码: var xmldom

  • JavaScript面向对象知识串结(读JavaScript高级程序设计(第三版))

    第一遍囫囵吞枣,不求甚解,感觉恍然大悟,结果晚上睡觉一想发现很多问题,什么都不明白,再看第二遍,发现原来是这样.过了几天一用,发现手写起来原来还是在凭记忆,于是下一遍,下一遍... 单凭记忆去弄清楚东西很不靠谱,时间一长脑袋空白.特别是技术上的很多思想和原理,只看不练,即便当时想得特别清楚,过久了也会忘.再者就是网上一些东西,只能说是提供了一种便捷的查看途径,事后还是自己总结为好,毕竟大多都是个人总结,一些概念很难讲的很清楚,而且两个人谈同一件事情,一般说的步骤和章节都是不同的,这样很容易形成交

  • JavaScript高级程序设计(第3版)学习笔记6 初识js对象

    在房子里面可以放你想放的任意事物--如果你有足够的美学造诣,你甚至可以弄一个房中房试试--当然,为了方便管理,我们会给房子里存放的所有事物都会取上一个不重复的名字,比如医药房间里的各种药品名称.在ECMAScript中,你可以在对象中存放任意你想放的数据,同样,我们需要给存放的数据取一个名字--也就是对象的属性名,再存放各种数据.再看看ECMA-262中对象的定义:无序属性的集合,其属性可以包含简单数据类型值.对象或者函数. 进入对象,我开始有些激动了,说实话,让我想起做这系列学习笔记的最初原因

  • JavaScript高级程序设计(第3版)学习笔记 概述

    在JavaScript面世之初,没有人会想到它会被应用的如此广泛,也远比一般人想象中的要复杂强大的多,在我自己学习的过程中,曾经有过多次震撼,只是常常没有过多久,很多美轮美奂的用法就又模糊起来,希望通过对JavaScript高级程序设计(第3版)的专题学习笔记,能够较为系统的将基础知识梳理一次,也能够将自己平常学习与工作过程中遇到的一些美妙用法记录下来,便于自己再次学习,当然,也希望可以给有需要的朋友们一些力所能及的帮助. 相关术语 先简要说一下和JavaScript相关的一些背景术语,就不详细

  • JavaScript高级程序设计(第三版)学习笔记1~5章

    第2章,在html中使用JavaScript Html引入外部js脚本 <script type="text/javascript" src="test.js">两个</script>之间不应放脚本,因为并不会被执行</script> <script>标签有一个defer属性可以延迟脚本执行,但是并不保证会按脚本排列顺序执行 建议:将脚本引入放在<body>标签的所有内容之后,而不放在<head>

  • JavaScript高级程序设计(第三版)学习笔记6、7章

    第6章,面向对象的程序设计 对象: 1.数据属性 configurable,表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或能否把属性修改为访问器属性,默认为true enumerbale,表示能否通过for-in访问属性,默认true ƒwritable,表示能否修改属性值,默认true „value,数据存储位置,默认undefined 修改默认属性特性:Object.defineProperty(),接收三个参数:属性所在对象,属性名,描述符对象,描述符对象属性必

  • JavaScript高级程序设计(第3版)学习笔记3 js简单数据类型

    ECMAScript是一种动态类型的语言,构建于5种简单数据类型(Undefined.Null.Boolean.Number.String)和一种复杂数据类型(Object)的基础之上.这篇文章就来复习一下简单数据类型,我会尽量从编程实践的角度来描述,下面代码运行环境为FireFox 14.0.1. 简单数据类型 简单数据类型 取值 Undefined undefined(只有一个值) Null null(只有一个值) Boolean true|false(只有两个值) Number 数值 St

  • JavaScript高级程序设计(第3版)学习笔记8 js函数(中)

    6.执行环境和作用域 (1)执行环境(execution context):所有的JavaScript代码都运行在一个执行环境中,当控制权转移至JavaScript的可执行代码时,就进入了一个执行环境.活动的执行环境从逻辑上形成了一个栈,全局执行环境永远是这个栈的栈底元素,栈顶元素就是当前正在运行的执行环境.每一个函数都有自己的执行环境,当执行流进入一个函数时,会将这个函数的执行环境压入栈顶,函数执行完之后再将这个执行环境弹出,控制权返回给之前的执行环境. (2)变量对象(variable ob

随机推荐