美文网首页
进阶2: 数据类型运算符流程控制语句

进阶2: 数据类型运算符流程控制语句

作者: 晓风残月1994 | 来源:发表于2017-08-25 00:23 被阅读3次

    1. JavaScript 定义了几种数据类型? 哪些是原始类型?哪些是复杂类型?原始类型和复杂类型的区别是什么?

    JavaScript 语言的每一个值,都属于某一种数据类型。JavaScript 的数据类型,共有六种。(ES6 又新增了第七种 Symbol 类型的值)分别为:

    数值(number)
    字符串(string)
    布尔值(boolean)
    undefined
    null
    对象(object)
    数值、字符串、布尔值称为原始类型(primitive type)的值
    对象称为合成类型(复杂类型)(complex type)的值
    undefined 和 null 一般看成两个特殊值


    2. typeof和instanceof的作用和区别?

    • typeof可以检测给定变量的数据类型,但是有局限性,对于Array、Null等特殊对象使用typeof一律返回object。 此外,typeof可以用来判断一个变量是否存在,或者是未被定义 if (typeof v === "undefined") {
    • 既然typeof对数组(array)和对象(object)的显示结果都是object,那么就需要 instanceof(非唯一方法) 进行区分。
      instanceof用于判断一个变量是否某个对象的实例,比如 var a = []; 那么 a instanceof Array 就会返回true。

    3. 如何判断一个变量是否是数字、字符串、布尔、函数

    使用typeof, 能返回字符串,里面告诉了什么类型,未定义、 数字、字符串、布尔、函数、分别对应,"undefined"、"number"、"string"、"boolean"、"function"。


    4. NaN是什么? 有什么特别之处?

    NaN含义是Not a Number,即非数值,是一个特殊的数值,用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)。

    特殊之处:

    • 任何涉及NaN的操作(例如NaN+10)都会返回NaN
    • NaN和任何值都不相等,包括NaN本身(例如 NaN == NaN //false)

    5. 如何把非数值转化为数值?

    有三个函数可以把非数值转换为数值

    1. Number()
    2. parseInt()
    3. parseFloat()
    

    Number()

    • Number()可以用于任何数据类型,布尔值 true=>1, false=>0. 数字则是简单传入,null=>0, undefined=>NaN,
    • 字符串
      • 字符串只包含数字(十进制、八进制、十六进制)都会转换成十进制;
      • 字符串包含有效的浮点格式,则转换为对应的浮点数值;
      • 字符串是空的(包括空格字符),都转换为0;
      • 如果字符串包含除上述格式之外的字符,则将其转换为NaN, 这意味着需要parseInt() 和 parseFloat() 进一步对字符串进行更合理的转换。
    • 如果是对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值。如果转换结果是NaN,则继续调用对象的 toString() 方法,然后再次依照规则转换返回的字符串值。

    parseInt() 和parseFloat()

    • 都是对字符串进行数制转换。前者是针对整数格式,后者是解析包括整数在内的浮点格式的数值。
    • parseInt()可以指定第二个参数作为转换时的基数,指定有多少进制进行转化,比如parseInt(111,2) 结果是7,如果不指定parseInt(111), 则默认是十进制进行解析转换,那么结果就是111,除了指定二进制,你还可以指定其他进制。
      因此多数情况下,我们要解析的都是十进制数值,因此还是建议指定10,避免错误解析。
    • 相同点
      • 忽略字符串前面的空白字符,找到第一个非空白字符
      • 如果第一个字符不是-或者数字返回NaN
      • 0开头会当做八进制,0x开头会当做十六进制
      • 如果是继续解析,直到非数值模式为止
      • 如果是空字符串(包括含有空格的字符串),则返回NaN

    6. ==与===有什么区别

    首先,二者都是比较运算符。用来比较两个值,然后返回布尔值,用true 或者 false 来表示是否满足比较条件。
    但是, ==表示相等 , === 表示严格相等。
    例如:

    5 == '5' 
    

    使用相等比较运算符的时候,会将string '5',自动转换成number 5,进行比较,从而可以满足比较条件,因为 5 == 5。

    但是 :

    5 === '5' 
    

    使用 === 严格相等 的比较运算符时, 则不会自动做转换处理,显然 number 5 ,是不会和 string '5',相等的。因此,返回boolean的 false值。


    7. break与continue有什么区别

    break用于强制退出循环体,执行循环后面的语句,
    比如:

    for( var i = 1; i < 5; i++ ){
      if( i === 3 ){
        break;
      }
      console.log(i);
    }
    // 输出为 1 2
    // break 为强制退出整个循环体,执行后面的语句所以输出 1  2 到此为止 
    
    for( var i = 1; i < 5; i++ ){
      if( i === 3 ){
        continue;
      }
      console.log(i);
    }
    // 输出为 1 2 4
    // continue 用于退出本次循环,执行下次循环
    //所以 i === 3的时候,这一次退出循环,不再输出 i,但是此后 继续 i++,进行下一次的 i < 5 的判断
    

    8. void 0 和 undefined 在使用场景上有什么区别

    先看一个例子:

    function fn() {
      var undefined = 3;
      var a;
      if(a === undefined ){
        console.log('===') 
      }else{
        console.log('!==')
      }
    }
    fn()
    

    上面的代码中,a虽然声明变量了,但是没有赋值,所以应该是未定义undefined,在接下来的条件判断语句中,a应该会严格等于undefined。
    但是在一开始,对 undefined 声明并且赋值为3
    Infinity、NaN、undefined 这三个词虽然不是保留字,但因为具有特别含义,一般不应该用作标识符,但是强行用也是可以的。
    这个时候,程序的结果是 !==, 显然a !== undefined,严格不等于undefined,因为undefined是3, 实际上,a != undefined ,a 也不等于 undefined,彻底的不一样了。

    然而,a显然还是undefined,未定义。这是个bug,怎么办呢?所以要最保险的方法是是void操作符。
    void运算符的作用是执行一个表达式,然后返回undefined。
    根据这个特性,其他不变,把if判断条件修改一下:

    function fn() {
      var undefined = 3;
      var a;
      if(a === void 0 ){
        console.log('===') 
      }else{
        console.log('!==')
        console.log(a)
      }
    }
    fn()
    

    此时 void 优先级高于 比较运算符 === ,所以 void 0 无脑返回 undefined,从而 a === 真正纯天然无污染的 undefined。最后判断结果是 布尔值 true。 输出 ===


    9. 以下代码的输出结果是?为什么?

    console.log(1+1);   //输出number 2
    console.log("2"+"4");  //输出string "24"
    console.log(2+"4");  //输出string "24"
    console.log(+"4");  //输出number 4
    

    下面解释一下原因:

    首先这些都是 运算符 + 在不同数据类型下具有的不同含义。

    1. 第一个很好理解,两个参数都是数字,则此时的+就是加法运算。
    2. 两个参数都是string,这时候会进行字符串的拼接,于是拼接成新的string "24"。
    3. 一个参数是number,但是另一个是string,那么会把number转化成string,与另一个string进行拼接。所以结果还是string '24'。
    4. 最后一个,只有一个数字参数,则会返回其正整数。是number,直接返回number,是string,但里面是number,则还是返回number,如果 console.log("jirengu"),则返回NaN。可以理解为 本性还是数值类型,但是字符串 jirengu,是没办法转化成一个具体number值的。

    10. 以下代码的输出结果是?

    var a = 1;  
    a+++a;  
    typeof a+2;
    

    结果是字符串 "number2"
    为什么会这样子?
    因为这里的 + 实际上并不是算数运算符里面的加法运算符,而是代表字符串拼接。
    a 不管怎样,都是number类型,而typeof返回的是数据类型是string格式的(注意,这里不是说typeof返回的结果,告诉我们是string类型。)
    至于第二行中 a+++a,实际上可以拆分成:
    (a++)(+a)
    理解为:
    a=1
    b=a
    a= a+1
    b+a


    11. 以下代码的输出结果是? 为什么

     var a = 1;
     var b = 3;
     console.log( a+++b ); //输出结果是4
    

    结果是4, 首先++ 自增运算符优先级高于 + 加法运算符。 a++,表示参与当前的运算后(先赋值),再自增1。
    所以是 1 + 3 = 4
    这时候,再console.log(a) , 则返回 2


    12. 遍历数组,打印数组每一项的平方

    var arr = [3, 4, 5]
    for(i = 0; i<arr.length; i++){
      console.log(arr[i]*arr[i])
    } 
    // 输出为 9 16 25
    

    倒序遍历数组并打印

     var arr = [100, 90, 80, 70, 60]
     for(var i = arr.length - 1; i >= 0; i-- ){
       console.log(arr[i])
     }
    // 输出为 60 70 80 90 100
    

    正序遍历偶数序位的数组

    var arr = [100, 90, 80, 70, 60, 50, 40]
    for(var i = 1; i < arr.length; i += 2){
      console.log(arr[i])
    }
    // 输出为 90 70 50
    

    13. 遍历 JSON, 打印里面的值

    var obj = {
     name: 'hunger', 
     sex: 'male', 
     age: 28 
    }
    for( var key in obj ){
      console.log(obj[key])
    }
    // 输出为 hunger male 28
    

    14. 以下代码输出结果是? 为什么 (选做题目)

    var a = 1, b = 2, c = 3; 
    var val = typeof a + b || c >0
    console.log(val) 
    // 输出 number2
    

    typeof优先级最高,判断a是"number",接着和 2 进行拼接,成为"number2",由于是 || 或运算符,所以左边成立,右边即可忽略,不会执行。 因此最后把"number" 赋值给 val,通过console.log(val) 的时候,就去掉了""

    var d = 5;
    var data = d ==5 && console.log('bb')
    console.log(data)
    // 输出 bb undefined
    

    因为先执行console.log 输出bb,然后 d == 5为 true,然后&&右边 console.log('bb') 无法被自动转换为布尔值,不是true也不是false,而是undefined,于是就把undefined 赋值给了 data。

    var data2 = d = 0 || console.log('haha')
    console.log(data2)
    // 输出 haha  defined
    

    首先因为是console.log所以先无脑输出haha, 然后 因为这是或运算符,左边 0 转化为false,所以继续看右边的,右边console.log('haha')无法被有效的转换为 布尔值boolean, 因此是undefined未定义。所以最后把 undefined赋值给 data2。
    所以最后输出两行:
    haha
    defined
    因为console.log()方法会自动换行

    var x = !!"Hello" + (!"world", !!"from here!!");
    console.log(x)
    // 输出 2
    

    原因很简单, 首先括号优先级最高,其次里面有逗号运算符,虽然逗号运算符低的不要不要的, 但是可以让我们去忽略逗号前面的 !"world"
    所以返回的是逗号后面的表达式, "from here!!" 本来是无辜的字符串,但是使用了布尔运算符中的 ! 取反运算符,所以被偷偷转换为布尔值,因为字符串非空,所以是true,进行了两次取反,最后还是true。
    然后再看!!"Hello" 同理,转换为boolean值 true, 这时候 有个 加法运算符 + ,
    于是布尔值 又被偷偷转换为number参与 加法运算, true对应的是1,
    所以,大声告诉我:
    x = 1 + 1
    请问 x 是多少?

    相关文章

      网友评论

          本文标题:进阶2: 数据类型运算符流程控制语句

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