JS面试题(一)

目录

一、JS的数据类型有哪些?如何判断JS的数据类型?

 1.1String字符串型

字符串引号嵌套

字符串转义符

字符串的长度

 字符串拼接+

字符串拼接加强 

 1.2Number数字型

isNaN用来判断非数字

1.3Boolean布尔值类型

1.4Undefind未定义

1.5Null空值

1.6object对象

1.7symbol(这个是Es6新出来的) 

二、NAN是什么?

为什么NaN不等于NaN?

三、JS中的数据类型转换?

 3.1什么是数据类型转换

3.2转换为字符串类型

3.3转换为数字型 

1.parseInt(变量)可以把字符型转换为数字型  得到的是整数

2.parseFloat(变量)可以把字符串型转换为数字型  得到的是小数 浮点数

 ​

3.利用Number(变量)

 4.利用算数运算符运算 - * / 隐式转换

3.4转换为布尔型 

四、如何判断得到的结果是不是数组?

五、js的运算符都有什么?

5.1算数运算符

1.整数

2.浮点数 

5.2、递增(++)和递减(--)运算符

1.前置递增(递减)运算符

2.后置递增(递减)运算符

5.3比较运算符

5.4逻辑运算符

1.逻辑与

2.逻辑或

3.逻辑非

5.5赋值运算符

5.6运算符优先级

六、JS语句的相关考点

6.1 if语句

 6.2 if else双分支语句

 6.3 if else if语句(多分支语句)

 6.4 switch语句

6.5switch语句和if else if语句的区别

6.6for循环

6.7双重for循环

6.8while循环

6.9do while循环

6.10continue关键字

6.11brank关键字

七、数组常用方法

向数组添加元素的方法:

1.Array.push(value1,value2,…)末尾添加

2.Array.unshift(value1,value2,…)开头添加

3.splice(index,0,value1,value2,…)指定位置插入数据

向数组删除元素的方法:

1.pop()尾部删除一个

2.shift()头部删除一个

3.splice(index,howmany)删除指定位置元素

数组排序的方法:

1.reverse()反转

2.sort()排序

数组连接的方法:

1.concat()数组连接

2.join()数组分隔连接成字符串

数组截取的方法:

1.slice(start,end)数组截取

数组转换的方法:

1.toString()数组转换成字符串

八、JS this指向

8.1函数名+小括号直接调用函数,this指向全局对象window。

8.2 通过对象点来调用对象的某个函数,this指向调用这个函数的对象。

8.3当函数被当做事件处理函数时,this指向触发事件的元素。

8.4 IIFE:this指向window。

8.5构造函数中this指向new出来的新对象。

8.6定时器的回调函数中this指向window。

改变this指向的方法

九、闭包

9.1什么是闭包?

 9.2闭包的用途

9.3闭包的优点

9.4闭包的缺点 

十、DOM对象的常用方法

10.1replaceChild()

10.2appendChild()

10.3innersetBefore()

10.4removeChild()


一、JS的数据类型有哪些?如何判断JS的数据类型?

 1.1String字符串型

字符串型可以是引号中的任意文本,其语法为双引号" "和单引号' '

因为HTML标签里面的属性使用的是双引号,JS这里我们更推荐用单引号' '

字符串引号嵌套

JS可以用单引号嵌套双引号,或者用双引号嵌套单引号(外双内单,外单内双)

字符串转义符

转义符都是\开头的

转义符解释说明
\n换行符
\\斜杠\
\'单引号
\"双引号
\tTab缩进
\b空格

字符串的长度

字符串是由若干个字符组成,字符的数量就是字符串的长度,我们可以通过length属性获取整个字符串的长度。

// 检测获取字符串长度
var str = 'I am lili,i like csdn';
console.log(str.length);//21

 字符串拼接+

只要有字符串和其他类型相拼接最终的结果是字符串类型

// 字符串拼接
console.log('今天'+'天气'+'真好');
console.log('我的年龄是'+18);
console.log('20'+21);
console.log('布尔值'+true);

 

字符串拼接加强 

