js的试题及解析方法_第1页
js的试题及解析方法_第2页
js的试题及解析方法_第3页
js的试题及解析方法_第4页
js的试题及解析方法_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

js试题及解析一、单项选择题(共10题,每题1分,共10分)以下属于JavaScript原始数据类型的是?A.对象B.数组C.字符串D.函数答案:C解析:JavaScript数据类型分为原始类型和引用类型,原始类型包括undefined、null、string、number、boolean、symbol、bigint,引用类型包括对象、数组、函数等,因此C选项正确,其余三个选项均属于引用类型。执行如下代码:vara=10;functionfn(){console.log(a);vara=20;}fn();控制台输出的结果是?A.10B.20C.undefinedD.运行报错答案:C解析:var声明的变量存在变量提升,函数内部的vara声明会提升到函数作用域的最顶端,但赋值操作不会提升,因此执行console.log时,a已经被声明但还未赋值,所以输出undefined,C选项正确。执行typeofnull,返回的结果是?A.nullB.objectC.undefinedD.number答案:B解析:这是JavaScript历史遗留的设计bug,null的类型标签和对象的类型标签相同,因此typeofnull会返回object,B选项正确。非严格模式下,全局直接调用普通函数时,函数内部的this默认指向?A.函数本身B.全局window对象C.undefinedD.调用函数的参数对象答案:B解析:非严格模式下普通函数全局调用时,this默认指向window对象;严格模式下会指向undefined,因此B选项正确。以下数组方法中,会修改原数组的是?A.mapB.filterC.sliceD.splice答案:D解析:map、filter、slice都是返回新数组,不会修改原数组;splice用于对数组进行增、删、改操作,会直接修改原数组,因此D选项正确。以下属于JavaScript事件循环中宏任务的是?A.Promise.then的回调B.process.nextTick的回调C.setTimeout的回调D.async函数await后面的代码答案:C解析:宏任务包括整体script代码、setTimeout、setInterval、I/O操作、UI渲染等;微任务包括Promise.then/catch/finally、process.nextTick、MutationObserver等,因此C选项属于宏任务,其余均属于微任务。每个JavaScript函数都具备的原型相关属性是?A.protoB.prototypeC.constructorD.parent答案:B解析:prototype是函数独有的显式原型属性,指向函数的原型对象;__proto__是所有对象都有的隐式原型属性,不是函数独有;constructor是原型对象上的属性指向构造函数,因此B选项正确。关于ES6新增的let声明变量,以下说法正确的是?A.let具备块级作用域B.let存在变量提升,可以在声明前访问C.let可以在同一作用域下重复声明同一个变量D.let声明的全局变量会挂载在window对象上答案:A解析:let具备块级作用域,仅在声明的块范围内有效;不存在变量提升,声明前访问会触发暂时性死区报错;同一作用域下不能重复声明同一变量;声明的全局变量不会挂载在window上,因此A选项正确。关于箭头函数的说法,错误的是?A.箭头函数没有自己的thisB.箭头函数可以作为构造函数使用new关键字实例化C.箭头函数内部没有arguments对象D.箭头函数的this指向无法通过call方法修改答案:B解析:箭头函数没有自己的this,继承外层作用域的this,因此无法通过call、apply、bind修改this指向;没有arguments对象;没有constructor属性,不能作为构造函数使用new实例化,因此B选项说法错误。以下不属于JavaScript异步编程方案的是?A.回调函数B.PromiseC.async/awaitD.立即执行函数答案:D解析:回调函数、Promise、async/await都是常见的异步编程方案;立即执行函数是同步执行的,作用是创建私有作用域避免全局变量污染,不属于异步方案,因此D选项正确。二、多项选择题(共10题,每题2分,共20分)以下属于JavaScript引用数据类型的有?A.普通对象B.数组C.函数D.Symbol答案:ABC解析:引用数据类型存储在堆内存中,包括对象、数组、函数等;Symbol属于原始数据类型,因此ABC选项正确。不使用严格模式,以下表达式返回结果为true的有?A.[]==falseB.null==undefinedC.1==‘1’D.NaN==NaN答案:ABC解析:==比较会进行隐式类型转换,空数组转换为布尔值是false,因此[]==false为true;null和undefined宽松相等为true;数字1和字符串’1’转换后相等;NaN不等于任何值包括自身,因此D选项错误,ABC正确。以下数组遍历方法中,可以通过break关键字正常跳出循环的有?A.普通for循环B.forEachC.for…of循环D.map答案:AC解析:forEach和map遍历过程中无法通过break跳出循环,会忽略break语句或者报错;普通for循环和for…of循环都可以通过break关键字终止遍历,因此AC选项正确。以下属于ES6版本新增特性的有?A.let、const声明方式B.箭头函数C.Promise异步对象D.原型链机制答案:ABC解析:let、const、箭头函数、Promise都是ES6新增的内容;原型链是JavaScript本身就具备的核心机制,不是ES6新增,因此ABC选项正确。以下场景中,this指向调用该函数的对象的有?A.通过对象.方法的形式调用对象的方法B.全局直接调用普通函数C.点击DOM元素触发绑定的事件回调函数D.使用new关键字调用构造函数答案:ACD解析:对象方法调用时this指向该对象;事件回调函数的this指向绑定事件的DOM元素;构造函数的this指向new出来的实例对象;全局调用普通函数时this指向window(非严格模式),不属于调用对象,因此ACD选项正确。以下属于闭包的核心特性的有?A.可以访问另一个函数作用域内的变量B.被引用的外层函数变量不会被垃圾回收机制回收C.可以用来封装私有变量和方法D.一定会造成内存泄漏答案:ABC解析:闭包是有权访问另一个函数作用域变量的函数,被引用的外层变量不会被回收,因此可以用来封装私有变量,避免全局污染;只有滥用闭包且没有手动清理引用时才会造成内存泄漏,属于不当使用的后果,不是闭包本身的特性,因此ABC选项正确。以下属于Promise合法状态的有?A.pending(等待中)B.fulfilled(已成功)C.rejected(已失败)D.cancelled(已取消)答案:ABC解析:Promise只有三种状态,分别是等待中pending、已成功fulfilled、已失败rejected,状态一旦变更就不会再改变,不存在cancelled状态,因此ABC选项正确。关于localStorage和sessionStorage的说法,正确的有?A.localStorage存储的数据除非手动删除,否则会永久保留B.sessionStorage存储的数据在当前页面关闭后就会被清除C.两者的存储容量上限都在5MB左右D.两者都可以跨域名共享数据答案:ABC解析:localStorage是持久化存储,手动删除才会消失;sessionStorage是会话级存储,页面关闭就清除;两者存储容量都在5MB左右;两者都遵循同源策略,不能跨域名共享数据,因此ABC选项正确。以下typeof表达式的返回值正确的有?A.typeof‘123’返回‘string’B.typeof123返回‘number’C.typeof[]返回‘array’D.typeoffunction(){}返回‘function’答案:ABD解析:typeof检测字符串返回’string’,检测数字返回’number’,检测函数返回’function’;typeof检测数组会返回’object’,不是’array’,因此ABD选项正确。关于防抖和节流的说法,正确的有?A.防抖的逻辑是多次高频触发事件后,只执行最后一次触发的回调B.节流的逻辑是规定时间内,无论触发多少次事件,只执行一次回调C.防抖适合应用在输入框实时搜索联想的场景D.节流适合应用在滚动监听加载更多的场景答案:ABCD解析:防抖是合并多次触发为最后一次,适合输入框搜索、窗口大小调整结束后渲染等场景;节流是限制触发频率,固定时间内只执行一次,适合滚动加载、高频点击等场景,四个选项的说法均正确。三、判断题(共10题,每题1分,共10分)JavaScript是一门静态类型的编程语言。答案:错误解析:JavaScript是动态类型语言,变量的类型可以在运行时动态修改,不需要在声明时指定变量类型;静态类型语言需要在声明时指定类型,运行时不允许随意修改类型。使用const声明的常量,其值一定不能被修改。答案:错误解析:const声明的基本类型变量,确实不能重新赋值;但const声明的引用类型变量,只是限制了引用地址不能修改,引用对象内部的属性、数组元素等内容是可以修改的。setTimeout的回调函数一定会在设置的延迟时间之后准时执行。答案:错误解析:JavaScript是单线程语言,事件循环机制中,setTimeout的回调到了延迟时间后,会进入宏任务队列,需要等主线程执行栈的任务全部执行完毕、微任务清空后才会执行,如果主线程有阻塞任务,回调就会延迟执行,不能保证准时。JavaScript原型链的顶端是null。答案:正确解析:所有对象的隐式原型__proto__最终都会指向Ototype,而Ototype.__proto__指向null,因此原型链的顶端是null。async函数的返回值一定是一个Promise对象。答案:正确解析:不管async函数内部return的是什么类型的值,都会被自动包装成Promise对象;如果return的是非Promise值,会被包装成状态为fulfilled的Promise对象。for…in循环可以遍历到数组的所有可枚举属性,包括原型链上的可枚举属性。答案:正确解析:for…in循环的遍历规则是遍历对象所有的可枚举属性,包括自身定义的和原型链上继承的,因此遍历数组时如果给数组原型添加了可枚举属性,也会被for…in遍历到。JavaScript的垃圾回收机制只会回收没有被引用的对象,因此两个对象互相引用就一定会造成内存泄漏。答案:错误解析:现在主流浏览器的垃圾回收采用标记清除法,会从根对象(比如window)开始遍历,所有能被访问到的对象都会被标记为存活,不能被访问到的对象就算互相引用,也会被回收,因此互相引用不一定会造成内存泄漏。箭头函数的this指向是在函数定义的时候确定的,不会随着调用方式的改变而改变。答案:正确解析:箭头函数没有自己的this,会继承外层作用域的this,因此定义的时候就已经确定了this指向,call、apply、bind方法都无法修改箭头函数的this指向。在JavaScript中,0.1+0.2===0.3的返回结果是true。答案:错误解析:JavaScript采用双精度浮点数存储数字,0.1和0.2转换为二进制是无限循环小数,存储时会有精度损失,相加后的结果是0.30000000000000004,不等于0.3,因此返回false。事件委托是利用事件冒泡的机制,将子元素的事件绑定到父元素上统一处理。答案:正确解析:事件触发后会从触发元素向上冒泡到父元素、祖先元素,因此可以将子元素的事件绑定到父元素,通过判断事件触发源来执行对应逻辑,减少事件绑定数量,还可以处理动态新增的子元素的事件。四、简答题(共5题,每题6分,共30分)简述var、let、const三者的区别。答案:第一,作用域不同,var的作用域是函数作用域,仅在所在函数内部有效;let和const的作用域是块级作用域,在if、for等大括号包裹的块范围内生效。第二,变量提升不同,var存在变量提升,可以在声明前访问,值为undefined;let和const存在暂时性死区,在声明前访问会直接报错。第三,重复声明规则不同,var可以在同一作用域下重复声明同一个变量,后声明的会覆盖之前的;let和const在同一作用域下不允许重复声明同一个变量。第四,重新赋值规则不同,var和let声明的变量可以随意重新赋值;const声明的基本类型变量不能重新赋值,引用类型变量可以修改内部内容但不能修改引用地址。解析:以上四点是三者的核心区别,实际开发中优先使用const,需要修改值的场景使用let,尽量避免使用var,减少变量污染和逻辑错误。简述什么是闭包,以及闭包的常见应用场景。答案:第一,闭包的定义:闭包是指有权访问另一个函数作用域内变量的函数,本质是函数嵌套时,内层函数引用了外层函数的变量,导致外层函数执行完毕后,被引用的变量不会被垃圾回收机制回收。第二,应用场景一:封装私有变量和方法,避免全局变量污染,外层函数的变量只能通过闭包暴露的方法访问和修改,无法直接被外部操作。第三,应用场景二:实现函数柯里化,固定部分参数生成新的函数,提升函数的复用性,比如创建固定前缀的字符串拼接函数。第四,应用场景三:保存异步操作的上下文,解决循环绑定事件时索引值错误的问题,比如循环给多个元素绑定点击事件,用闭包保存每次循环的索引值。解析:闭包是JavaScript作用域的核心应用,合理使用可以实现很多灵活的功能,但使用后要注意及时清理不需要的引用,避免内存泄漏。简述JavaScript的事件循环机制(包含宏任务、微任务的执行顺序)。答案:第一,基础规则:JavaScript是单线程语言,同一时间只能执行一个任务,为了避免阻塞,任务分为同步任务和异步任务,同步任务直接在主线程执行栈中依次执行,异步任务会进入任务队列等待调度。第二,异步任务分类:异步任务分为宏任务和微任务,宏任务包括整体script代码、setTimeout、setInterval、I/O操作、UI渲染等;微任务包括Promise.then/catch/finally、process.nextTick、MutationObserver等。第三,执行顺序:首先执行当前执行栈中的所有同步任务,同步任务执行完毕后,依次清空当前所有的微任务;之后从宏任务队列中取出第一个宏任务执行,执行完一个宏任务后再次清空所有微任务,不断循环这个过程,就是事件循环。解析:事件循环是JavaScript异步执行的核心机制,掌握执行顺序可以避免异步代码的逻辑错误,比如多个异步任务嵌套时可以准确判断执行顺序。简述原型和原型链的作用。答案:第一,prototype显式原型的作用:每个函数都有prototype属性,指向函数的原型对象,原型对象上存储的属性和方法可以被所有实例共享,避免每个实例都重复创建相同的方法,节省内存空间。第二,__proto__隐式原型的作用:每个对象都有__proto__隐式原型属性,指向其构造函数的prototype属性,是实现属性继承和查找的桥梁。第三,原型链的作用:当访问对象的属性或方法时,首先在对象自身查找,如果找不到就会去__proto__指向的原型对象上查找,还找不到就继续查找原型对象的__proto__,直到顶端的null,这个查找链路就是原型链,实现了JavaScript的继承机制。解析:原型和原型链是JavaScript面向对象编程的核心,比如数组的所有内置方法都存储在Atotype上,所有数组实例都可以直接调用这些方法,不需要单独创建。简述防抖和节流的区别,以及各自的适用场景。答案:第一,防抖的逻辑:高频事件触发后,会等待n秒再执行回调,如果n秒内再次触发该事件,就会重新计算等待时间,最终只执行最后一次触发的回调。第二,节流的逻辑:高频事件触发后,规定n秒内只会执行一次回调,n秒内的重复触发都会被忽略,直到过了n秒后才能再次触发执行。第三,防抖的适用场景:输入框实时搜索联想(避免每输入一个字符就请求一次接口,等用户输入停止后再请求)、窗口大小调整结束后重新渲染页面、按钮多次提交只执行最后一次等。第四,节流的适用场景:滚动事件监听加载更多(避免滚动一次就触发多次,固定时间内只执行一次)、鼠标高频点击按钮限制触发频率、拖拽元素时实时计算位置等。解析:防抖和节流都是优化高频事件的核心手段,核心区别是防抖合并多次触发为最后一次,节流限制触发频率,根据场景选择可以大幅减少不必要的函数执行,提升页面性能。五、论述题(共3题,每题10分,共30分)结合实例论述JavaScript中this的指向规则,以及修改this指向的常用方法。答案:论点1:this的指向是在函数调用时确定的,和定义位置无关,不同调用场景有不同的指向规则论据:第一种场景:全局调用普通函数,非严格模式下this指向全局window对象,严格模式下指向undefined。比如定义函数functionfn(){console.log(this)},直接调用fn(),非严格模式下会输出window,严格模式输出undefined。第二种场景:对象方法调用,this指向调用该方法的对象。比如定义对象constobj={name:‘测试’,fn:function(){console.log()}},调用obj.fn()时,this指向obj,输出“测试”。第三种场景:构造函数调用,this指向new关键字创建的实例对象。比如定义构造函数functionPerson(name){=name},执行constp=newPerson(‘张三’)时,this指向实例p,因此的值为“张三”。第四种场景:箭头函数调用,箭头函数没有自己的this,继承外层作用域的this,定义时就确定,不会随调用方式改变。比如定义constobj={fn:()=>{console.log(this)}},调用obj.fn()时,因为对象的大括号没有独立作用域,外层是全局作用域,因此this指向window。论点2:可以通过call、apply、bind三个方法修改普通函数的this指向论据:三个方法都可以修改普通函数的this指向,区别在于执行方式和传参形式:call方法会立即执行函数,第一个参数是指定的this指向,后续参数逐个传入。比如定义functiongetInfo(age,gender){console.log(,age,gender)},constuser={name:‘李四’},执行getInfo.call(user,18,‘男’),this会指向user,输出“李四18男”。apply方法会立即执行函数,第一个参数是指定的this指向,第二个参数是参数数组。比如执行getInfo.apply(user,[18,‘男’]),效果和call一致,输出内容相同。bind方法不会立即执行函数,会返回一个修改了this指向的新函数,需要手动调用执行。比如constnewGetInfo=getInfo.bind(user,18,‘男’),执行newGetInfo()后才会输出对应内容。结论:掌握this的指向规则可以避免大量上下文逻辑错误,灵活使用三个修改this的方法,可以实现函数的复用,适配不同的业务场景。结合实例论述Promise解决了什么问题,以及Promise链式调用的原理。答案:论点1:Promise解决了传统异步编程的回调地狱问题,提升了异步代码的可读性和可维护性论据:传统异步编程依赖回调函数实现,当多个异步任务有依赖关系时,就会出现多层回调嵌套,也就是回调地狱。比如需要实现依次请求三个接口:先请求接口A获取用户id,再用用户id请求接口B获取订单id,再用订单id请求接口C获取订单详情,传统回调写法如下:jsajax(‘/api/user’,(resA)=>{ajax(/api/order?userId=${resA.id},(resB)=>{ajax(/api/orderDetail?orderId=${resB.id},(resC)=>{console.log(resC)},err=>{console.log(‘接口C错误’,err)})},err=>{console.log(‘接口B错误’,err)})},err=>{console.log(‘接口A错误’,err)})这种写法代码横向扩展,可读性差,错误处理分散,维护成本高。而Promise可以将嵌套的回调改成纵向的链式调用,代码结构清晰,错误处理统一。论点2:Promise链式调用的核心原理是每个then方法都会返回一个新的Promise对象论据:Promise的then方法执行后会返回一个全新的Promise对象,因此可以继续调用then方法,形成链式结构。如果then的回调函数返回的是普通值,会被包装成状态为fulfilled的Promise,作为下一个then的参数;如果返回的是Promise对象,下一个then会等待该Promise状态变更后再执行。同样的三个接口请求用Promise链式调用的写法如下:jsfetch(‘/api/user’).then(res=>res.json()).then(resA=>fetch(/api/order?userId=${resA.id})).then(res=>res.json()).then(resB=>fetch(/api/orderDetail?orderId=${resB.id})).then(res=>res.json()).then(resC=>console.log(resC)).catch(err=>console.log(‘任意环节错误’,err))这种结构纵向扩展,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论