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
下面解释一下原因:
首先这些都是 运算符 + 在不同数据类型下具有的不同含义。
- 第一个很好理解,两个参数都是数字,则此时的+就是加法运算。
- 两个参数都是string,这时候会进行字符串的拼接,于是拼接成新的string "24"。
- 一个参数是number,但是另一个是string,那么会把number转化成string,与另一个string进行拼接。所以结果还是string '24'。
- 最后一个,只有一个数字参数,则会返回其正整数。是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 是多少?