前端面试题2021(JS篇(上))

1.简述JavaScript的特点

JavaScript是一门基于对象的、事件驱动的、跨平台的、弱类型的、函数优先的、解释型的编程语言
基于对象:JavaScript封装了很多对象提供了强大的功能,提高了开发效率
事件驱动:JavaScript可以友好的响应用户的操作,通过事件的方式进行处理
跨平台:JavaScript本身对于操作系统平台依赖性很低
弱类型:JavaScript对于变量中存储的数据的类型不是强制的
函数优先:JavaScript开发过程中以灵活运用到函数式程序开发优先
解释型:JavaScript在执行过程中,解释一行执行一行,对于开发和测试效率都有一定的提升

2.描述JavaScript的引入方式,以及每种方式的优缺点

JavaScript在网页项目开发时主要有三种引入和使用的方式
行内引入:HTML标签的事件属性中可以添加JavaScript代码,当用户操作标签时就会执行事件属性中的代码:
优点:随时需要随时写,比较方便
缺点:能够编写的代码量不多,同时编写的代码只能作用于当前标签,且可读性较低
页面内嵌:HTML网页中添加一对script标签,然后将需要执行的JavaScript代码填写到标签的内部
优点:当前页面需要什么效果,可以直接在网页中编写,简单效果方便查看和修改代码
缺点:JavaScript代码和HTML代码混合出现在同一个页面中可读性较差,且这些JavaScript代码只能用于当前网页
外部引入:编写一个独立的js文件,将需要的JavaScript代码存放在这个独立的文件中,在需要这些代码的网页中通过引入使用
优点:js文件中只有JavaScript代码,网页中只有htm标签,代码看上去非常干净整洁,方便后期维护,可以在任意需要的网页中重复引入使用

3.JavaScript的基本类型都有哪些,有什么特点

JavaScript中提供了一些基本数据类型,包含了如下几种
String字符串、使用引号包含的一串字符
Number数值型、代码中就是一串数字,可以是整数、负数、浮点数
Boolean布尔值、代码中只有两种结果的类型,分别是ture或者false
null,特殊的类型,表示空值的意思
Undefined,特殊的类型。表示未定义、未声明的意思

4.写出下面代码的输出结果,并阐明原因


var n1 = 12
var n2 = 20
var r1 = n1 + n2
console.log(r1,typeof(r1))
var n3 = '12'
var n4 = '20'
var r2 = n3 + n4
console.log(r2,typeof(r2))

1.32 两个数值相加得到的结果为一个相加后的数值
2.1220一个数值与一个字符串相加,得到的结果是一个字符串,相当于字符串拼接

5.简述什么是变量,变量有什么作用,变量的命名规则有哪些

变量是程序中存储数据的容器,变量的主要用于数据的复用
变量名称的命名需要满足一定的规范
变量名称由字母、数字、和下划线组成、数字不能开头
变量的命名遵循驼峰命名法,变量名称由一个或者多个英文单词组成,第一个单词全部小写 ,后面每个单词的首字母大写

6.什么是隐式类型转换,简单描述两种隐式类型转换的场景

数据在代码中可以呈现出来不同的类型,从一个类型转换成另一种类型称为类型转换,JS中某些表达式可以自动将数据从一个类型转化成另一种类型,不需要开发人员干预就可以完成类型转换的过程称为隐式类型转换
isNaN(dat)在进行数据判断包含了隐式类型转换、toFixed(n)进行浮点数小数位数保留时包含了隐式类型转换、运算符进行数据运算时包含了部分数据类型隐式转换

7.什么是运算符

运算符就是让代码中的数据参与运算的符号,项目中常见的运算符有赋值运算符、算数运算符、比较运算符、逻辑运算符等

8.下面代码输出的结果是否正确,为什么

var res = 20 + "20"
console.log(res)  // 40

var res2 = 10 - "5"
console.log(res2) //5

var res3 = 10 - true
console.log(res3)  // 9

var res4 = NaN == NaN
console.log(res4)  // true

var res5 = null == undefined
cosnole.log(res5)  //true

