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

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

倒序遍历数组并打印

 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: 数据类型运算符流程控制语句)