美文网首页
“特殊”

“特殊”

作者: 不知道的是 | 来源:发表于2018-06-13 16:12 被阅读0次

    可以在同一条var命令中声明多个变量。

    var a, b;
    a // undefined
    b // undefined
    

    如果使用var重新声明一个已经存在的变量,是无效的。

    var x = 1;
    var x;
    x // 1
    

    上面代码中,变量x声明了两次,第二次声明是无效的。

    但是,如果第二次声明的时候还进行了赋值,则会覆盖掉前面的值。

    var x = 1;
    var x = 2;
    
    // 等同于
    
    var x = 1;
    var x;
    x = 2;
    

    标识符

    var π = 3.14
    π // 3.14
    
    var 临时变量 = 1
    临时变量 // 1
    

    注释

    --> 这是一条合法的JS注释
    <!-- 这是一条合法的JS注释
    <!-- 这是一条合法的JS注释 -->
    

    -->只有在行首,才会被当成单行注释,否则会当作正常的运算。

    function countdown(n) {
      while (n --> 0) console.log(n)
    }
    countdown(3) // 2 1 0
    

    上面代码中,n --> 0实际上会当作n-- > 0,因此输出2、1、0。

    条件语句

    if结构

    if (布尔值)
      语句;
    
    if (布尔值) 语句;
    
    if (布尔值) {
      语句;
      ...
    }
    
    let x = 2
    if (x = 3)  console.log(x)
    // 3
    if (2 = x) console.log(x)
    // Uncaught ReferenceError: Invalid left-hand side in assignment
    

    if...else 结构
    else代码块总是与离自己最近的那个if语句配对。

    var m = 1;
    var n = 2;
    
    if (m !== 1)
    if (n === 2) console.log('hello');
    else console.log('world');
    

    上面代码不会有任何输出,else代码块不会得到执行,因为它跟着的是最近的那个if语句,相当于下面这样。

    if (m !== 1) {
      if (n === 2) {
        console.log('hello');   
      } else {
        console.log('world');
      }
    }
    

    switch 结构

    var x = 1;
    
    switch (x) {
      case 1:
        console.log('x 等于1');
      case 2:
        console.log('x 等于2');
      default:
        console.log('x 等于其他值');
    }
    // x等于1
    // x等于2
    // x等于其他值
    

    switch语句部分和case语句部分,都可以使用表达式。

    switch(1 + 3) { // 1 + 3
      case 2 + 2: // 2 + 2
        f();
        break;
      default:
        neverHappens();
    }
    

    需要注意的是,switch语句后面的表达式,与case语句后面的表示式比较运行结果时,采用的是严格相等运算符(===),而不是相等运算符(==),这意味着比较时不会发生类型转换。

    循环语句

    while 循环

    while (条件)
      语句;
    
    while (条件) 语句;
    
    while (条件) {
      语句;
    }
    

    for 循环

    for (初始化表达式; 条件; 递增表达式)
      语句
    
    for (initialize; test; increment) {
      语句
    }
    

    for语句的三个部分(initialize、test、increment),可以省略任何一个,也可以全部省略。

    for ( ; ; ){
      console.log('Hello World');
    }
    

    上面代码省略了for语句表达式的三个部分,结果就导致了一个无限循环。

    do…while 循环
    do...while循环与while循环类似,唯一的区别就是先运行一次循环体,然后判断循环条件。

    do
      语句
    while (条件);
    
    do {
      语句
    } while (条件);
    

    不管条件是否为真,do...while循环至少运行一次,这是这种结构最大的特点。另外,while语句后面的分号注意不要省略

    let w = 5
    do {
      w--
      console.log(w) // 4 3 2 1 0 -1
    } while(w >= 0);
    
    // 省略分号的测试结果
    let v = 10
    do {
      v--
      console.log(v) // 9 8 7 6 5 4
    } while(v >= 5)
    

    break 语句

    var i = 0
    
    while(i < 100) {
      console.log('i 当前为:' + i)
      // 上面代码只会执行10次循环,一旦i等于10,就会跳出循环。
      i++
      if (i === 10) break
    }
    
    for (var i = 0; i < 5; i++) {
      console.log(i)
      // 上面代码执行到i等于3,就会跳出循环
      if (i === 3)
        break
    }
    

    continue 语句

    for (let i = 0; i <= 5; i++) {
      if (i % 2) {
        continue
        // 如果i为奇数,直接进入下一轮循环
      }
      console.log(i) // 0 2 4
    }
    

    标签(label)

    label:
      语句
    

    标签通常与break语句和continue语句配合使用,跳出特定的循环。

    Use label

    top:
      for (var i = 0; i < 3; i++){
        for (var j = 0; j < 3; j++){
          if (i === 1 && j === 1) break top;
          console.log('i=' + i + ', j=' + j);
        }
      }
    // i=0, j=0
    // i=0, j=1
    // i=0, j=2
    // i=1, j=0
    

    Without label

    for (var i = 0; i < 3; i++) {
      for (var j = 0; j < 3; j++) {
        console.log('i=' + i + ', j=' + j);
      }
    }
    
    // i=0, j=0
    // i=0, j=1
    // ... ...
    // i=2, j=2
    

    typeof 运算符

    typeof  function () {} // "function"
    typeof undefined // undefined
    typeof [] // "object"
    typeof null // "object"
    

    null 和 undefined

    Number(null) // 0
    Number(undefined) // NaN
    

    布尔值

    if ('') console.log('true') // 无输出
    

    整数和浮点数

    /**
     * true
     * JS内部,所有数字都以64位浮点数形式储存
     * JavaScript 语言的底层根本没有整数
     */
    1 === 1.0
    

    由于浮点数不是精确的值,所以涉及小数的比较和运算要特别小心。

    0.1 + 0.2 === 0.3 // false
    0.3 / 0.1 // 2.9999999999999996
    (0.3 - 0.2) === (0.2 - 0.1) // false
    
    /**
     * 精度最多只能到53个二进制位,
     * 这意味着,
     * 绝对值小于等于2的53次方的整数,
     * 即-2的53次方到2的53次方,都可以精确表示。
     */
    Math.pow(2, 53) // 9007199254740992
    
    /**
     * 出错
     * 9007199254740992
     */
    Math.pow(2, 53) + 1
    
    // 多出的三个有效数字,将无法保存
    9007199254740992111
    // 9007199254740992000
    

    数值范围

    JS能够表示的数值范围为2的1024次方到2的-1023次方(开区间),超出这个范围的数无法表示。

    Math.pow(2, 1024) // Infinity 正向溢出
    Math.pow(2, -1075) // 0 负向溢出
    
    Number.MAX_VALUE // 1.7976931348623157e+308
    Number.MIN_VALUE // 5e-324
    

    数值的表示法

    .1e-23 // 1e-24
    
    /**
     * 小数点前的数字多于21位
     * 1.2345678901234568e+21
     */
    1234567890123456789012
    
    /**
     * 小数点后的零多于5个
     * 3e-7
     */
    0.0000003
    
    0.000003 // 0.000003
    

    数值的进制

    0xff // 255 16进制
    0o377 // 255 8进制
    0b11 // 3 2进制
    

    如果八进制、十六进制、二进制的数值里面,出现不属于该进制的数字,就会报错。

    /**
     * Uncaught SyntaxError: 
     * Invalid or unexpected token
     */
    0xzz  // 16进制出现 z
    0o88 // 8进制出现 8
    0b22 // 2进制出现 2
    
    /**
     * 通常来说,有前导0的数值会被视为八进制,
     * 但是如果前导0后面有数字8和9,
     * 则该数值被视为十进制。
     * 
     * 前导0表示八进制,处理时很容易造成混乱。
     * ES5 严格模式和 ES6中,已废除这种表示法。
     */
    
    0888 // 888
    0777 // 511
    

    特殊数值

    正零和负零

    -0 === +0 // true
    0 === -0 // true
    0 === +0 // true
    
    +0 // 0
    -0 // 0
    (-0).toString() // '0'
    (+0).toString() // '0'
    
    (1 / +0) === (1 / -0) // false
    

    NaN

    5 - 'x'
    // NaN
    
    Math.acos(2) // NaN
    Math.log(-1) // NaN
    Math.sqrt(-1) // NaN
    
    0 / 0 // NaN
    
    typeof NaN // 'number'
    
    NaN === NaN // false
    
    [NaN].indexOf(NaN) // -1
    
    Boolean(NaN) // false
    
    NaN + 32 // NaN
    NaN - 32 // NaN
    NaN * 32 // NaN
    NaN / 32 // NaN
    

    Infinity

    Math.pow(2, 1024) // Infinity
    
    0 / 0 // NaN
    1 / 0 // Infinity
    
    Infinity === -Infinity // false
    
    1 / -0 // -Infinity
    -1 / -0 // Infinity
    

    Infinity大于一切数值(除了NaN),-Infinity小于一切数值(除了NaN)。

    Infinity > 1000 // true
    -Infinity < -1000 // true
    

    Infinity与NaN比较,总是返回false。

    Infinity > NaN // false
    -Infinity > NaN // false
    
    Infinity < NaN // false
    -Infinity < NaN // false
    

    parseInt()

    parseInt('   81') // 81
    

    如果parseInt的参数不是字符串,则会先转为字符串再转换。

    parseInt(1.23) // 1
    // 等同于
    parseInt('1.23') // 1
    
    parseInt('abc') // NaN
    parseInt('.3') // NaN
    parseInt('') // NaN
    parseInt('+') // NaN
    parseInt('+1') // 1
    
    parseInt('0x10') // 16
    
    parseInt('011') // 11
    
    /**
     * 对于那些会自动转为科学计数法的数字,
     * parseInt会将科学计数法的表示方法视为字符串,
     * 因此导致一些奇怪的结果。
     */
    parseInt(1000000000000000000000.5) // 1
    // 等同于
    parseInt('1e+21') // 1
    
    parseInt(0.0000008) // 8
    // 等同于
    parseInt('8e-7') // 8
    
    parseInt('1000', 2) // 8
    parseInt('1000', 6) // 216
    parseInt('1000', 8) // 512
    
    parseInt('10', 37) // NaN
    parseInt('10', 1) // NaN
    parseInt('10', 0) // 10
    parseInt('10', null) // 10
    parseInt('10', undefined) // 10
    
    parseInt('1546', 2) // 1
    parseInt('546', 2) // NaN
    

    parseFloat()

    parseFloat(true)  // NaN
    Number(true) // 1
    
    parseFloat(null) // NaN
    Number(null) // 0
    
    parseFloat('') // NaN
    Number('') // 0
    
    parseFloat('123.45#') // 123.45
    Number('123.45#') // NaN
    

    参考资料:
    JavaScript标准参考教程(alpha)

    相关文章

      网友评论

          本文标题:“特殊”

          本文链接:https://www.haomeiwen.com/subject/urvjeftx.html