• JS 运算符和流程控制


    一、操作符

    1.一元操作符

    自加自减操作符

    前置型

    执行前置递增和递减操作时,变量的值都是在语句被求值以前改变的 

    var num1 = 2;
    var num2 = 20;
    var num3 = --num1 + num2; // 等于 21
    var num4 = num1 + num2; // 等于 21

    后置型

    把递增操作符放在变量后面并不会改变语句的结果 

    var num1 = 2;
    var num2 = 20;
    var num3 = num1-- + num2; // 等于 22
    var num4 = num1 + num2; // 等于 21

    在应用于一个包含有效数字字符的字符串时,先将其转换为数字值,再执行加减 1 的操作。字
    符串变量变成数值变量。
     在应用于一个不包含有效数字字符的字符串时,将变量的值设置为 NaN(第 4 章将详细讨论)。
    字符串变量变成数值变量。
     在应用于布尔值 false 时,先将其转换为 0 再执行加减 1 的操作。布尔值变量变成数值变量。
     在应用于布尔值 true 时,先将其转换为 1 再执行加减 1 的操作。布尔值变量变成数值变量。
     在应用于浮点数值时,执行加减 1 的操作。
     在应用于对象时,先调用对象的 valueOf()方法(第 5 章将详细讨论)以取得一个可供操作的
    值。然后对该值应用前述规则。如果结果是 NaN,则在调用 toString()方法后再应用前述规
    则。对象变量变成数值变量

    var s1 = "2";
    var s2 = "z";
    var b = false;
    var f = 1.1;
    var o = {
    valueOf: function() {
    return -1;
    }
    };
    s1++; // 值变成数值 3
    s2++; // 值变成 NaN
    b++; // 值变成数值 1
    f--; // 值变成 0.10000000000000009(由于浮点舍入错误所致)
    o--; // 值变成数值-2 

    加和减操作符

    一元加操作符以一个加号(+)表示,放在数值前面,对数值不会产生任何影响,

    var num = 25;
    num = +num; // 仍然是 25

    不过,在对非数值应用一元加操作符时,该操作符会像 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; // 值变成数值 1
    s2 = +s2; // 值变成数值 1.1
    s3 = +s3; // 值变成 NaN
    b = +b; // 值变成数值 0
    f = +f; // 值未变,仍然是 1.1
    o = +o; // 值变成数值-1

    一元减操作符主要用于表示负数

    var num = 25;
    num = -num; // 变成了-25

    当应用于非数值时,一元减操作符遵循与一元加操作符相同的规则,最后再将得到的数值转换为负数 

    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; // 值变成了数值-1
    s2 = -s2; // 值变成了数值-1.1
    s3 = -s3; // 值变成了 NaN
    b = -b; // 值变成了数值 0
    f = -f; // 变成了-1.1
    o = -o; // 值变成了数值 1

    2.位操作符

    暂略

    3.布尔操作符

    逻辑非(!)

    无论这个值是什么数据类型,这个操作符都会返回一个布尔值。逻辑非操作符首先会将它的操作数转换为一个布尔值,然后再对其求反

     如果操作数是一个对象,返回 false;
     如果操作数是一个空字符串,返回 true;
     如果操作数是一个非空字符串,返回 false;
     如果操作数是数值 0,返回 true;
     如果操作数是任意非 0 数值(包括 Infinity),返回 false;
     如果操作数是 null,返回 true;
     如果操作数是 NaN,返回 true;
     如果操作数是 undefined,返回 true。

    alert(!false); // true
    alert(!"blue"); // false
    alert(!0); // true
    alert(!NaN); // true
    alert(!""); // true
    alert(!12345); // false

    同时使用两个逻辑非操作符,实际上就会模拟 Boolean()转型函数的行为

    alert(!!"blue"); //true
    alert(!!0); //false
    alert(!!NaN); //false
    alert(!!""); //false
    alert(!!12345); //true

    逻辑与(&&)

    逻辑与操作可以应用于任何类型的操作数,而不仅仅是布尔值

    如果第一个操作数是对象,则返回第二个操作数;
    如果第二个操作数是对象,则只有在第一个操作数的求值结果为 true 的情况下才会返回该
    对象;
    如果两个操作数都是对象,则返回第二个操作数;
    如果有一个操作数是 null,则返回 null
    如果有一个操作数是 NaN,则返回 NaN
    如果有一个操作数是 undefined,则返回 undefined

     

     如果第一个操作数是 false,则无论第二个操作数是什么值,结果都不再可能是true 了

    var found = true;
    var result = (found && someUndefinedVariable); // 这里会发生错误
    alert(result); // 这一行不会执行
    var found = false;
    var result = (found && someUndefinedVariable); // 不会发生错误
    alert(result); // 会执行( "false")

    逻辑或

    与逻辑与操作相似,如果有一个操作数不是布尔值,逻辑或也不一定返回布尔值

    如果第一个操作数是对象,则返回第一个操作数;
    如果第一个操作数的求值结果为 false,则返回第二个操作数;
    如果两个操作数都是对象,则返回第一个操作数;
    如果两个操作数都是 null,则返回 null
    如果两个操作数都是 NaN,则返回 NaN
    如果两个操作数都是 undefined,则返回 undefined

    与逻辑与操作符相似,逻辑或操作符也是短路操作符。也就是说,如果第一个操作数的求值结果为
    true,就不会对第二个操作数求值了

    var found = true;
    var result = (found || someUndefinedVariable); // 不会发生错误
    alert(result); // 会执行( "true")

    4.乘性操作符

    乘法

    var result = 34 * 56;

    在处理特殊值的情况下,乘法操作符遵循下列特殊的规则:
     如果操作数都是数值,执行常规的乘法计算,即两个正数或两个负数相乘的结果还是正数,而
    如果只有一个操作数有符号,那么结果就是负数。如果乘积超过了 ECMAScript 数值的表示范围,
    则返回 Infinity 或-Infinity;
     如果有一个操作数是 NaN,则结果是 NaN;
     如果是 Infinity 与 0 相乘,则结果是 NaN;
     如果是 Infinity 与非 0 数值相乘,则结果是 Infinity 或-Infinity,取决于有符号操作数
    的符号;
     如果是 Infinity 与 Infinity 相乘,则结果是 Infinity;
     如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值,然后再应用上面的
    规则。

    除法

    var result = 66 / 11;

     如果操作数都是数值,执行常规的除法计算,即两个正数或两个负数相除的结果还是正数,而
    如果只有一个操作数有符号,那么结果就是负数。如果商超过了 ECMAScript 数值的表示范围,
    则返回 Infinity 或-Infinity;
     如果有一个操作数是 NaN,则结果是 NaN;
     如果是 Infinity 被 Infinity 除,则结果是 NaN;
     如果是零被零除,则结果是 NaN;
     如果是非零的有限数被零除,则结果是 Infinity 或-Infinity,取决于有符号操作数的符号;
     如果是 Infinity 被任何非零数值除,则结果是 Infinity 或-Infinity,取决于有符号操作
    数的符号;

     如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值,然后再应用上面的规则。

    求余

    var result = 26 % 5; // 等于 1

    与另外两个乘性操作符类似,求模操作符会遵循下列特殊规则来处理特殊的值:
    如果操作数都是数值,执行常规的除法计算,返回除得的余数;
    如果被除数是无穷大值而除数是有限大的数值,则结果是 NaN
    如果被除数是有限大的数值而除数是零,则结果是 NaN
    如果是 Infinity Infinity 除,则结果是 NaN
    如果被除数是有限大的数值而除数是无穷大的数值,则结果是被除数;
    如果被除数是零,则结果是零;
    如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值,然后再应用上面的规则

    5.加性操作符

    var result = 1 + 2;

    如果有一个操作数是 NaN,则结果是 NaN
    如果是 Infinity Infinity,则结果是 Infinity
    如果是-Infinity -Infinity,则结果是-Infinity
    如果是 Infinity -Infinity,则结果是 NaN
    如果是+0 +0,则结果是+0
    如果是0 0,则结果是0
    如果是+0 0,则结果是+0
    不过,如果有一个操作数是字符串,那么就要应用如下规则:
    如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来;
    如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接
    起来。

    如果有一个操作数是对象、数值或布尔值,则调用它们的 toString()方法取得相应的字符串值,
    然后再应用前面关于字符串的规则。对于 undefined null,则分别调用 String()函数并取得字符
    "undefined""null"

    var result1 = 5 + 5; // 两个数值相加
    alert(result1); // 10
    var result2 = 5 + "5"; // 一个数值和一个字符串相加
    alert(result2); // "55"
    var num1 = 5;
    var num2 = 10;
    var message = "The sum of 5 and 10 is " + num1 + num2;
    alert(message); // "The sum of 5 and 10 is 510"
    var num1 = 5;
    var num2 = 10;
    var message = "The sum of 5 and 10 is " + (num1 + num2);
    alert(message); //"The sum of 5 and 10 is 15"

    减法

    var result = 2 - 1;

    如果两个操作符都是数值,则执行常规的算术减法操作并返回结果;
    如果有一个操作数是 NaN,则结果是 NaN
    如果是 Infinity Infinity,则结果是 NaN
    如果是-Infinity -Infinity,则结果是 NaN
    如果是 Infinity -Infinity,则结果是 Infinity
    如果是-Infinity Infinity,则结果是-Infinity
    如果是+0 +0,则结果是+0
    如果是+0 0,则结果是0

    如果是0 0,则结果是+0
    如果有一个操作数是字符串、布尔值、 null undefined,则先在后台调用 Number()函数将
    其转换为数值,然后再根据前面的规则执行减法计算。如果转换的结果是 NaN,则减法的结果
    就是 NaN
    如果有一个操作数是对象,则调用对象的 valueOf()方法以取得表示该对象的数值。如果得到
    的值是 NaN,则减法的结果就是 NaN。如果对象没有 valueOf()方法,则调用其 toString()
    方法并将得到的字符串转换为数值

    var result1 = 5 - true; // 4,因为 true 被转换成了 1
    var result2 = NaN - 1; // NaN
    var result3 = 5 - 3; // 2
    var result4 = 5 - ""; // 5,因为"" 被转换成了 0
    var result5 = 5 - "2"; // 3,因为"2"被转换成了 2
    var result6 = 5 - null; // 5,因为 null 被转换成了 0

     

    6.关系操作符

    小于(<) 、大于(>) 、小于等于(<=)和大于等于(>=)再应用上面的规则。这几个操作符都返回一个布尔值

    var result1 = 5 > 3; //true
    var result2 = 5 < 3; //false

    如果两个操作数都是数值,则执行数值比较。
    如果两个操作数都是字符串,则比较两个字符串对应的字符编码值。
    如果一个操作数是数值,则将另一个操作数转换为一个数值,然后执行数值比较。
    如果一个操作数是对象,则调用这个对象的 valueOf()方法,用得到的结果按照前面的规则执
    行比较。如果对象没有 valueOf()方法,则调用 toString()方法,并用得到的结果根据前面
    的规则执行比较。
    如果一个操作数是布尔值,则先将其转换为数值,然后再执行比较。

     

    在比较字符串时,实际比较的是两个字符串中对应位置的每个字符的字符编码值。经过这么一番比较之后,再返回一个布尔值 

    var result = "Brick" < "alphabet"; //true
    var result = "23" < "3"; //true

    在比较数值和字符串时,字符串都会被转换成数值,然后再以数值方式与另一个数值比较

    var result = "23" < 3; //false

    如果那个字符串不能被转换成一个合理的数值

    var result = "a" < 3; // false,因为"a"被转换成了 NaN

    任何操作数与 NaN 进行关系比较,结果都是 false

    var result1 = NaN < 3; //false
    var result2 = NaN >= 3; //false

    7.相等操作符

    相等和不相等

    如果两个操作数相等,则返回 true ,两个操作数不相等,则返回 false

    两个操作符都会先转换操作数(通常称为强制转型),然后再比较它们的相等性 

    在转换不同的数据类型时的基本规则 :

    如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false 转换为 0,而
    true 转换为 1

    如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值;
    如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf()方法,用得到的基本类
    型值按照前面的规则进行比较;
    这两个操作符在进行比较时则要遵循下列规则。
    null undefined 是相等的。
    要比较相等性之前,不能将 null undefined 转换成其他任何值。
    如果有一个操作数是 NaN,则相等操作符返回 false,而不相等操作符返回 true。重要提示:
    即使两个操作数都是 NaN,相等操作符也返回 false;因为按照规则, NaN 不等于 NaN
    如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,
    则相等操作符返回 true;否则,返回 false

     全等和不全等

    除了在比较之前不转换操作数之外,全等和不全等操作符与相等和不相等操作符没有什么区别。全等操作符由 3 个等于号(===)表示,它只在两个操作数未经转换就相等的情况下返回 true

    var result1 = ("55" == 55); //true,因为转换后相等
    var result2 = ("55" === 55); //false,因为不同的数据类型不相等
    var result1 = ("55" != 55); //false,因为转换后相等
    var result2 = ("55" !== 55); //true,因为不同的数据类型不相等

    ***  null == undefined 会返回 true,因为它们是类似的值;但 null === undefined 会返回 false,因为它们是不同类型的值

    8.条件操作符

    var max = (num1 > num2) ? num1 : num2;

    如果num1 > num2 为真,返回num1

    如果num1 > num2 为假,返回num2

    9.赋值操作符

    如果在等于号(=)前面再添加乘性操作符、加性操作符或位操作符,就可以完成复合赋值操作

    num += 10;
    //相当于
    num = num + 10;

     乘/赋值(*=);
     除/赋值(/=);
     模/赋值(%=);
     加/赋值(+=);
     减/赋值(=);
     左移/赋值(<<=);
     有符号右移/赋值(>>=)
     无符号右移/赋值(>>>=)

    10.逗号操作符

    使用逗号操作符可以在一条语句中执行多个操作

    var num1=1, num2=2, num3=3;

     

    在用于赋值时,逗号操作符总会返回表达式中的最后一项 

    var num = (5, 1, 4, 8, 0); // num 的值为 0

    虽然逗号的这种使用方式并不常见,但这个例子可以帮我们理解逗号的这种行为

    二、流程控制

    1.if语句

    if (i > 25) {
    alert("Greater than 25.");
    } else if (i < 0) {
    alert("Less than 0.");
    } else {
    alert("Between 0 and 25, inclusive.");
    }

    2.do-while语句

    var i = 0;
    do {
    i += 2;
    } while (i < 10);
    alert(i);

    3.while语句

    var i = 0;
    while (i < 10) {
    i += 2;
    }

    4.for语句

    var count = 10;
    for (var i = 0; i < count; i++){
    alert(i);
    }

    5.for in 语句

    for-in 语句是一种精准的迭代语句,可以用来枚举对象的属性

    for (var propName in window) {
    document.write(propName);
    }

    使用 for-in 循环来显示了 BOM window 对象的所有属性

    6.label语句

    使用 label 语句可以在代码中添加标签,当break label 或 continue label  会跳到标签位置

    start: for (var i=0; i < count; i++) {
    alert(i);
    }

    这个例子中定义的 start 标签可以在将来由 break continue 语句引用。加标签的语句一般都
    要与 for
    语句等循环语句配合使用

    7.break和continue语句

    break跳出本层循环

    var num = 0;
    for (var i=1; i < 10; i++) {
    if (i % 5 == 0) {
    break;
    }
    num++;
    }
    alert(num); //4

    continue跳出本次循环

    var num = 0;
    for (var i=1; i < 10; i++) {
    if (i % 5 == 0) {
    continue;
    }
    num++;
    }
    alert(num); //8

    配合label使用

    var num = 0;
    outermost:
    for (var i=0; i < 10; i++) {
    for (var j=0; j < 10; j++) {
    if (i == 5 && j == 5) {
    break outermost;
    }
    num++;
    }
    }
    alert(num); //55

    建议如果使用 label 语句,一定要使用描述性的标签,同时不要嵌套过多的循环

    8.with语句

    不建议使用

    9.switch语句

    switch (i) {
    case 25:
    alert("25");
    break;
    case 35:
    alert("35");
    break;
    case 45:
    alert("45");
    break;
    default:
    alert("Other");
    }
    合并两种情形
    switch (i) {
    case 25:
    /* 合并两种情形 */
    case 35:
    alert("25 or 35");
    break;
    case 45:
    alert("45");
    break;
    default:
    alert("Other");
    }
    var num = 25;
    switch (true) {
    case num < 0:
    alert("Less than 0.");
    break;
    case num >= 0 && num <= 10:
    alert("Between 0 and 10.");
    break;
    case num > 10 && num <= 20:
    alert("Between 10 and 20.");
    break;
    default:
    alert("More than 20.");
    }

    三、函数

    定义函数

    function sayHi(name, message) {
    alert("Hello " + name + "," + message);
    }

     调用函数

    sayHi("Nicholas", "how are you today?");

    ECMAScript 中的函数在定义时不必指定是否返回值

    理解参数

    ECMAScript 函数的参数与大多数其他语言中函数的参数有所不同。 ECMAScript 函数不介意传递进
    来多少个参数,也不在乎传进来参数是什么数据类型。也就是说,即便你定义的函数只接收两个参数,
    在调用这个函数时也未必一定要传递两个参数。可以传递一个、三个甚至不传递参数,而解析器永远不
    会有什么怨言。之所以会这样,原因是 ECMAScript 中的参数在内部是用一个数组来表示的。函数接收
    到的始终都是这个数组,而不关心数组中包含哪些参数(如果有参数的话)。如果这个数组中不包含任
    何元素,无所谓;如果包含多个元素,也没有问题。实际上,在函数体内可以通过 arguments 对象来
    访问这个参数数组,从而获取传递给函数的每一个参数。
    其实, arguments 对象只是与数组类似(它并不是 Array 的实例),因为可以使用方括号语法访
    问它的每一个元素(即第一个元素是 arguments[0],第二个元素是 argumetns[1],以此类推),使
    length 属性来确定传递进来多少个参数。在前面的例子中, sayHi()函数的第一个参数的名字叫
    name,而该参数的值也可以通过访问 arguments[0]来获取。因此,那个函数也可以像下面这样重写,
    即不显式地使用命名参数:

    function sayHi() {
    alert("Hello " + arguments[0] + "," + arguments[1]);
    }
    FunctionExample05.

    这个重写后的函数中不包含命名的参数。虽然没有使用 name message 标识符,但函数的功能
    依旧。这个事实说明了 ECMAScript 函数的一个重要特点:命名的参数只提供便利,但不是必需的。另
    外,在命名参数方面,其他语言可能需要事先创建一个函数签名,而将来的调用必须与该签名一致。但
    ECMAScript 中,没有这些条条框框,解析器不会验证命名参数。

    通过访问 arguments 对象的 length 属性可以获知有多少个参数传递给了函数。下面这个函数会
    在每次被调用时,输出传入其中的参数个数:

    function howManyArgs() {
    alert(arguments.length);
    }
    howManyArgs("string", 45); //2
    howManyArgs(); //0
    howManyArgs(12); //1
    function doAdd() {
    if(arguments.length == 1) {
    alert(arguments[0] + 10);
    } else if (arguments.length == 2) {
    alert(arguments[0] + arguments[1]);
    }
    }
    doAdd(10); //20
    doAdd(30, 20); //50

    没有重载

     如果在 ECMAScript 中定义了两个名字相同的函数,则该名字只属于后定义的函数

    function addSomeNumber(num){
    return num + 100;
    }
    function addSomeNumber(num) {
    return num + 200;
    }
    var result = addSomeNumber(100); //300
  • 相关阅读:
    笨办法学习python之hashmap
    python实现三级菜单源代码
    ql的python学习之路-day3
    ql的python学习之路-day2
    Spring的数据库开发
    Spring学习之Aspectj开发实现AOP
    spring学习之依赖注入DI与控制反转IOC
    spring学习之第一个spring程序
    spring学习之spring入门
    Java线程(一)——创建线程的两种方法
  • 原文地址:https://www.cnblogs.com/buchizaodian/p/7106833.html
Copyright © 2020-2023  润新知