var age = 18;
console.log('我今年'+age+'岁');

 1.2Number数字型

包含整数和小数十六进制: 0-9,a-f  数字前面加0x表示十六进制

isNaN用来判断非数字

 如果是数字返回flase 如果不是数字返回true

// isNaN
console.log(isNaN(12));//flase
console.log(isNaN('张三'));//true

1.3Boolean布尔值类型

布尔值有两个值:true和false,其中true表示真,flase表示假

true = 1;flase=0

var boll1 = true;
var boll2 = false;
console.log(boll1+1);
console.log(boll2+1);

 

1.4Undefind未定义

声明变量未赋值

var str;
console.log(str);
var un = undefined;
console.log(un + '相加');
console.log(un + 1);

 

1.5Null空值

var nu = null;
console.log(nu + '相加');
console.log(nu + 1);

1.6object对象

Object包含了:Data、function、Array。 

1.7symbol(这个是Es6新出来的) 

Symbol数据类型: 表示独一无二的值

二、NAN是什么?

NAN是属于JavaScript的数值类型Number类型。NaN意思是指数据not a number不是一个数字,但是NAN却属于数值类型。

  1. NaN不等于任何值,包括它本身。
  2. NaN在布尔运算时被当作false。
  3. NaN与任何数(包括它自己)的运算,得到的都是NaN。

为什么NaN不等于NaN?

因为NaN表示的是非数字, 但是这个非数字不等于任何值,包括它本身。

三、JS中的数据类型转换?

 3.1什么是数据类型转换

把一种数据类型的变量转换成另外一种数据类型

3.2转换为字符串类型

方式说明案例
toString()转成字符串

var num=1;

alert(num.toString());

String()强制转换转成字符串

var num=1;

alert(String(num));

加号拼接字符串和字符串拼接的结果都是字符串

var num=1;

alert(num+"我是字符串");

// 1.把数字型转换成字符串型    变量.toString()
var num = 10;
var str = num.toString();
console.log(str);
console.log(typeof str);
// 2.利用变量String(变量)
console.log(String(num));
console.log(typeof String(num));
// 3.利用+拼接字符串
console.log(num+'');
console.log(typeof (num+''));

 第三种又称之为隐式转换

3.3转换为数字型 

方式说明案例
parselnt(string)函数将string类型转换成整数数值型parselent('78')

parseFloat(string)函数

将string类型转换成浮点数数值型parseFloat('78.21')
Number()强制转换函数将string类型转换为数值型Number(’12‘)
js隐式转换(- * /)利用算数隐式转换为数值型’12‘-0

1.parseInt(变量)可以把字符型转换为数字型  得到的是整数

console.log(parseInt('18'));//18
console.log(parseInt('3.14'));//3   取整
console.log(parseInt('3.98'));//3   取整
console.log(parseInt('18px'));//18  自动去掉px
console.log(parseInt('px18px'));//NaN

2.parseFloat(变量)可以把字符串型转换为数字型  得到的是小数 浮点数

console.log(parseFloat('18'));//18
console.log(parseFloat('3.14'));//3.14
console.log(parseFloat('3.98'));//3.98
console.log(parseFloat('18px'));//18    自动去掉px
console.log(parseFloat('px18px'));//NaN

 

3.利用Number(变量)

console.log(Number('100'));

 4.利用算数运算符运算 - * / 隐式转换

console.log('12'-0);//12
console.log('100'-'50');
console.log('100'*1);

3.4转换为布尔型 

方式说明案例
Boolean()函数其它类型转成布尔值Boolean('true')

代表空、否定的值会被转换为false,例如0、NaN、null、undefind,‘ ’

其余都是true

console.log(Boolean(''));//false
console.log(Boolean(0));//false
console.log(Boolean(NaN));//false
console.log(Boolean(null));//false
console.log(Boolean(undefined));//false
console.log(Boolean(1));//true
console.log(Boolean('张三'));//true

 

四、如何判断得到的结果是不是数组?

Array.isArray()

五、js的运算符都有什么?