1.错误,应该是2020,加号两侧的数据如果包含字符串,就会自动将非字符串数据转换为字符串进行拼接
2.正确,加号两侧的字符会自动转换成数值进行运算
3.正确,减法运算中将符号两侧的数据转换为数值进行运算,布尔类型的true转换为数值型为1
4.错误,结果应该为false,JavaScript语法规范中针对NaN进行了明确的规定,每个NaN都是一个独立的特殊数值互不相等
5.结果正确,JavaScript语法规范中null和undefined进行了明确的定义,用来描述无效数据!都是无效数据可以通过==相等判断得到true结果

9.下面代码的结果是否正确,为什么

var res1 = (10-5) && (100+21)
console.log(res1)   //121

var res2 = undefined && null
console.log(res2)    //null

var res3 = res2 || 'string'
console.lof(res3) //string

1.正确,逻辑表达式&&中,若左侧表达式的结果为false,则直接返回,如果左侧表达式的结果为true,则返回右侧表达式的结果
2.错误,左侧表达式为false,应该直接返回左侧表达式结果undefined
3.正确,逻辑表达式||中,若左侧表达式得到的结果为false,则返回符号右侧的表达式

10.写出JavaScript中获取HTML网页标签的语法

通过标签名获取多个标签 document.getElementsByTagName('tag')
通过id获取标签 document.getElementById('id')
通过name值获取多个标签 document.getElementsByName('name')
通过类名获取多个标签(不支持ie8以下浏览器,存在兼容问题) document.getElementsByClassName('className')
(h5新增,存在兼容问题) 获取单个标签document.querySelector('.类名/#id/标签名 ')
(h5新增,存在兼容问题) 获取多个标签document.querySelectorAll('.类名/#id/标签名 ')

11.简述JS如何操作标签属性

