版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2026年《js的基础面试题及答案》(含解析)一、单项选择题(每题3分,共30分)1.以下关于JavaScript数据类型的描述中,哪一项是错误的?A.`Symbol`是ES6引入的一种新的原始数据类型,表示独一无二的值。B.`BigInt`可以用来表示超出`Number`安全整数范围的大整数。C.`null`和`undefined`在进行宽松相等(`==`)比较时,结果为`false`。D.`Array`在JavaScript中本质上是一种特殊的`Object`。答案:C解析:本题考查JavaScript的基础数据类型与类型转换。在JavaScript中,`null==undefined`的结果是`true`。这是因为在宽松相等比较中,ECMAScript规范规定两者会相互转换并视为相等。选项A、B、D的描述均是正确的。`Symbol`确实是ES6新增的原始类型;`BigInt`用于处理大整数;`Array`的原型链指向`Object`,且`typeof[]`返回`'object'`,因此它是特殊的对象。2.执行以下代码,控制台输出的结果是?```javascriptvara=[];console.log(a==false);```A.`true`B.`false`C.`undefined`D.`TypeError`答案:A解析:本题考查抽象相等比较算法。当数组(对象)与布尔值进行比较时:1.首先将布尔值转换为数字:`false`变为`0`。2.比较变为`[]==0`。3.当对象与原始值比较时,对象先调用`ToPrimitive`。对于空数组`[]`,其`valueOf()`返回数组自身(非原始值),因此转而调用`toString()`,返回空字符串`""`。4.比较变为`""==0`。5.将字符串转换为数字:空字符串变为`0`。6.最终比较`0==0`,结果为`true`。3.关于ES6模块化(ESModules)与CommonJS的区别,以下说法正确的是?A.CommonJS是运行时加载,ESModules是编译时输出接口。B.CommonJS支持`exportdefault`语法。C.ESModules中的`this`指向全局对象(非严格模式下)。D.CommonJSrequire的模块可以被动态修改,且影响其他require该模块的地方。答案:A解析:选项A正确:CommonJS加载的是整个模块对象(运行时同步加载),而ESModules是静态分析,在编译时就确定模块的依赖关系和输出接口,支持TreeShaking。选项A正确:CommonJS加载的是整个模块对象(运行时同步加载),而ESModules是静态分析,在编译时就确定模块的依赖关系和输出接口,支持TreeShaking。选项B错误:`exportdefault`是ESModules的语法,CommonJS使用`module.exports`。选项B错误:`exportdefault`是ESModules的语法,CommonJS使用`module.exports`。选项C错误:ESModules模块代码默认运行在严格模式下,且`this`在顶层作用域中为`undefined`,不会指向全局对象。选项C错误:ESModules模块代码默认运行在严格模式下,且`this`在顶层作用域中为`undefined`,不会指向全局对象。选项D错误:CommonJS缓存的是模块的输出值的拷贝(对于基本类型)或引用(对于对象)。虽然修改对象的属性会影响其他引用,但模块本身一旦加载就会被缓存,重新`require`不会再次执行模块代码,除非清除缓存。但ESModules导出的是值的只读引用(LiveBindings),这是两者的重要区别。选项D错误:CommonJS缓存的是模块的输出值的拷贝(对于基本类型)或引用(对于对象)。虽然修改对象的属性会影响其他引用,但模块本身一旦加载就会被缓存,重新`require`不会再次执行模块代码,除非清除缓存。但ESModules导出的是值的只读引用(LiveBindings),这是两者的重要区别。4.下列关于Promise的状态描述,不正确的是?A.Promise对象有三种状态:pending、fulfilled(或resolved)和rejected。B.状态一旦改变,就不会再变。C.`Promise.resolve().then(()=>{})`返回的Promise状态一定是fulfilled。D.`Promise.reject()`后跟`.catch()`可以捕获错误,但如果在`.then`中抛出错误,也可以被后续的`.catch`捕获。答案:C解析:选项A、B正确:这是Promise的核心特性,状态具有不可逆性。选项A、B正确:这是Promise的核心特性,状态具有不可逆性。选项C错误:`Promise.resolve().then(callback)`返回的Promise状态取决于`callback`的执行结果。如果`callback`内部抛出错误,返回的Promise状态就是`rejected`;如果返回的是一个新的Promise,则状态由该Promise决定。因此不一定是fulfilled。选项C错误:`Promise.resolve().then(callback)`返回的Promise状态取决于`callback`的执行结果。如果`callback`内部抛出错误,返回的Promise状态就是`rejected`;如果返回的是一个新的Promise,则状态由该Promise决定。因此不一定是fulfilled。选项D正确:Promise的错误冒泡机制允许`.then`中的错误被后续最近的`.catch`捕获。选项D正确:Promise的错误冒泡机制允许`.then`中的错误被后续最近的`.catch`捕获。5.在浏览器环境中,`console.log(typeofNaN)`的输出是?A.`'undefined'`B.`'number'`C.`'NaN'`D.`'object'`答案:B解析:`NaN`(NotaNumber)是JavaScript中全局对象的一个属性,其本身就是`Number`类型。虽然它表示“非数字”,但从数据类型上讲,它是数字类型。这是一个经典的面试陷阱题。6.以下代码执行后,`arr`的值是?```javascriptletarr=[1,2,3];arr.map(num=>num2).filter(num=>num>4);arr.map(num=>num2).filter(num=>num>4);```A.`[1,2,3]`B.`[2,4,6]`C.`[6]`D.`[4,6]`答案:A解析:本题考查数组方法的纯函数特性。`map`和`filter`方法都不会改变原数组,而是返回一个新的数组。代码中虽然调用了这两个方法,但没有将返回值赋值给`arr`,也没有使用返回值,因此`arr`保持原值`[1,2,3]`不变。7.关于JavaScript的事件循环(EventLoop),以下描述正确的是?A.宏任务和微任务都存放在同一个任务队列中,按照先进先出原则执行。B.`setTimeout`属于微任务。C.当前宏任务执行完毕后,会立即清空微任务队列。D.`Promise.then`属于宏任务。答案:C解析:选项A错误:宏任务和微任务存放在不同的队列中。选项A错误:宏任务和微任务存放在不同的队列中。选项B错误:`setTimeout`属于宏任务。选项B错误:`setTimeout`属于宏任务。选项C正确:这是事件循环的核心机制。每次从宏任务队列中取出一个任务执行完毕后,引擎会检查微任务队列,如果存在微任务,会依次执行队列中的所有微任务,直到微任务队列为空,然后开始下一轮宏任务调度(如UI渲染)。选项C正确:这是事件循环的核心机制。每次从宏任务队列中取出一个任务执行完毕后,引擎会检查微任务队列,如果存在微任务,会依次执行队列中的所有微任务,直到微任务队列为空,然后开始下一轮宏任务调度(如UI渲染)。选项D错误:`Promise.then`属于微任务。选项D错误:`Promise.then`属于微任务。8.以下关于`this`指向的代码,输出结果为?```javascriptvarname='global';constobj={name:'obj',getName:function(){return;}};constfn=obj.getName;console.log(fn());```A.`'obj'`B.`'global'`C.`undefined`D.报错答案:B解析:本题考查`this`的隐式绑定丢失。`fn`是`obj.getName`的引用,但在调用`fn()`时,它是作为普通函数调用的,没有明确的调用者(上下文对象)。在非严格模式下,独立函数调用的`this`指向全局对象(浏览器中为`window`),因此``访问的是全局变量`name`,即`'global'`。如果是严格模式(`'usestrict'`),结果将是`undefined`。9.下列哪个方法可以创建一个具有指定原型的新对象?A.`Object.create(null)`B.`Object.assign(null)`C.`Object.setPrototypeOf(null)`D.`Object.defineProperties(null)`答案:A解析:`Object.create(proto)`方法用于创建一个新对象,使用现有的对象来提供新创建的对象的`__proto__`。`Object.create(null)`会创建一个真正空的对象,没有原型链,常用于作为字典使用以避免原型污染。`Object.assign`用于属性复制,`Object.setPrototypeOf`用于设置原型,`Object.defineProperties`用于定义属性,它们都不主要用于“创建具有指定原型的新对象”这一特定目的。10.以下代码的输出结果是?```javascriptfunctionfoo(){console.log(a);vara=10;console.log(a);}foo();```A.`undefined`,`10`B.`ReferenceError`,`10`C.`undefined`,`undefined`D.`10`,`10`答案:A解析:本题考查变量提升。在函数作用域内,`vara`的声明会被提升到函数顶部,但赋值操作留在原处。因此,代码执行逻辑等价于:```javascriptfunctionfoo(){vara;//声明提升,未赋值,默认为undefinedconsole.log(a);//输出undefineda=10;console.log(a);//输出10}```第一个`console.log`输出`undefined`,第二个输出`10`。二、多项选择题(每题5分,共25分。多选、少选、错选不得分)1.以下哪些是JavaScript防止XSS攻击的常见手段?A.在将用户输入输出到HTML之前进行转义。B.使用`textContent`代替`innerHTML`插入文本。C.设置ContentSecurityPolicy(CSP)头。D.使用`eval()`函数动态解析字符串。答案:A,B,C解析:A、B正确:XSS(跨站脚本攻击)的核心是注入恶意脚本。转义特殊字符(如`<`,`>`,`&`,`"`,`'`)可以防止脚本标签被解析;使用`textContent`会将内容作为纯文本处理,不会解析HTML标签。A、B正确:XSS(跨站脚本攻击)的核心是注入恶意脚本。转义特殊字符(如`<`,`>`,`&`,`"`,`'`)可以防止脚本标签被解析;使用`textContent`会将内容作为纯文本处理,不会解析HTML标签。C正确:CSP是一种额外的安全层,用于检测并削弱某些特定类型的攻击,包括XSS和数据注入攻击。它可以限制资源加载来源(如禁止执行内联脚本)。C正确:CSP是一种额外的安全层,用于检测并削弱某些特定类型的攻击,包括XSS和数据注入攻击。它可以限制资源加载来源(如禁止执行内联脚本)。D错误:`eval()`可以执行动态字符串代码,这是极不安全的做法,极易被利用进行XSS注入,应当极力避免。D错误:`eval()`可以执行动态字符串代码,这是极不安全的做法,极易被利用进行XSS注入,应当极力避免。2.关于ES6+新特性,以下说法正确的有?A.`let`和`const`声明的变量具有“暂时性死区”(TDZ)特性。B.箭头函数没有自己的`arguments`对象,但可以通过rest参数`...args`获取参数。C.`Atotype.includes()`方法可以用来检测数组是否包含NaN。D.`Object.is()`与`===`的行为完全一致。答案:A,B,C解析:A正确:TDZ指在变量声明之前访问该变量会导致ReferenceError,这对于`let`和`const`是成立的。A正确:TDZ指在变量声明之前访问该变量会导致ReferenceError,这对于`let`和`const`是成立的。B正确:箭头函数没有自己的`arguments`,它会继承外层作用域的`arguments`(如果外层是普通函数)。要获取参数,推荐使用`...args`。B正确:箭头函数没有自己的`arguments`,它会继承外层作用域的`arguments`(如果外层是普通函数)。要获取参数,推荐使用`...args`。C正确:`includes`方法使用SameValueZero算法,能够正确识别NaN,这是`indexOf`做不到的。C正确:`includes`方法使用SameValueZero算法,能够正确识别NaN,这是`indexOf`做不到的。D错误:`Object.is()`与`===`大部分情况下一致,但有两点不同:`Object.is(NaN,NaN)`为`true`(`===`为`false`);`Object.is(+0,-0)`为`false`(`===`为`true`)。D错误:`Object.is()`与`===`大部分情况下一致,但有两点不同:`Object.is(NaN,NaN)`为`true`(`===`为`false`);`Object.is(+0,-0)`为`false`(`===`为`true`)。3.下列关于DOM事件流的描述,正确的有?A.事件流包括三个阶段:捕获阶段、目标阶段、冒泡阶段。B.`addEventListener`的第三个参数设置为`true`表示在捕获阶段触发事件处理函数。C.阻止事件冒泡可以使用`event.stopPropagation()`。D.`event.preventDefault()`可以阻止事件冒泡。答案:A,B,C解析:A正确:这是DOM2级事件规定的事件流模型。A正确:这是DOM2级事件规定的事件流模型。B正确:`addEventListener(type,handler,useCapture)`,`useCapture`为`true`时在捕获阶段触发。B正确:`addEventListener(type,handler,useCapture)`,`useCapture`为`true`时在捕获阶段触发。C正确:`stopPropagation`是阻止事件进一步传播(冒泡或捕获)的标准方法。C正确:`stopPropagation`是阻止事件进一步传播(冒泡或捕获)的标准方法。D错误:`preventDefault()`用于取消事件的默认行为(如链接跳转、表单提交),它不会阻止事件的冒泡传播。D错误:`preventDefault()`用于取消事件的默认行为(如链接跳转、表单提交),它不会阻止事件的冒泡传播。4.以下哪些操作会导致浏览器触发重排?A.改变元素的`width`或`height`。B.改变元素的`color`。C.改变元素的`top`或`left`(定位元素)。D.读取元素的`offsetWidth`。答案:A,C,D解析:重排会涉及页面布局的计算,开销较大。重排会涉及页面布局的计算,开销较大。A、C正确:改变元素尺寸或位置会导致布局变化,触发重排。A、C正确:改变元素尺寸或位置会导致布局变化,触发重排。B错误:改变颜色通常只触发重绘,不涉及布局变化。B错误:改变颜色通常只触发重绘,不涉及布局变化。D正确:这是一个常见的性能陷阱。浏览器为了获取准确的布局信息(如`offsetWidth`),必须强制执行之前队列中待处理的布局变更(强制同步布局),从而触发重排。D正确:这是一个常见的性能陷阱。浏览器为了获取准确的布局信息(如`offsetWidth`),必须强制执行之前队列中待处理的布局变更(强制同步布局),从而触发重排。5.以下关于闭包的理解,正确的有?A.闭包可以访问外部函数作用域中的变量。B.闭包会导致被引用的外部变量无法被垃圾回收机制回收,可能引起内存泄漏。C.闭包只能通过函数嵌套函数的方式创建。D.闭包常用于创建私有变量和数据封装。答案:A,B,D解析:A正确:这是闭包的定义,即函数能够记住并访问其词法作用域。A正确:这是闭包的定义,即函数能够记住并访问其词法作用域。B正确:如果闭包一直被引用(例如绑定在全局事件上),它所携带的作用域链中的变量就不会被释放,若不注意管理可能导致内存占用过高。B正确:如果闭包一直被引用(例如绑定在全局事件上),它所携带的作用域链中的变量就不会被释放,若不注意管理可能导致内存占用过高。C错误:虽然通常通过函数嵌套创建,但理论上只要是在词法作用域外访问了内部作用域变量的行为,都涉及闭包机制。但在JS中最典型的创建方式确实是函数嵌套。但在现代JS视角下,C的表述略显绝对,但在常规面试语境下,通常认为闭包就是函数嵌套。不过,更严谨地说,闭包是函数+词法环境。但选项C说“只能”略显绝对,但在常规基础题中,往往被认为是主要创建方式。然而,更准确的是,闭包是必然产生的。但在这里,我们主要关注其特性。选项C在某些严格定义下有争议,但相比之下A、B、D是无可争议的正确特性。修正:实际上,JS中函数创建时就形成了闭包(如果存在外层作用域),不仅仅是“嵌套”才创建。但通常面试中“创建闭包”指的是利用该特性。为了稳妥,我们选A、B、D。C错误:虽然通常通过函数嵌套创建,但理论上只要是在词法作用域外访问了内部作用域变量的行为,都涉及闭包机制。但在JS中最典型的创建方式确实是函数嵌套。但在现代JS视角下,C的表述略显绝对,但在常规面试语境下,通常认为闭包就是函数嵌套。不过,更严谨地说,闭包是函数+词法环境。但选项C说“只能”略显绝对,但在常规基础题中,往往被认为是主要创建方式。然而,更准确的是,闭包是必然产生的。但在这里,我们主要关注其特性。选项C在某些严格定义下有争议,但相比之下A、B、D是无可争议的正确特性。修正:实际上,JS中函数创建时就形成了闭包(如果存在外层作用域),不仅仅是“嵌套”才创建。但通常面试中“创建闭包”指的是利用该特性。为了稳妥,我们选A、B、D。D正确:利用闭包特性,模拟私有方法是JS中常见的模块模式。D正确:利用闭包特性,模拟私有方法是JS中常见的模块模式。三、填空题(每题3分,共15分)1.在JavaScript中,`2**3`的计算结果是\_\_\_\_\_\_\_\_。1.在JavaScript中,`2**3`的计算结果是\_\_\_\_\_\_\_\_。答案:8解析:`**`是ES6引入的幂运算符,等同于`Math.pow(2,3)`,即=82.表达式`'b'+'a'++'a'+'a'`的结果是\_\_\_\_\_\_\_\_。答案:baNaNa解析:这是一个有趣的字符串运算题。1.`'b'+'a'`得到`'ba'`。2.`+'a'`:一元加号尝试将字符串转换为数字。`'a'`无法转换为有效数字,结果为`NaN`。3.`'ba'+NaN`:字符串与数字相加,数字转为字符串`'NaN'`。结果为`'baNaN'`。4.`'baNaN'+'a'`:结果为`'baNaNa'`。3.要判断变量`x`是否为数组实例,最准确的方法是使用\_\_\_\_\_\_\_\_。答案:Array.isArray(x)解析:`Array.isArray()`是ES5提供的检测数组的最准确方法,它能避免跨iframe问题(`instanceof`在不同执行环境下会失效)。4.在ES6中,用于声明类的关键字是\_\_\_\_\_\_\_\_,而用于继承类的关键字是\_\_\_\_\_\_\_\_。答案:class,extends解析:ES6引入了`class`语法糖来定义类,使用`extends`关键字实现继承。5.JavaScript中,所有对象都继承自\_\_\_\_\_\_\_\_原型对象(除了通过`Object.create(null)`创建的对象)。答案:Ototype解析:原型链的顶端是`Ototype`,`Ototype.__proto__`为`null`。四、简答题(每题8分,共40分)1.请简述`var`、`let`和`const`的区别。答案与解析:1.作用域:`var`具有函数作用域,即在函数内声明的变量在整个函数内都可见,容易导致变量泄露到块级作用域外(如`if`或`for`循环外)。`var`具有函数作用域,即在函数内声明的变量在整个函数内都可见,容易导致变量泄露到块级作用域外(如`if`或`for`循环外)。`let`和`const`具有块级作用域,仅在声明所在的代码块(`{}`)内有效。`let`和`const`具有块级作用域,仅在声明所在的代码块(`{}`)内有效。2.变量提升:`var`存在变量提升,变量可以在声明之前使用(值为`undefined`)。`var`存在变量提升,变量可以在声明之前使用(值为`undefined`)。`let`和`const`存在“暂时性死区”(TDZ),在声明之前使用会抛出`ReferenceError`。`let`和`const`存在“暂时性死区”(TDZ),在声明之前使用会抛出`ReferenceError`。3.重复声明:`var`允许在相同作用域内重复声明。`var`允许在相同作用域内重复声明。`let`和`const`不允许在相同作用域内重复声明,否则报错。`let`和`const`不允许在相同作用域内重复声明,否则报错。4.初始值与修改:`var`和`let`声明变量时可以不初始化,且值可以修改。`var`和`let`声明变量时可以不初始化,且值可以修改。`const`声明时必须初始化,且一旦声明,其引用的内存地址不可变(即对于基本类型值不可变,对于引用类型,属性可以修改,但不能重新赋值)。`const`声明时必须初始化,且一旦声明,其引用的内存地址不可变(即对于基本类型值不可变,对于引用类型,属性可以修改,但不能重新赋值)。2.什么是原型链?它是如何工作的?答案与解析:原型链是JavaScript实现继承的主要机制,也是其核心特性之一。定义:JavaScript对象有一个内置属性`[[Prototype]]`(在代码中通常通过`__proto__`访问),指向它的原型对象。当我们访问一个对象的属性或方法时,如果对象本身不存在该属性,JavaScript引擎就会沿着`__proto__`指针向上一级查找,直到找到该属性或查找到顶层对象(`Ototype`)。如果顶层也没有,则返回`undefined`。这种层层向上的链式结构就称为原型链。工作原理:1.假设我们要读取`obj.toString()`。2.引擎首先检查`obj`自身是否有`toString`属性。3.如果没有,引擎去`obj.__proto__`(即`obj`的构造函数的`prototype`)中查找。4.如果还没找到,继续沿着原型链向上查找,直到`Ototype`。5.`Ototype`中通常包含`toString`等方法,于是找到并使用。6.如果直到`Ototype.__proto__`(即`null`)都没找到,则确认为不存在。3.请解释JavaScript中的“事件循环”机制,特别是宏任务和微任务的执行顺序。答案与解析:JavaScript是单线程语言,为了处理异步操作且不阻塞主线程,采用了事件循环机制。任务分类:同步任务:在主线程上立即执行的任务。异步任务:不进入主线程,而是进入任务队列等待执行。异步任务分为:宏任务:包括`script`(整体代码)、`setTimeout`、`setInterval`、`setImmediate`(Node.js)、I/O、UIRendering。微任务:包括`Promise.then/catch/finally`、`process.nextTick`(Node.js)、`MutationObserver`。执行顺序:1.执行主线程中的同步代码(这被视为第一个宏任务)。2.同步代码执行完毕后,主线程空闲。3.检查微任务队列:如果微任务队列中有任务,依次执行队列中的所有微任务,直到队列清空。4.UI渲染:浏览器通常会根据需要在微任务执行后进行页面渲染(并非每次循环都渲染)。5.检查宏任务队列:从宏任务队列中取出一个任务放入主线程执行。6.执行完该宏任务后,再次回到步骤3(检查微任务队列)。总结:同步->所有微任务->渲染->一个宏任务->所有微任务->...总结:同步->所有微任务->渲染->一个宏任务->所有微任务->...4.什么是防抖和节流?请写出它们的区别及应用场景。答案与解析:防抖和节流都是用于控制函数执行频率的高阶函数,主要用于优化性能,避免因高频触发事件(如resize、scroll、input)导致函数执行过于频繁。防抖:原理:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。效果:将多次触发合并为最后一次触发后的一次执行。应用场景:搜索框输入联想(用户停止输入后再发送请求)、窗口resize结束后计算布局、防止按钮重复点击。节流:原理:规定在一个单位时间内,只能触发一次函数回调。如果这个单位时间内触发多次,只有一次生效。效果:稀释触发频率,保证以固定频率执行。应用场景:滚动条加载更多(每隔一段距离加载一次)、鼠标移动计算位置、高频点击防止请求过多(如抢购)。区别:防抖是将“多次执行”变为“最后一次执行”;防抖是将“多次执行”变为“最后一次执行”;节流是将“多次执行”变为“每隔一段时间执行一次”。节流是将“多次执行”变为“每隔一段时间执行一次”。5.请简述`call`、`apply`和`bind`的作用及区别。答案与解析:三者都是`Ftotype`上的方法,用于改变函数内部`this`的指向。共同点:都可以指定函数执行时的`this`上下文。区别:`call(fn,thisArg,arg1,arg2,...)`:立即执行函数。立即执行函数。参数是逐个列举的。参数是逐个列举的。`apply(fn,thisArg,[argsArray])`:立即执行函数。立即执行函数。参数以数组(或类数组对象)形式传递。参数以数组(或类数组对象)形式传递。`bind(fn,thisArg,arg1,arg2,...)`:不会立即执行函数,而是返回一个新的函数(绑定函数)。新函数的`this`被永久绑定(除非使用`new`调用)。新函数的`this`被永久绑定(除非使用`new`调用)。支持部分传参(柯里化)。支持部分传参(柯里化)。五、阅读代码题(每题10分,共30分)1.请写出以下代码的输出结果,并解释原因。```javascriptasyncfunctionasync1(){console.log('async1start');awaitasync2();console.log('async1end');}asyncfunctionasync2(){console.log('async2');}console.log('scriptstart');setTimeout(()=>{console.log('setTimeout');},0);async1();console.log('scriptend');```答案与解析:输出结果:```scriptstartasync1startasync2scriptendasync1endsetTimeout```解析:这是一道经典的事件循环与async/await题目。1.执行同步代码:`console.log('scriptstart')`。2.遇到`setTimeout`,将其回调加入宏任务队列。3.执行`async1()`:打印`async1start`。打印`async1start`。遇到`awaitasync2()`:遇到`awaitasync2()`:先执行`async2()`函数体(同步部分),打印`async2`。先执行`async2()`函数体(同步部分),打印`async2`。`async2`返回一个Promise,状态为resolved。`async2`返回一个Promise,状态为resolved。`await`会阻塞`async1`后续代码,将`console.log('async1end')`加入微任务队列。4.继续执行同步代码:`console.log('scriptend')`。5.此时主线程同步代码执行完毕。6.检查微任务队列,发现有一个任务`console.log('async1end')`,执行它。7.微任务清空,开始下一轮事件循环,检查宏任务队列,执行`setTimeout`回调,打印`setTimeout`。2.请写出以下代码的输出结果,并解释原因。```javascriptfunctionF(){}Ototype.a=function(){console.log('a');};Ftotype.b=function(){console.log('b');}letf=newF();f.a();f.b();F.a();F.b();```答案与解析:输出结果:```aUncaughtTypeError:f.bisnotafunctionab```解析:本题考查原型链查找。`f`是`F`的实例。`f`是`F`的实例。`f.a()`:`f.a()`:`f`自身没有`a`方法。`f`自身没有`a`方法。沿着原型链查找`f.__proto__`(即`F.prototype`)。`F.prototype`是一个空对象`{}`,没有`a`。沿着原型链查找`f.__proto__`(即`F.prototype`)。`F.prototype`是一个空对象`{}`,没有`a`。继续向上查找`F.prototype.__proto__`(即`Ototype`)。继续向上查找`F.prototype.__proto__`(即`Ototype`)。`Ototype`上有`a`方法,找到并执行,输出`'a'`。`Ototype`上有`a`方法,找到并执行,输出`'a'`。`f.b()`:`f.b()`:`f`自身没有`b`。`f`自身没有`b`。查找`F.prototype`,没有。查找`F.prototype`,没有。查找`Ototype`,没有。查找`Ototype`,没有。到达原型链顶端`null`,报错`f.bisnotafunction`。到达原型链顶端`null`,报错`f.bisnotafunction`。注意:`Ftotype.b`是挂载在函数的构造函数原型上的,`f`是对象实例,不是函数,其原型链不经过`Ftotype`。注意:`Ftotype.b`是挂载在函数的构造函数原型上的,`f`是对象实例,不是函数,其原型链不经过`Ftotype`。`F.a()`:`F.a()`:`F`是一个函数,也是对象。`F`自身没有`a`。`F`是一个函数,也是对象。`F`自身没有`a`。查找`F.__proto__`(即`Ftotype`),没有`a`。查找`F.__proto__`(即`Ftotype`),没有`a`。查找`Ftotype.__proto__`(即`Ototype`),找到`a`,输出`'a'`。查找`Ftotype.__proto__`(即`Ototype`),找到`a`,输出`'a'`。`F.b()`:`F.b()`:`F`自身没有`b`。`F`自身没有`b`。查找`F.__proto__`(即`Ftotype`),找到`b`,输出`'b'`。查找`F.__proto__`(即`Ftotype`),找到`b`,输出`'b'`。3.请写出以下代码的输出结果,并解释原因。```javascriptletlength=10;functionfn(){console.log(this.length);}varobj={length:5,method:function(fn){fn();arguments[0]();}};obj.method(fn,1);```答案与解析:输出结果:```101```解析:本题考查`this`指向与类数组对象`arguments`。1.`obj.method(fn,1)`调用`method`函数。2.在`method`内部:第一次调用`fn()`:第一次调用`fn()`:这里的`fn`是作为普通函数直接调用的。这里的`fn`是作为普通函数直接调用的。在非严格模式下,`this`指向全局对象(`window`)。在非严格模式下,`this`指向全局对象(`window`)。全局变量`length`为10,因此输出`10`。全局变量`length`为10,因此输出`10`。第二次调用`arguments[0]()`:第二次调用`arguments[0]()`:`arguments`是一个类数组对象,包含了传入的参数`[fn,1]`。`arguments`是一个类数组对象,包含了传入的参数`[fn,1]`。`arguments[0]`就是`fn`。`arguments[0]`就是`fn`。这里是通过`arguments[0]()`的形式调用的,相当于`arguments`对象调用了`fn`。这里是通过`arguments[0]()`的形式调用的,相当于`arguments`对象调用了`fn`。因此,`fn`内部的`this`指向`arguments`对象。因此,`fn`内部的`this`指向`arguments`对象。`arguments.length`表示参数个数,这里传入了`fn`和`1`两个参数,所以长度为2?`arguments.length`表示参数个数,这里传入了`fn`和`1`两个参数,所以长度为2?修正:请注意代码`obj.method(fn,1)`,确实传了两个参数。但是,`arguments`对象的`length`属性就是传入参数的个数。让我们重新确认代码:`arguments[0]()`是调用`fn`,`this`指向`arguments`。`arguments.length`为2。让我们重新确认代码:`arguments[0]()`是调用`fn`,`this`指向`arguments`。`arguments.length`为2。等等,题目代码是`obj.method(fn,1)`。参数个数确实是2。但是,如果题目是`obj.method(fn)`,那`arguments.length`就是1。让我们再看一遍题目代码:`obj.method(fn,1);`。确实传了`1`。让我们再看一遍题目代码:`obj.method(fn,1);`。确实传了`1`。所以`arguments.length`应该是2。所以`arguments.length`应该是2。自我纠正:如果题目意图是考察`arguments`的`length`,那么答案是2。如果题目是`obj.method(fn)`,答案是1。基于题目给出的代码`obj.method(fn,1)`,正确输出应该是2。注:如果这是一道标准真题,通常陷阱在于`arguments`作为调用者。这里按照题目代码`obj.method(fn,1)`分析,`arguments`长度为2。如果原题没有`,1`,则是1。鉴于题目代码明确写了`,1`,答案为2。注:如果这是一道标准真题,通常陷阱在于`arguments`作为调用者。这里按照题目代码`obj.method(fn,1)`分析,`arguments`长度为2。如果原题没有`,1`,则是1。鉴于题目代码明确写了`,1`,答案为2。再次复核:如果用户提供的题目代码是固定的,我必须基于固定代码。代码是`obj.method(fn,1);`。所以`arguments`有两个元素。`arguments.length`是2。再次复核:如果用户提供的题目代码是固定的,我必须基于固定代码。代码是`obj.method(fn,1);`。所以`arguments`有两个元素。`arguments.length`是2。另一种可能:如果题目代码原本是`obj.method(fn)`',那么答案是1。但在本题中,我将严格按照提供的代码`obj.method(fn,1)`回答。另一种可能:如果题目代码原本是`obj.method(fn)`',那么答案是1。但在本题中,我将严格按照提供的代码`obj.method(fn,1)`回答。然而,这类面试题通常有个变体。为了严谨,我将基于`obj.method(fn,1)`回答。然而,这类面试题通常有个变体。为了严谨,我将基于`obj.method(fn,1)`回答。实际上,很多复制粘贴的题目可能会漏掉参数。让我们假设题目就是`obj.method(fn,1)`。实际上,很多复制粘贴的题目可能会漏掉参数。让我们假设题目就是`obj.method(fn,1)`。最终确认:`arguments[0]()`->`this`指向`arguments`。`arguments.length`为2。修正后的答案:1.`10`(全局length)2.`2`(arguments对象的length,因为传了fn和1两个参数)六、编程实现题(每题10分,共20分)1.请实现一个`deepClone`函数,用于对任意对象(包括嵌套对象、数组、Date、RegExp等)进行深拷贝,并处理循环引用问题。答案与解析:```javascriptfunctiondeepClone(obj,hash=newWeakMap()){//1.如果是null或非对象类型,直接返回if(obj===null||typeofobj!=='object'){returnobj;}//2.检查循环引用:如果该对象已经被拷贝过,直接返回对应的拷贝对象if(hash.has(obj)){returnhash.get(obj);}//3.初始化拷贝对象,根据构造函数判断类型(Date,RegExp等)letcloneObj;if(objinstanceofDate){cloneObj
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 上海工程技术大学《AUTOCAD 制图》2025-2026学年第一学期期末试卷(A卷)
- 上海工商职业技术学院《安装工程施工技术》2025-2026学年第一学期期末试卷(B卷)
- 上海工商职业技术学院《安全检测与监控》2025-2026学年第一学期期末试卷(A卷)
- 上海工商职业技术学院《Android 开发基础》2025-2026学年第一学期期末试卷(B卷)
- 上饶卫生健康职业学院《安全管理》2025-2026学年第一学期期末试卷(B卷)
- 初中生阅读方法提升主题班会说课稿
- 演唱 唱脸谱说课稿2025年初中音乐七年级下册(2024)人音版(2024 主编:赵季平杜永寿)
- 上海音乐学院《安全学原理》2025-2026学年第一学期期末试卷(B卷)
- 医学26年:甲减危象急救处理流程 查房课件
- 初中生2025心理强化说课稿
- 拆违控违培训课件
- 小学信息技术课堂中STEAM教育模式研究教学研究课题报告
- 算力设施产业图谱研究报告 -2024
- 2026年四川省事业单位联考《综合知识》试题及答案
- 公共洗手间卫生清洁培训
- 大连软件产业发展战略的深度剖析与对策构建
- 专题05平面向量(讲义)数学学业水平考试合格考总复习(原卷版)
- 细胞素功效课件
- 早产儿家庭环境改造与安全防护方案
- 2025广东中山市神湾镇人民政府所属事业单位招聘事业单位人员8人人参考题库及答案详解(真题汇编)
- 会计岗位招聘笔试题及解答(某大型国企)附答案
评论
0/150
提交评论