5.1算数运算符

用于执行两个变量或值的算数运算

运算符描述实例
+1+1=2
-2-1=1
*

1*1=1

/4/2=2
%取余数(取模)5%2=1

1.整数

console.log(1 + 1); //2
console.log(1 - 1); //0
console.log(1 * 1); //1
console.log(1 / 1); //1
console.log(5 % 2); //1
console.log(3 % 5); //3

2.浮点数 

浮点数的最高精度是17位小数,但在进行算数计算时其精确度不如整数 

  •  不要直接判断两个浮点数是否相等 
  • 求一个数是否可以被整除查看余数是否为0
  • 有优先级(先乘除后加减有括号先算括号里的)

表达式:由数字、运算符、变量等组成的式子

返回值:表达式最终的结果返回给我们称为返回值

5.2、递增(++)和递减(--)运算符

  • 给一个变量反复加1或减1
  • 必须配合变量使用

1.前置递增(递减)运算符

递增(++)递减(--)放在变量前面称为前置递增(递减)运算符

//前置运算符    先加1后返回值
var age = 10;
++age; //类似于age = age + 1
console.log(age);//11

 先自加再返回值

2.后置递增(递减)运算符

递增(++)递减(--)放在变量后面称为后置递增(递减)运算符

//后置运算符
var num = 10;
num++;
console.log(num); //11

 先返回原值后自加

var age = 10;
console.log(age++ + 10); //20
console.log(age); //11
  • 单独使用时,运行结果相同
  • 与其它代码连用结果不同
  • 后置:先返回再自加(先人后己)
  • 前置:先自加再返回 (先己后人)
  • 开发时使用后置较多

5.3比较运算符

两个数据进行比较时所使用的的运算符,返回布尔值(true/false)

运算符名称说明案例结果
<小于号1<2true
>大于号1>2false
>=大于等于号2>=2true
<=小于等于号1<=2true
==等于号1==1true
!=不等号1!=1flase
===        !==全等        不全等1==='1'flase
console.log(3 >= 5); //flase
console.log(2 <= 8); //true
console.log(3 == '3'); //true   会把字符型转换成数字型
console.log(3 != 3); //flase
console.log(3 === '3'); //flase     要求值和数据类型一样

5.4逻辑运算符

用来进行布尔值运算的运算符,返回值也是布尔值,用于多个条件的判断

逻辑运算符说明案例
&&‘逻辑与’,andtrue&&salse
||'逻辑或',ortrue||false
!'逻辑非',not!true

1.逻辑与

两侧都为true结果为true,有一侧是flase结果为flase

//一个为假就为假
console.log(3 > 5 && 3 > 2); //flase
//两个为真就为真
console.log(2 > 1 && 3 == 3); //true
//两个为假就为假
console.log(10 > 20 && 3 > 5); //flase

2.逻辑或

两侧都为flase结果为flase;有一侧为true结果就是true

//一真一假
console.log(3 > 5 || 3 > 2);
//两假
console.log(3 > 5 || 3 < 2);

3.逻辑非

取反符,用来取一个布尔值相反的值

//not
console.log(!true);//flase
  •  逻辑中断很重要可能会影响程序的运行结果

5.5赋值运算符

用来把数据赋值给变量的运算符

赋值运算符说明案例
直接赋值var myName='张三'
+=、-=加、减一个数后再赋值var age = 10;age+=5;//15
*=、/=、%=乘、除、取模后再赋值var age = 2;age*=5;//10
var num = 10;
num += 2;
console.log(num); //12
var age = 2;
age *= 3;
console.log(age); //6

5.6运算符优先级

优先级运算符顺序
1小括号()
2一元运算符! ++ -- 
3算数运算符先* / %后+ -
4关系运算符> >= < <=
5相等运算符== !== === !===
6逻辑运算符先&&后||
7赋值运算符=
8逗号运算符

六、JS语句的相关考点

语句相关案例,查看以前笔记JavaScript流程控制

6.1 if语句

if(条件表达式){
    //执行语句
}