获取元素 ele
获取属性:ele.属性名
ele['‘属性名’]
设置属性:ele.属性名 = ‘属性值’
ele['‘属性名’] = “属性值”

12.简述JS如何操作标签样式

获取元素ele
获取行内样式 ele.style.样式名
获取非行内样式
非ie getComputedStyle(ele).样式名
ie ele.currentStyle.样式名
设置样式 ele.style.样式名 = ‘样式值’

13.简述JS如何操作标签内容

获取元素ele
闭合标签内容获取(innerHTML会对内部HTML内容进行解析,innerText获取、设置的胃纯文本内容)
ele.innerHTML
ele.innerText
闭合标签内容设置
ele.innerHTML = '标签内部值'
ele.innerText = '标签内部值'
表单内容获取
ele.value
表单内容设置
ele.value = "值"

14.JavaScript都有哪些基本数据类型,哪些复杂数据类型

JavaScript的基本类型都包含字符串String、数值Number、布尔值Boolean、空值Null和无效值Undefined。复杂数据类型包含数组Aray、函数Function、对象Object

注:JavaScript不同的规范版本中,有两种针对Object的不同描述
第一种认为Object对象类型属于基本类型
第二种认为Object对象类型属于复杂数据类型

15.什么是类型转换?简述3种强制类型转换的方式,3种隐式类型转换的方式

类型转换就是一个数据从一种类型转换为另一种类型,包含强制类型转换和隐式类型转换两种转换方式
强制类型转换如String(dat)将dat数据转换为字符串、Number(dat)将dat数据转换为数值、Boolean(dat)将dat数据转换成布尔值
隐式类型转换如isNaN(dat)判断数据是否是一个非数值,会自动将数据转换为布尔值、toFixed(dat)在小数位数保留时内含了类型转换,将数值型转换为字符串进行截取,运算时符号两侧数据类型不一致也会进行隐式类型转换

16.null和undefined都是什么意思,有什么异同

Null和undefined都是基本数据类型,JavaScript规范中都是用来描述无效数据,其中null 表示空值、既是变量中存储的数据,也是一种null基本类型,undefined表示无效值,既是变量中存储的数据,也是一种undefined基本类型

JavaScript底层对于数据类型的判断,是基于二进制的判断方式,直接使用typeof(null)的类型会得到一个object对象类型,正常情况null类型也是属于对象类型,如果要得到null值的真实类型,可以通过Object.prototype.toString.call(null)的方法,获取真实类型,就是null类型

17.编写程序,计算1-100整数的和

var sum = 0;
for(var i=1;i<=100;i++) {
    sum+= i
}
console.log(sum);

18.编写程序,计算1-100奇数的和,偶数的和

var oddSum = evenSum = 0;
for(var i=1;i<=100;i++) {
    if(i%2 == 1) {
        // 奇数
        oddSum += i
    }else {
        // 偶数
        evenSum += i
    }
}
console.log(oddSum,evenSum)

19.生成100个p元素、隔行变色(红 黄 蓝 灰 绿 )

// 获取容器元素 
var box = document.getElementById('container')
for(var i=1;i<=100;i++) {
    if(i%5 == 1) {
         // 第一个
        box.innerHTML = '

i

' }else if(i%5 == 2) { // 第二个 box.innerHTML = '

i

' }else if(i%5 == 3) { // 第三个 box.innerHTML = '

i

' }else if(i%5 == 4) { // 第四个 box.innerHTML = '

i

' }else { // 第五个 box.innerHTML = '

i

' } }

20.观察并写出下属代码的运行结果,并说明原因

var res1 = 12 + "10"
var res2 = "a" + 20
var res3 = "hello" + true
var res4 = 20 * "10"
var res5 = 100 * true
var res6 = 20 / false
var res7 = "12++"
var res8 = "12" ++
var res9 = "100" > 20
var res10 = "100" > "20"

1.1210 字符串拼接
2.a20 字符串拼接
3."hellotrue" 字符串拼接
4.200 数值类型隐式转换
5.100 数值类型隐式转换
6.Infinity 无穷值 零当除数时会得到一个Infinity值
7.12++ 字符串原文输出
8.报错,字符串无法进行自增、自减运算
9.true 数值类型隐式转换
10.false 两侧都是字符串,逐位比较ascii码

21.分析下面代码的输出结果,并说明原因

var myName = 'zhangsan'
function fn() {
    console.log(myName)
   var myName = "lisi"
}
fn()

undefined 变量提升/预解析
JavaScript语法规范中,变量在自己所在的作用域中进行赋值时,会出现一个预解析的过程,先声明后操作,所以会出现undefined

22.编写代码,找出111-999中的水仙花数

(水仙花数也被称为超完全数字不变数、自恋数、自幂数、阿姆斯特朗数。水仙花数是指一个3位数,它的每个位上的数字的3次幂之和等于它本身 例如: 1~3 + 5~3 + 3~3 =153)

// 判断一个数是否是水仙花数
for(var i=111;i<999;i++) {
    if(parseInt(i /100)**3+ parseInt(i % 100 / 10)**3+parseInt(i % 10)**3==i) {
        console.log(i+'是水仙花数');   
    }
}

23.编写代码,找出1-100之间的质数

(质数就是在大于1的自然数中,除了1和它本身以外不在有其他因数的自然数)

// 找出一个数是否是质数
function fn(number) {
    for(var i=2;i

24 .NaN是什么意思,会在什么情况下出现

NaN本意上并不是一个数字,属于数值类型的一个特殊的值
在执行算数运算时,出现了类型转换失败的情况如 1-‘abv’
执行类型转换时,数据类型转换失败的情况,如number(“abc”)

25.变量有什么作用,有哪些命名规则

变量本质上就是代码中临时存储数据的容器,存储数据通过变量名称可以重复使用,变量在操作过程中遵循一定的命名规则和规范
变量名由字符数字下划线和$组成,且数字不能开头
变量在命名的时候遵循驼峰命名法,即变量名称由一个或者多个英文单词组成,第一个单词全部小写,后面每个单词的首字母要大写
变量在命名时要见名知意

26.观察代码说明输出结果

var a = 10
var b = a++
console.log(a,b)

a:11,b:10

自增运算符放在变量后面,是先运算表达式,再执行自增操作

27.==和===的区别

==和===都属于比较运算符中的相等关系判断
==判断符号两侧的数据值是否相等
===判断符号两侧值和数据类型是否都相等

28.innerHTML和innerText的区别

innerHTML和innerText都是用于获取和设置闭合标签中的内容
innerText只操作文本内容,出现的标签当成普通文本内进行处理
innerHTML操作解释标签和文本内容,出现的标签解释渲染对应的格式

29.continue和break的区别

continue只能出现在循环中,主要用于结束本次循环,直接开始下次循环
break可以出现在swich-case选择结构中,也可以出现在循环中
出现在switch-case中用于结束一个条件分支
出现在循环结构中用于跳出循环

30.声明函数的方式有哪些

标准声明
function 函数名称() {}
表达式声明
var 变量 = function() {}

31.简述你对this的理解

this指代的是当前对象,在JavaScript操作页面标签对象时,this会出现如下几种情况
直接声明全局函数,函数内部的this指代的浏览器窗口对象window
声明函数挂载到标签事件属性上,函数内部this指代的是当前标签对象
函数出现在JSON对象中,函数内部的this指代的就是当前JSON字面量对象

32.请描述你对预解析的理解

JavaScript语法规范中,在变量声明时,变量所在的作用域空间,会将变量的声明提升到所有代码的最前面,就是语法规范中的变量预解析,防止代码出现语法错误

js语法规范中,对于函数的预解析,和函数的声明方式有关
如果表达式方式声明的函数,预解析方式和变量一致,函数声明之前,函数名称中存储的数据是undefined
如果标准方式声明的函数,JavaScript语法规范中会将整个函数进行预解析,函数名称中存储的是整个函数的声明

33.编写代码,实现一个获取元素样式的函数

function getStyle(ele,styleName) {
//判断是否是ie浏览器
  if(ele.currentStyle) {
        return ele.currentStyle[styleName]
  }else {
        return getComputedStyle(ele)[styleName]
  }
}

34简述while和do-while循环有什么区别

while循环是循环结构中的一种基本循环,通过判断条件是否为true执行循环中的代码
do-while循环是循环结构中的一种基本循环,先执行一次循环内部的代码,然后根据判断的条件是否为true决定是否继续重复执行循环中的代码
它们之间的区别在于根据条件是否满足来执行循环中代码的过程,while循环如果不满足不会执行代码;do-while循环无论条件是否满足至少会执行一次循环内部代码

35.流程控制语句有哪些

JavaScript语法规范中规定了流程控制语句主要包含顺序结构、选择结构以及循环结构
顺序结构就是从上到下依次、逐行解释并执行代码的过程
选择结构根据不同的条件执行不同的分支代码的过程,不同的分支不会同时执行,语法中主要提供了if-else和switch-case两种选择结构
循环结构根据条件是否满足重复执行某段代码块的过程,语法中主要提供了for循环、while循环、do-while循环以及for...in循环

36.定时器有哪些?它们的作用和区别都是什么?

JavaScript语法规范中提供了定时器函数,主要包含计时器函数和延时器函数
计时器函数是setInterval(),间隔指定的时间重复执行指定的函数
延时器函数是setTimeout(),指定的时间之后执行一次某个指定的函数

37.简述你对作用域链的理解

JavaScript语法规范中使用变量时,遵循就近原则,首先从当前变量所在的作用域空间查询声明变量的位置,如果没有查询到,继续向上一级作用域空间查询变量声明的位置,若还是没有查询到,继续查询JavaScript语法中变量的声明,若没有,则查询浏览器内核中是否有该变量的声明,若没有查询到就会报错:变量 is not defined!
这个查询的过程就是作用域链,局部作用域->全局作用域->JavaScript语法->浏览器

38.请简述JavaScript和ECMAScript的关系

ECMAScript是一种脚本语言语法规范和标准
JavaScript是ECMAScript语法规范/标准的一种语言实现
ECMAScript本质上是通过JavaScript指定的语法规范和标准,所以一般称呼ECMAScript的时候指定的就是JavaScript!

39.简述你对window.onload的认识

一个网页在浏览器中渲染时,首先加载HTML标签和样式,标签和样式加载完成后才会加载标签中引入的图片、字体、音频、视频等静态资源
为了保障网页中所有的数据全部加载后再执行JS代码,window.onload事件就是为保障该功能而出现的,最大程度的保障JS代码操作页面数据的正确性

40.编写代码,实现一个选项卡效果

  var uli =document.querySelector('ul').querySelectorAll('li')
    var oli =document.querySelector('ol').querySelectorAll('li')
    for(var i=0;i
  • 一号页面
  • 二号页面
  • 三号页面
  1. 1
  2. 2
  3. 3
ol li {
        display: none;
    }
    ol li:nth-child(1) {
        display: block
    }

41.写出数学对象中包含了哪些方法以及对应含义解释

Math.ceil() 向上取整
Math.floor()向下取整
Math.round() 四舍五入
Math.trunc() 截断数据
Math.max() 获取最大值
Math.min() 获取最小值
Math.random() 获取0-1之间的随机数
Math.sin()/cos()/tan() 获取对应三角函数值
Math.pow()/Math.sqrt() 求幂次方/开根号

42. 说出this的概念以及所有指向的环境

JavaScript语法中this关键字指代当前对象
全局函数中,this指向window对象
事件赋值函数中,this指向操作事件的标签
JOSN字面量对象中的函数,this指向的是JOSN字面量对象
定时器执行的函数中,this指向的是window对象

43.下面代码的输出结果是什么,为什么

function fun(x) {
  console.log("x"+x)
}
function fun(x,y) {
  console.log("x+y="+(x+y))
}

输出结果:NaN,执行了fun(x,y),x赋值为10,y没有赋值默认为undefined
JavaScript是解释型语言,解释一行执行一行,在加载函数的声明时,后面声明的同名函数会覆盖前面声明的同名函数

44.写出Date日期函数中常用的函数和对应的函数解释

var date = new Date() 获取当前系统时间
var date = new Date("2021/10/1") 根据字符串创建一个指定时间对象
var date = new Date ("2021,9.1") 根据数值对象创建一个指定时间对象
date.getFullYear()获取完整年份
date.getMonth()获取月份
date .getDate()获取一月中的第几天
date.getDay()获取星期几
date.getHours()获取小时
date.getMinues() 获取分钟
date.getSeconds()获取秒钟
date.getMilliSeconds()获取毫秒

45.编写代码,实现倒计时效果的核心代码

function auto(time) {
   var date1 = new Date()
  var date2 = new Date(time)
  var date3 = date2 - date1
  var day = parseInt(date3 / (24*60*60*1000))
  var hour = parseInt(date3  %  (24*60*60*1000)/(60*60*1000))
  var min = parseInt(date3 % (60*60*1000) / (60*1000))
  var sec = parseInt(date3 % (60*1000)/1000)
  retrun [day,hour,min,sec] 
}

46.var arr = new Array()创建的数组是(A)

A [] B [""] C [undefined] D [null]

47.var arr = new Array(false)创建的数组是(B)

A ['false'] B [false] C[0] D[]

48.[0][1]?"hello":"world"输出的结果是(D)

A null B undefined C “hello” D“world”

49.“helloworld”.substr(2,5)的结果是(A)

A "llowo" B "llow" C "llo" D null

50."helloworld".substring(2,5) 的结果是(C)

A "llowo" B "llow" C "llo" D null

51.编写一个可以获取1-任意值之间随机数的函数

function getRandom(maxNum) {
    return   Math.ceil(Math.random() * maxNum)
}

52.什么是数组的深浅拷贝

数组的拷贝,就是通过复制的方式,复用数组中的数据
浅拷贝:引用赋值,将一个数组在引用变量中存储的内存地址赋值给另一个变量,通过两个变量都可以操作这个数组中的数据
深拷贝:真实数据赋值,堆内存中直接将原始数组又复制了一个新的数组,两个数组互相独立,操作数据互不影响,代码中创建了一个新的数组,通过循环代码将原来数组的数据赋值给了新的数组
数组的拷贝主要区分了浅拷贝和深拷贝
所谓的浅拷贝实质上就是引用赋值,就是复制了数组的引用地址,所谓的深拷贝是真实的数据赋值,相当于创建了一个一模一样数据的新数组

53.数组有哪些可以操作的函数?分别有什么含义?

push()/unshift()/pop()/shift() 增加和删除数组头尾数据的函数
splice() 增加/删除/替换数组中的任意数据
join() 拼接数组中的数据
slice() 截取数组中的部分数据
indexOf()获取数组元素对应索引
sort() 数组内置的排序方法
reverse()翻转数组
Array.isArray() 判断数据是否是数组

54.编写函数,完成数组中重复数据的剔重功能

var arr = [2,3,6,6,7,3,4,5]
function fn(arr) {
    var arr2 = []
    for(var i=0;i

55.下列不是Date对象的操作函数的是(A)

A getYear()
B getMonth()
C getDay()
DgetDate()

56.不是JavaScript语言特点的是(B)

A 基于对象
B 移动端优先
C 事件驱动
D 跨平台

57 哪些不是JavaScript基本类型(B)

A String
B Float
C Number
D Null

58.正则表达式符号\w表示的是(C)

A 任意单个字符
B 任意单个字母
C 任意单个字母、数字、下划线
D 任意单个字母、数学、下划线、$符号

59.我们可以在下列哪个HTML元素中放置Javascript代码(B)

A
B
B.
C.
D.

88.分析下面代码


以下说法中正确的是(AD)
A.在页面的第二个文本框中输入内容后,当目标离开第二个文本框时,第一个文本框的内容不变
B.在页面的第一个文本框中输入内容后,当鼠标离开第一个文本框时,将在第二个文本框中复制第一个文本框的内容
C.在页面的第二个文本框中输入内容后,当鼠标离开第二个文本框时候,将在第一个文本框中复制第二个文本框的内容
D.在页面的第一个文本框中输入内容后,当鼠标离开第一个文本框时,第二个文本框的内容不变

89.列举浏览器对象模型BOM常用的至少4个对象,列举window对象常用的方法至少5个

documetnt\location\history\navigator\window
alert()/confirm()/prompt()/onload()/onresize()/onscroll()

90.说明如何使用JavaScript提交表单

表单对象.submit()

91.元素的样式、类如何改变

获取样式: 元素.currentSytle(样式名称)或者getComputedStyle(元素).样式名称
设置样式:元素.style.样式名称 = 样式值
改变类: 元素.className = “新名称”

92.什么是懒加载?

懒加载就是延迟加载,当用户触发了一定的事件之后再加载目标元素的操作

93.document.write和innerHTML的区别

document.write()会改变页面文档,不建议使用
innerHTML操作闭合标签内部内容

94.如何区分声明函数和表达式函数

function 声明函数() {}
var 变量 = function(){} //表达式函数

95.编写程序,实现点击超链接按钮后弹出一个自定义对话框

btn.onclick = function(e) {
  //获取事件对象
  var event = window.event || e
if(e.preventDefault) {
    e.preventDefault()
}else {
    e.returnValue = false
}
//改变自定义对话框样式
box.style.display = "block"
}

96.编写程序,实现自定义右键菜单

document.addEventListener('contextmenu',function(e){
    //获取时间对象,阻止默认行为
    var event =  window.event  ||e 
  if(event.preventDefault) {
  event.preventDefault()
}else {
event.returnValue = false
}
//打开自定义右键菜单
menu.style.display = "block"
menu.style.left = event.clientX + 'px'
menu.style.top = event.clientY + 'px'
})

97.编写程序,实现一个吸顶导航菜单的效果

window.onscroll = function() {
//网页卷去的高度
var st = document.documentElement.scrolTop
//菜单距离文档顶部的距离
var mt = menu.offsetTop
//判断菜单是否已经到浏览器窗口顶部
if(st >= mt) {
//固定定位,吸顶
mt.style.positon = "fixed"
mt.style.left = 0
mt.style.top = 0
}else {
//跟随网页移动
mt.style.position = 'relative'
}
}

98.什么是防抖,什么是节流,他们的区别是什么

防抖,让用户在某个超时范围内,多次频繁的事件只生效一次,降低服务开销
节流:让用户在某个超时范围内,多次频繁的事件操作降低为间隔一定时间生效一次,降低服务开销
防抖在超时范围内,多次频繁操作有一个生效频率,节流是在超时范围内,多次频繁操作有一个生效频率

99.什么是回调函数,什么情况下需要使用回调函数

回调函数,将函数作为参数传递给一个执行函数,当执行函数执行完成后根据条件来调用传递的参数,这个传递的函数就是回调函数
当执行函数需要一定的延迟时间才能得到执行结果,此时为了保障执行顺序需要通过回调函数的方式固定操作步骤和顺序

100:什么是闭包函数,什么情况下使用闭包函数

闭包函数就是一个函数的内部声明了函数,可以将当前外层函数的作用域进行扩展并且在一定的情况下常驻内存
如多功能效果开发时,多个特效之间的变量或者函数名称可能出现全局污染,需要使用闭包来屏蔽全局污染,防抖和节流中也用到了闭包函数
注:闭包函数使用后一定要审查代码,避免出现常驻内存的情况,会在运行一段时间之后导致内存溢出

你可能感兴趣的:(前端面试题2021(JS篇(上)))