今天千锋扣丁学堂HTML5培训给大家分享一些关于目前各大企业招聘JavaScript进阶面试题,小编整理了从基础到高阶:测试您对JavaScript的了解程度,重新整理您的知识,或为您的编码面试做好准备!1.下面程式码的输出是什么?functionsayHi{console.log(name);console.log(age);varname="Lydia";letage=21;}sayHi;A:Lydia和undefinedB:Lydia和ReferenceErrorC:ReferenceError和21D:undefined和ReferenceError答案:D在函式中,我们首先使用var关键字声明了name变数。这意味着变数在建立阶段会被提升(JavaScript会在建立变数建立阶段为其分配内存空间),预设值为undefined,直到我们实际执行到使用该变数的行。我们还没有为name变数赋值,所以它仍然保持undefined的值。使用let关键字(和const)宣告的变数也会存在变数提升,但与var不同,初始化没有被提升。在我们宣告(初始化)它们之前,它们是不可访问的。这被称为“暂时死区”。当我们在宣告变数之前尝试访问变数时,JavaScript会丢掷一个ReferenceError。译者注:关于let的是否存在变数提升,我们何以用下面的例子来验证:letname=\'ConardLi\'{console.log(name)//UncaughtReferenceError:nameisnotdefinedletname=\'code秘密花园\'}let变数如果不存在变数提升,console.log(name)就会输出ConardLi,结果却丢掷了ReferenceError,那么这很好的说明了,let也存在变数提升,但是它存在一个“暂时死区”,在变数未初始化或赋值前不允许访问。变数的赋值可以分为三个阶段:建立变数,在内存中开辟空间初始化变数,将变数初始化为undefined真正赋值关于let、var和function:let的“建立”过程被提升了,但是初始化没有提升。var的“建立”和“初始化”都被提升了。function的“建立”“初始化”和“赋值”都被提升了。2.下面程式码的输出是什么?for(vari=0;i<3;i++){setTimeout(=>console.log(i),1);}for(leti=0;i<3;i++){setTimeout(=>console.log(i),1);}A:012and012B:012and333C:333and012答案:C由于JavaScript中的事件执行机制,setTimeout函式真正被执行时,循环已经走完。由于第一个循环中的变数i是使用var关键字宣告的,因此该值是全域性的。在循环期间,我们每次使用一元运算子++都会将i的值增加1。因此在第一个例子中,当呼叫setTimeout函式时,i已经被赋值为3。在第二个循环中,使用let关键字宣告变数i:使用let(和const)关键字宣告的变数是具有块作用域的(块是{}之间的任何东西)。在每次迭代期间,i将被建立为一个新值,并且每个值都会存在于循环内的块级作用域。3.下面程式码的输出是什么?constshape={radius:10,diameter{returnthis.radius*2;},perimeter:=>2*Math.PI*this.radius};shape.diameter;shape.perimeter;A:20and62.83185307179586B:20andNaNC:20and63D:NaNand63答案:B请注意,diameter是普通函式,而perimeter是箭头函式。对于箭头函式,this关键字指向是它所在上下文(定义时的位置)的环境,与普通函式不同!这意味着当我们呼叫perimeter时,它不是指向shape物件,而是指其定义时的环境(window)。没有值radius属性,返回undefined。4.下面程式码的输出是什么?+true;!"Lydia";A:1andfalseB:falseandNaNC:falseandfalse答案:A一元加号会尝试将boolean型别转换为数字型别。true被转换为1,false被转换为0。字串\'Lydia\'是一个真值。我们实际上要问的是“这个真值是假的吗?”。这会返回false。5.哪个选项是不正确的?constbird={size:"small"};constmouse={name:"Mickey",small:true};A:mouse.bird.sizeB:mouse[bird.size]C:mouse[bird["size"]]D:Allofthemarevalid答案:A在JavaScript中,所有物件键都是字串(除了Symbol)。尽管有时我们可能不会给定字串型别,但它们总是被转换为字串。JavaScript解释语句。当我们使用方括号表示法时,它会看到第一个左括号[,然后继续,直到找到右括号]。只有在那个时候,它才会对这个语句求值。mouse[bird.size]:首先它会对bird.size求值,得到small。mouse[“small”]返回true。但是,使用点表示法,这不会发生。mouse没有名为bird的键,这意味着mouse.bird是undefined。然后,我们使用点符号来询问size:mouse.bird.size。由于mouse.bird是undefined,我们实际上是在询问undefined.size。这是无效的,并将丢掷Cannotreadproperty"size"ofundefined。6.下面程式码的输出是什么?letc={greeting:"Hey!"};letd;d=c;c.greeting="Hello";console.log(d.greeting);A:HelloB:undefinedC:ReferenceErrorD:TypeError答案:A在JavaScript中,当设定它们彼此相等时,所有物件都通过引用进行互动。首先,变数c为物件储存一个值。之后,我们将d指定为c与物件相同的引用。更改一个物件时,可以更改所有物件。7.下面程式码的输出是什么?leta=3;letb=newNumber(3);letc=3;console.log(a==b);console.log(a===b);console.log(b===c);A:truefalsetrueB:falsefalsetrueC:truefalsefalseD:falsetruetrue答案:CnewNumber是一个内建的函式建构函式。虽然它看起来像一个数字,但它并不是一个真正的数字:它有一堆额外的功能,是一个物件。当我们使用==运算子时,它只检查它是否具有相同的值。他们都有3的值,所以它返回true。译者注:==会引发隐式型别转换,右侧的物件型别会自动拆箱为Number型别。然而,当我们使用===操作符时,型别和值都需要相等,newNumber不是一个数字,是一个物件型别。两者都返回false。8.下面程式码的输出是什么?classChameleon{staticcolorChange(newColor){this.newColor=newColor;}constructor({newColor="green"}={}){this.newColor=newColor;}}constfreddie=newChameleon({newColor:"purple"});freddie.colorChange("orange");A:orangeB:purpleC:greenD:TypeError答案:DcolorChange方法是静态的。静态方法仅在建立它们的建构函式中存在,并且不能传递给任何子级。由于freddie是一个子级物件,函式不会传递,所以在freddie例项上不存在freddie方法:丢掷TypeError。9.下面程式码的输出是什么?letgreeting;greetign={};//Typo!console.log(greetign);A:{}B:ReferenceError:greetignisnotdefinedC:undefined答案:A控制台会输出空物件,因为我们刚刚在全域性物件上建立了一个空物件!当我们错误地将greeting输入为greetign时,JS直译器实际上在浏览器中将其视为global.greetign={}(或window.greetign={})。为了避免这种情况,我们可以使用“usestrict”。这可以确保在将变数赋值之前必须宣告变数。10.当我们这样做时会发生什么?functionbark{console.log("Woof!");}bark.animal="dog";A:Nothing,thisistotallyfine!B:SyntaxError.Youcannotaddpropertiestoafunctionthisway.C:undefinedD:ReferenceError答案:A这在JavaScript中是可能的,因为函式也是物件!(原始型别之外的所有东西都是物件)函式是一种特殊型别的物件。您自己编写的程式码并不是实际的函式。该函式是具有属性的物件,此属性是可呼叫的。11.下面程式码的输出是什么?functionPerson(firstName,lastName){this.firstName=firstName;this.lastName=lastName;}constmember=newPerson("Lydia","Hallie");Person.getFullName==>this.firstName+this.lastName;console.log(member.getFullName);A:TypeErrorB:SyntaxErrorC:LydiaHallieD:undefinedundefined答案:A您不能像使用常规物件那样向建构函式新增属性。如果要一次向所有物件新增功能,则必须使用原型。所以在这种情况下应该这样写:Person.prototype.getFullName=function{return`${this.firstName}${this.lastName}`;}这样会使member.getFullName是可用的,为什么样做是对的?假设我们将此方法新增到建构函式本身。也许不是每个Person例项都需要这种方法。这会浪费大量内存空间,因为它们仍然具有该属性,这占用了每个例项的内存空间。相反,如果我们只将它新增到原型中,我们只需将它放在内存中的一个位置,但它们都可以访问它!12.下面程式码的输出是什么?functionPerson(firstName,lastName){this.firstName=firstName;this.lastName=lastName;}constlydia=newPerson("Lydia","Hallie");constsarah=Person("Sarah","Smith");console.log(lydia);console.log(sarah);A:Person{firstName:"Lydia",lastName:"Hallie"}andundefinedB:Person{firstName:"Lydia",lastName:"Hallie"}andPerson{firstName:"Sarah",lastName:"Smith"}C:Person{firstName:"Lydia",lastName:"Hallie"}and{}D:Person{firstName:"Lydia",lastName:"Hallie"}andReferenceError答案:A对于sarah,我们没有使用new关键字。使用new时,它指的是我们建立的新空物件。但是,如果你不新增new它指的是全域性物件!我们指定了this.firstName等于\'Sarah和this.lastName等于Smith。我们实际做的是定义global.firstName=\'Sarah\'和global.lastName=\'Smith。sarah本身的返回值是undefined。12.事件传播的三个阶段是什么??A:目标>捕获>冒泡B:冒泡>目标>捕获C:目标>冒泡>捕获D:捕获>目标>冒泡答案:D在捕获阶段,事件通过父元素向下传递到目标元素。然后它到达目标元素,冒泡开始。13.所有物件都有原型.A:对B:错误答案:B除基础物件外,所有物件都有原型。基础物件可以访问某些方法和属性,例如.toString。这就是您可以使用内建JavaScript方法的原因!所有这些方法都可以在原型上找到。虽然JavaScript无法直接在您的物件上找到它,但它会沿着原型链向下寻找并在那里找到它,这使您可以访问它。译者注:基础物件指原型链终点的物件。基础物件的原型是null。14.下面程式码的输出是什么?functionsum(a,b){returna+b;}sum(1,"2");A:NaNB:TypeErrorC:"12"D:3答案:CJavaScript是一种动态型别语言:我们没有指定某些变数的型别。在您不知情的情况下,值可以自动转换为另一种型别,称为隐式型别转换。强制从一种型别转换为另一种型别。在此示例中,JavaScript将数字1转换为字串,以使函式有意义并返回值。在让数字型别(1)和字串型别(\'2\')相加时,该数字被视为字串。我们可以连线像“Hello”+“World”这样的字串,所以这里发生的是“1”+“2”返回“12”。15.下面程式码的输出是什么?letnumber=0;console.log(number++);console.log(++number);console.log(number);A:112B:122C:022D:012答案:C字尾一元运算子++:返回值(返回0)增加值(数字现在是1)字首一元运算子++:增加值(数字现在是2)返回值(返回2)所以返回022。16.下面程式码的输出是什么?functiongetPersonInfo(one,two,three){console.log(one);console.log(two);console.log(three);}constperson="Lydia";constage=21;getPersonInfo`${person}is${age}yearsold`;A:Lydia21["","is","yearsold"]B:["","is","yearsold"]Lydia21C:Lydia["","is","yearsold"]21答案:B如果使用标记的模板字串,则第一个引数的值始终是字串值的阵列。其余引数获取传递到模板字串中的表示式的值!17.下面程式码的输出是什么?functioncheckAge(data){if(data==={age:18}){console.log("Youareanadult!");}elseif(data=={age:18}){console.log("Youarestillanadult.");}else{console.log(`Hmm..Youdon\'thaveanageIguess`);}}checkAge({age:18});A:Youareanadult!B:Youarestillanadult.C:Hmm..Youdon\'thaveanageIguess答案:C在比较相等性,原始型别通过它们的值进行比较,而物件通过它们的引用进行比较。JavaScript检查物件是否具有对内存中相同位置的引用。我们作为引数传递的物件和我们用于检查相等性的物件在内存中位于不同位置,所以它们的引用是不同的。这就是为什么{age:18}==={age:18}和{age:18}=={age:18}返回false的原因。18.下面程式码的输出是什么?functiongetAge(...args){console.log(typeofargs);}getAge(21);A:"number"B:"array"C:"object"D:"NaN"答案:C扩充套件运算子(...args)返回一个带引数的阵列。阵列是一个物件,因此typeofargs返回object。20.下面程式码的输出是什么?functiongetAge{"usestrict";age=21;console.log(age);}getAge;A:21B:undefinedC:ReferenceErrorD:TypeError答案:C使用“usestrict”,可以确保不会意外地宣告全域性变数。我们从未宣告变数age,因为我们使用`usestrict\',它会引发一个ReferenceError。如果我们不使用“usestrict”,它就会起作用,因为属性age会被新增到全域性物件中。21.下面程式码的输出是什么?constsum=eval("10*10+5");A:105B:"105"C:TypeErrorD:"10*10+5"答案:Aeval会为字串传递的程式码求值。如果它是一个表示式,就像在这种情况下一样,它会计算表示式。表示式为10*10+5计算得到105。22.cool_secret可以访问多长时间?sessionStorage.setItem("cool_secret",123);A:永远,资料不会丢失。B:使用者关闭选项卡时。C:当用户关闭整个浏览器时,不仅是选项卡。D:使用者关闭计算机时。答案:B关闭选项卡后,将删除储存在sessionStorage中的资料。如果使用localStorage,资料将永远存在,除非例如呼叫localStorage.clear。23.下面程式码的输出是什么?varnum=8;varnum=10;console.log(num);A:8B:10C:SyntaxErrorD:ReferenceError答案:B使用var关键字,您可以用相同的名称宣告多个变数。然后变数将储存最新的值。您不能使用let或const来实现这一点,因为它们是块作用域的。24.下面程式码的输出是什么?constobj={1:"a",2:"b",3:"c"};constset=newSet([1,2,3,4,5]);obj.hasOwnProperty("1");obj.hasOwnProperty(1);set.has("1");set.has(1);A:falsetruefalsetrueB:falsetruetruetrueC:truetruefalsetrueD:truetruetruetrue答案:C所有物件键(不包括Symbols)都会被储存为字串,即使你没有给定字串型别的键。这就是为什么obj.hasOwnProperty(\'1\')也返回true。上面的说法不适用于Set。在我们的Set中没有“1”:set.has(\'1\')返回false。它有数字型别1,set.has(1)返回true。25.下面程式码的输出是什么?constobj={a:"one",b:"two",a:"three"};console.log(obj);A:{a:"one",b:"two"}B:{b:"two",a:"three"}C:{a:"three",b:"two"}D:SyntaxError答案:C如果物件有两个具有相同名称的键,则将替前面的键。它仍将处于第一个位置,但具有最后指定的值。26.JavaScript全域性执行上下文为你建立了两个东西:全域性物件和this关键字.A:对B:错误C:视情况而定答案:A基本执行上下文是全域性执行上下文:它是程式码中随处可访问的内容。27.下面程式码的输出是什么?for(leti=1;i<5;i++){if(i===3)continue;console.log(i);}A:12B:123C:124D:134答案:C如果某个条件返回true,则continue语句跳过迭代。28.下面程式码的输出是什么?String.prototype.giveLydiaPizza==>{return"JustgiveLydiapizzaalready!";};constname="Lydia";name.giveLydiaPizza;A:"JustgiveLydiapizzaalready!"B:TypeError:notafunctionC:SyntaxErrorD:undefined答案:AString是一个内建的建构函式,我们可以为它新增属性。我刚给它的原型添加了一个方法。原始型别的字串自动转换为字串物件,由字串原型函式生成。因此,所有字串(字串物件)都可以访问该方法!译者注:当使用基本型别的字串呼叫giveLydiaPizza时,实际上发生了下面的过程:建立一个String的包装型别例项在例项上呼叫substring方法销毁例项29.下面程式码的输出是什么?consta={};constb={key:"b"};constc={key:"c"};a[b]=123;a[c]=456;console.log(a[b]);A:123B:456C:undefinedD:ReferenceError答案:B物件键自动转换为字串。我们试图将一个物件设定为物件a的键,其值为123。但是,当物件自动转换为字串化时,它变成了[Objectobject]。所以我们在这里说的是a["Objectobject"]=123。然后,我们可以尝试再次做同样的事情。c物件同样会发生隐式型别转换。那么,a["Objectobject"]=456。然后,我们打印a[b],它实际上是a["Objectobject"]。我们将其设定为456,因此返回456。30.下面程式码的输出是什么?constfoo==>console.log("First");constbar==>setTimeout(=>console.log("Second"));constbaz==>console.log("Third");bar;foo;baz;A:FirstSecondThirdB:FirstThirdSecondC:SecondFirstThirdD:SecondThirdFirst答案:B我们有一个setTimeout函式并首先呼叫它。然而却最后打印了它。这是因为在浏览器中,我们不只有执行时引擎,我们还有一个叫做WebAPI的东西。WebAPI为我们提供了setTimeout函式,例如DOM。将callback推送到WebAPI后,setTimeout函式本身(但不是回拨!)从堆叠中弹出。现在,呼叫foo,并打印First。foo从堆叠弹出,baz被呼叫,并打印Third。WebAPI不能只是在准备就绪时将内容新增到堆叠中。相反,它将回调函式推送到一个称为任务伫列的东西。这是事件循环开始工作的地方。事件循环检视堆叠和任务伫列。如果堆叠为空,则会占用伫列中的第一个内容并将其推送到堆叠中。bar被呼叫,Second被打印,它从栈中弹出。31.单击按钮时event.target是什么?
千锋扣丁学堂HTML5培训之企业级JavaScript面试题详解
消息来源:baojiabao.com 作者: 发布时间:2026-05-22
报价宝综合消息千锋扣丁学堂HTML5培训之企业级JavaScript面试题详解





