如果if里面的条件表达式结果为真true则执行中括号里面的执行语句

如果if里面的条件表达式结果为假flase则不执行中括号里面的语句,执行if语句后面的代码

 6.2 if else双分支语句

//条件成立 执行if里面代码,否则执行else里面的代码
if (条件表达式) {
    //[如果]条件成立执行的代码
} else {
    //[否则]执行的代码

如果表达式结果为真执行语句1,否则执行语句2

if里面的语句1和else里面的语句2最终只能有一个语句执行        2选1

else后面直接跟中括号

 6.3 if else if语句(多分支语句)

if (条件表达式1) {
     语句1
} else if (条件表达式2) {
     语句2
} else if (条件表达式3) {
     语句3
} else {
     最后的语句
}

如果条件表达式1满足就执行语句1,执行 完毕后,退出整个if分支语句

如果条件表达式1不满足,则判断条件表达式2,满足的话执行语句2

以此类推

如果所有条件都不成立执行else里面的语句

 6.4 switch语句

switch (表达式) {
   case value1:
        执行语句1;
        break;
   case value2:
        执行语句2;
        break;
   default:
        执行最后的语句;
}

如果匹配上,就执行该case里面的语句

如果都没有匹配上,那么执行default里面的语句

6.5switch语句和if else if语句的区别

  1. 一般情况下,他们两个语句可以互相替换
  2. switch…case语句通常处理case为比较确定值的情况,而if…else…语句更加灵活,常用于范围判断(大于、等于某个范围)
  3. switch语句进行条件判断后直接执行到程序的条件语句,效率更大。而if…else语句有几种条件,就得判断多少次
  4. 当分支较少时,if…else语句的执行效率比switch语句高
  5. 当分支较多时,switxh语句的执行效率比较高,而且结构更清晰

6.6for循环

for (初始化变量; 条件b表达式; 操作表达式) {
     循环体
}

初始化变量:就是用var声明的一个普通变量,通常用于作为计数器使用

条件表达式:就是用来决定每一次循环是否继续执行         就是终止的条件

操作表达式:就是每次循环最后执行的代码        经常用于我们计数器变量进行更新(递增或者递减)

6.7双重for循环

for (外层的初始化变量; 外层的条件表达式; 外层的操作表达式) {
     for (里层的初始化变量; 里层的条件表达式; 里层的操作表达式) {
           执行语句;
     }
}

6.8while循环

while (条件表达式) {
      循环体
}

当条件表达式结果为true则执行循环体否则退出循环

6.9do while循环

do {
      循环体
} while (条件表达式)

先执行一次循环体再判断条件,如果条件表达式结果为真,则继续执行循环体,否则退出循环

6.10continue关键字

continue关键字用于跳出本次循环,继续下一次循环(本次循环体中continue之后的代码就会少执行一次)

6.11brank关键字

breake关键字用于立即跳出整个循环(循环结束)。

七、数组常用方法

向数组添加元素的方法:

1.Array.push(value1,value2,…)末尾添加

  • 向数组的末尾追加
  • 返回值是添加数据后数组的新长度。
  • 会改变原有数组
let arr = [1,2,3];
let result= arr.push(4,5);
console.log(result)   //5
console.log(arr)    //[1,2,3,4,5]

2.Array.unshift(value1,value2,…)开头添加

  • 向数组的开头添加
  • 返回值是添加数据后数组的新长度。
  • 会改变原有数组
let arr = [1,2,3];
let result= arr.unshift(4,5);
console.log(result)   //5
console.log(arr)    //[4,5,1,2,3]

3.splice(index,0,value1,value2,…)指定位置插入数据

  • 向数组的指定 index 处插入
  • 返回的是被删除的元素。
  • 会改变原有数组
如果只传入俩个参数那就是从【参数1】的位置删除【参数2】个数
let arr = [1,2,3];
let result = arr.splice(2,0,4,5);
console.log(result)   //Array(0)
console.log(arr)    //[1,2,4,5,3]

向数组删除元素的方法:

1.pop()尾部删除一个

  • 从尾部删除一个元素
  • 返回被删除掉的元素。
  • 会改变原有数组
let arr = [1,2,3];
let result = arr.pop();
console.log(result)   //3
console.log(arr)    //[1,2]

2.shift()头部删除一个

  • 从头部删除一个元素
  • 返回被删除掉的元素。
  • 会改变原有数组
let arr = [1,2,3];
let result = arr.shift();
console.log(result)   //1
console.log(arr)    //[2,3]

3.splice(index,howmany)删除指定位置元素

  • 在 index 处删除 howmany 个元素,
  • 返回的是被删除掉的元素的集合。
  • 会改变原有数组
let arr = [1,2,3];
let result = arr.splice(1,2);
console.log(result)   //[2,3]
console.log(arr)    //[1]

数组排序的方法:

1.reverse()反转

  • 反转,倒置
  • 该方法会改变原有数组
let arr = [1,2,3];
let result = arr.reverse();
console.log(result)   //[3,2,1]
console.log(arr)    //[3,2,1]

2.sort()排序

  • 按指定规则排序
  • 改变原有数组。
let arr = [2,1,3];
let result = arr.sort();
console.log(result)   //[1,2,3]
console.log(arr)    //[1,2,3]

注意: 如果你认为 sort 方法是让数组从小到大排序那就错了。 我们可以改变一下刚才的数组,加一些大一点的数字。

let arr = [25,148,12,6,38];
let result = arr.sort();
console.log(result)   //[12, 148, 25, 38, 6]
console.log(arr)    //[12, 148, 25, 38, 6]

有些朋友现在是不是稍微有一点懵了? 可是我们还是能找到一些规律的,他就是首先按照一个数字的第一个字符的大小去做比较,然后再用第二个字符去做比较,小的在前面,如果朋友们想让这个数组从真正的小到真正的大排序,那么我们可以改造一下刚才的代码。

let arr = [25,148,12,6,38];
let result = arr.sort((a,b) => a - b);
console.log(result)   //[6, 12, 25, 38, 148]
console.log(arr)    //[6, 12, 25, 38, 148]

如果想要从大到小排序那么就

let arr = [25,148,12,6,38];
let result = arr.sort((a,b) => b - a);
console.log(result)   //[148, 38, 25, 12, 6]
console.log(arr)    //[148, 38, 25, 12, 6]

总的来说,数组的 sort 方法里面的参数是一个回调函数,有俩个值,返回值如果是第一个值减去第二个值那么就是从小到大排序,如果是第二个值减去第一个值就是从大到小排序。

数组连接的方法:

1.concat()数组连接

  • 数组连接
  • 返回连接后的新数组。
let arr = [25,148,12,6,38],
    arr2 = [1,5,8]
let result = arr.concat(arr2);
console.log(result)   //[25, 148, 12, 6, 38, 1, 5, 8]
console.log(arr)    //[25, 148, 12, 6, 38]

2.join()数组分隔连接成字符串

  • 将数组的每个元素以指定分隔符(默认为“,”)连接成字符
  • 返回该连接完成后的字符串。
let arr = [25,148,12,6,38];
let result = arr.join(),
    result2 = arr.join('+')
console.log(result)   //25,148,12,6,38
console.log(result2)   //25+148+12+6+38
console.log(arr)    //[25, 148, 12, 6, 38]

数组截取的方法:

1.slice(start,end)数组截取

  • 从 start 起始索引处,截取到 end 结束索引处
  • 返回截取到的元素集合。 注意: 如果不传值那么就是直接拷贝了一份数组的值。 end 可以不传值,表示截取到数组的末尾。start 与 end 也可以取负值,取负值表示从后向前计数。
let arr = [1,2,3,4,5,6,7];
let result = arr.slice(),
    result2 = arr.slice(2),
    result3 = arr.slice(2,4);
console.log(result)   //[1, 2, 3, 4, 5, 6, 7]
console.log(result2)   //[3, 4, 5, 6, 7]
console.log(result3)    //[3, 4]
console.log(arr)    //[1, 2, 3, 4, 5, 6, 7]

数组转换的方法:

1.toString()数组转换成字符串

  • 转换为字符串,和不传参数的 join()一致,还可以使用 2,8,16 进制转变为不同结果。
let arr = [1,2,3,4,5,6];
let result = arr.toString();
console.log(result)   //1,2,3,4,5,6
console.log(arr)    //[1,2,3,4,5,6]

八、JS this指向

谁直接调用产生this的函数,this就指向谁。但是在使用了new操作符以后,构造函数内部的this指向的是新对象,也就是指向new出来的新实例。

8.1函数名+小括号直接调用函数,this指向全局对象window。

因为以函数名加小括号的方式调用函数时相当于是window通过.调用了该函数,所以此时this指向window。

8.2 通过对象点来调用对象的某个函数,this指向调用这个函数的对象。

举个例子就是,有一个对象obj,在这个对象内部有一个键值对,这个键值对的值是一个函数,那么通过obj.这个键可以调用这个函数,此时函数内部this指向的就是对象obj。​​​​​​​

8.3当函数被当做事件处理函数时,this指向触发事件的元素。

8.4 IIFE:this指向window。

8.5构造函数中this指向new出来的新对象。

在构造函数中使用new操作符的时候,js会先创建一个新的空对象,然后,执行这个函数,把函数中的执行对象赋给这个新生成的实例,也就是这个函数可以使用this来初始化这个新创建的对象的属性。最后返回这个新生成的对象。所以当使用new操作符之后,函数中的this指向的是新创建的对象。所以构造函数中的this就是指向new出来的那个对象。

8.6定时器的回调函数中this指向window。

以setTimeout为例,setTimeout属于宏任务,它的回调在延时之后才进入到主线程执行,而函数执行的时候才会明确this的指向。执行的时候由于没有设置内部this的指向,相当于是普通函数调用,所以默认指向window。

改变this指向的方法

  • call() 调用时,传入的第一个参数用来指定函数内部this指向,后面的所有参数是函数执行时需要的实参(实参必须列举出来)。
  • apply() 调用时,第一个参数和call一样,用来指定函数内部this的指向,第二个参数是一个数组或伪数组(比如arguments对象),数组元素是函数执行时需要的所有实参。
  • bind() 只有一个参数,用来指定函数内部this的指向,但是会返回一个新的函数。

        call和apply是一次性改变this,bind是永久性改变this

九、闭包

理解闭包,需要先理解

9.1什么是闭包?

闭包就是能够读取其他函数内部变量的函数。

由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。

 9.2闭包的用途

它的最大用处有两个,

一个是可以读取函数内部的变量

另一个就是让这些变量的值始终保持在内存中

9.3闭包的优点

可以在全局变量中重复使用变量,并且不会造成变量污染

可以用来定义私有属性和私有方法

9.4闭包的缺点 

比普通函数更占用内存,会导致网页性能变差,在IE下容易造成内存泄漏

十、DOM对象的常用方法

10.1replaceChild()

把一个给定父元素里的一个子节点替换为另外一个子节点
var reference = element.replaceChild(newChild,oldChild)
返回值指向已经被替换掉的那个子节点的引用

10.2appendChild()

为给定元素增加一个子节点
给定子节点newChild将成为element的最后一个节点
方法的返回值指向新增节点的引用
该方法通常与createElement()与createTextNode()一起使用
新节点可以追加给文档中的任何一个元素(不是属性和文本)

10.3innersetBefore()

把一个给定节点插入到一个给定元素子节点的前面
var reference = element.insertBefore(newNode,targetNode)
newNode节点将作为element的子节点出现,并在targetNode节点的前面
节点targetNode必须是element的一个子节点
该方法通常与createElement和createTextNode结合使用

10.4removeChild()

从给定的元素里删除一个子节点
var reference = element.removeChild(node)
返回值指向已经被删除的子节点的引用
当某个子节点被删除时,这个子节点所包含的子节点也被删除掉
如果想删除一个子节点,但不知道父节点,可以使用parentNode属性

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值