第三章:基本概念(操作符)

来源:互联网 发布:opt最优化理论 编辑:程序博客网 时间:2024/06/16 12:46

  • 操作符
    • 递增和递减操作符
    • 一元加和减操作符
    • 位操作符
      • 按位非
      • 按位与
      • 按位或
      • 按位异或
      • 左移
      • 右移有符号右移无符号右移
    • 布尔操作符
    • 乘性操作符
    • 加性操作符
      • 加法
      • 减法操作符
    • 关系比较符
    • 相等操作符
      • 相等和不相等
      • 全等和不全等
    • 条件操作符
    • 赋值操作符
    • 逗号操作符

操作符

  • 定义:操作符能用于操作数据值,包括算术运算符、位操作符、关系操作符和相等操作符。操作符能适用于很多值,例如字符串、数字值、布尔值,甚至对象。在应用于对象时,相应的操作符通常会调用对象的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;     //value 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。那么也会返回第二个操作数的原型。所以总结下来就是( 以下是我的个人总结,如有不对欢迎指出。):
    1. 第一个操作数使用Boolean()计算是false,则返回第一个操作数原型。
    2. 第一个操作数使用Boolean()计算是true,则返回第二个操作数原型。
  • 逻辑或(||):有两个操作数。在有一个操作数不是布尔值的时候,其返回结果就不一定是布尔值。类比上面的逻辑与操作符有总结如下:
    1. 第一个操作数使用Boolean()计算是true,则返回第一个操作数原型。
    2. 第一个操作数使用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:
    1. Infinity * Infinity = Infinity
    2. Infinity / Infinity = NaN
    3. Infinity % Infinity = NaN
    4. 10 / Infinity = 0
    5. 10 / 0 = Infinity
    6. 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)

关系比较符(>, <, >=, <=)

  1. 如果两个操作数都是数值,执行数字比较。
  2. 如果都是字符串,比较对应的字符编码值。(按高到低)
  3. 如果一个是数值,则将另外一个操作数通过Number()转换为数值进行比较。
  4. 如果一个操作数是对象,调用valueOf方法。如果没有valueOf方法则调用toString()方法。再按照前三条规则比较。
  5. 如果是布尔值则通过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

相等操作符

相等和不相等(==, !=)

  1. 如果一个操作数是布尔值,先转成数值再进行比较。
  2. 如果一个是字符串,一个是数值,则将字符串转成数值比较(可能得到NaN)。
  3. 如果一个是对象,一个不是,则调用该对象的valueOf方法(如果valueOf返回的还是对象则调用toString),通过返回的值的类型再按照上面规则进行比较。
  4. null 和 undefined相等,且不能将其转换成其他值。
  5. 如果操作数中有NaN, 相等永远为false。不等永远为true。(NaN != NaN)
  6. 如果都是对象,则比较他们是不是同一个对象。如果指向同一个对象返回true。

全等和不全等(===, !==)

  • 全等比较符除了在比较前不转换类型外,其他都与相等操作符一样。(null !== undefined)

条件操作符

  • 和java中一样。例如:
    var max = (num1 > num2) ? num1 : num2;

赋值操作符

  • 此处简单略过,使用类似 += -=其实主要目的是简化赋值操作。不会带来性能的提升。有以下几个赋值操作:
    1. *=
    2. /=
    3. %=
    4. +=
    5. -=
    6. <<=
    7. >>=
    8. >>>=

逗号操作符

  • 使用逗号操作符多用于声明多个变量。除此之外,逗号操作符还可以用于赋值。用于赋值时,逗号操作符总会返回表达式中的最后一项。例子如下:
    var num1=1, num2=2, num3=3;    var num = (1, 2, 3, 4, 5);//num最终为5
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 车辆年审过期2天怎么办 违停单子丢了怎么办 沙发弹簧包坏了怎么办 bt种子被和谐了怎么办 苹果手机id密码忘了怎么办 墙漆颜色太深了怎么办 油漆颜色太深了怎么办 墙面漆颜色太深怎么办 古代打仗牙掉了怎么办 乐视电视没声音怎么办 老公疑心病很重怎么办啊 被安装了尿道锁怎么办 狼青小狗腿罗圈怎么办 备孕期间有霉菌怎么办 虫子进皮肤里了怎么办 生完孩子肚子越来越大怎么办 怀孕8个月肚子小怎么办 孕晚期胎儿不长怎么办 肚子上肉特别多怎么办 奶堵了有硬块怎么办 便秘5天肚子胀怎么办 上火大便拉不出来怎么办 大便拉不出来肚子痛怎么办 戒奶奶涨有硬块怎么办 忌奶的时候涨奶怎么办 娃儿隔奶,,奶涨怎么办 狗肚子很大很鼓怎么办 注册不了的二建怎么办 专升本没考过怎么办 警察乱拘留人该怎么办 玩英雄联盟太卡怎么办 一方离婚证丢了怎么办 遭遇呼死你软件怎么办 开车遇见碰瓷的怎么办 遇到碰瓷老人的怎么办 睿强遥控锁坏了怎么办 地暖分水器坏了怎么办 京东赠品无货怎么办 图书馆的书丢了怎么办 三次临牌用完了怎么办 m3u8文件只有10k怎么办