前端笔试题总结,带答案和解析(持续更新,上次更新23/10/5,目前有30题)


这个系列将持续更新前端笔试题一期十题,每五题做一个标题(方便跳转),您可以一期一期阅读,也可以在点击汇总,一口气看完,如果对题目有不理解的地方,欢迎大家在评论区提问,如果有更好的意见也欢迎大家留言!!!

🎉往期回顾:

🍧汇总(持续更新)

🎶前端笔试题总结,带答案和解析(一)

前端笔试题总结,带答案和解析(二)

❤️前端笔试题总结,带答案和解析(三)

🍿1. 执行以下程序,输出结果为()

var x = 10;
var y = 20;
var z = x < y ? x++:++y;
console.log('x='+x+';y='+y+';z='+z);

A x=11;y=21;z=11
B x=11;y=20;z=10
C x=11;y=21;z=10
D x=11;y=20;z=11

初始化x的值为10,y的值为20,x < y返回结果为true,所以执行var z = x++,x++是后置自增,也就是先返回x值,然后再自增加1,所以输出x的值为11,z的值为10,而y值没有改变,仍然是20,B选项正确。


2. typeof Date.now() 的值是:'number'

先执行 Date.now() 得到一个时间戳 typeof 时间戳 =》‘number’


3. 请阅读以下代码
var obj = {};
obj.log = console.log;
obj.log.call(console,this);

该代码在浏览器中执行,输出的日志结果是什么?

A undefined
B window
C console
D obj

obj.log = console.log;//在本行中obj对象中创建了一个函数(即console.log)的引用log,因为是个这个函数的引用如果想要执行可以有两种方法,第一种是后边加(),第二种是使用apply()或者call(),二者第一个参数都是this,接下来的参数apply是参数数组或者是"arguments",而call的参数是直接的参数值
obj.log.call(console,this);//如上所述,call的第二个参数是要被传入obj.log()的参数,这行代码其实可等价于console.log(this),而因为这三行代码都是在global环境下定义的(不是函数中的局部变量),所以this就是window.
至于第一个参数为什么是console而不是this,我觉得console被按照this处理了,我试了试,替换后的执行结果相同


4.执行以下代码,alert的输出结果为()
 var msg = 'hello';
for (var i = 0; i<10; i++){
    var msg = 'hello' + i * 2 + i;
}
alert(msg);

答案:hello189

解析:在for循环内使用var声明的变量msg并不是局部变量,而是全局变量。在for循环中,每循环一次,变量msg的值就被覆盖一次, 当i=10时不满足i<10,则不执行for里面的逻辑,所以最后一次i=9,最终msg的值为表达式‘hello’ + 9 * 2 + 9的返回结果,根据运算符的优先级,先计算9 * 2,返回结果为18,接着运算hello + 18,返回结果为字符串类型的hello18,最后运算hello18 + 9,返回结果为字符串类型的hello189,故输出结果为hello189,B选项正确。

“hello”+9*2+9
“hello”+18+9
“hello18”+9
“hello189”


5.下列逻辑表达式的结果为false的是()
A NaN == NaN

B null == undefined

C ‘’ == 0

D true == 1

答案:A

解析:
A选项,NaN无论与谁比较,包括它自己,结果都是false,A正确;
B选项,null与undefined使用 ‘ == ’ 比较,结果为true,除此之外,undefined和null与谁比较,结果都为false;
C选项,String与Number比较,先将String转为Number类型,再比较,''转为Number类型的结果为0,故 ‘’ == 0的结果为true;
D选项,Boolean与其他类型比较,Boolean先转为Number类型,true转为Number类型的值为1,故true==1的结果为true。


🎐6.已知arr = [1,2,NaN,1,4,2,NaN],现为输出arr的不重复元素(重复元素只输出一次),则下列程序中的①处,可以作为判断条件的是()

var newArr = [];
for(var i = 0 ;i<arr.length;i++){
  if(){
    newArr.push(arr[i]);
  }
}
console.log(newArr);

A newArr.indexOf(arr[i]) == -1

B !newArr.indexOf(arr[i]) == -1

C newArr.includes(arr[i])

D !newArr.includes(arr[i])

解析:
indexOf()方法与includes()方法的一个重要区别在于indexOf()并不能判断数组的NaN元素,换句话说,不管数组arr是否有NaN元素,arr.indexOf(NaN)返回值都是-1,所以AB选项不能对NaN进行去重,不符合题意;
如果newArr数组不含有arr数组的某个元素,就应该把该元素添加到newArr数组中,如果含有,则不能添加,这样才能达到去重的目的,即newArr.includes(arr[i])返回值为false时,就应该执行if内的语句,所以应该使用“!”对条件取反,D选项符合题意,C选项不符合题意。


7. 执行以下程序,输出结果为()
var one;
var two = null;
console.log(one == two,one === two);

答案:true,false
解析:变量one只声明未赋值,所以其值为undefined,在使用 “ == ” 对undefined和null进行比较时,不能将null和undefined转换成其他任何值,并且规定undefined == null返回结果为true,而使用“ === ”进行比较时,由于“===”需要严格区分数据类型,故undefined === null返回结果为False,A选项正确。


8. 如下代码片段的运行结果是
var obj ={a:1,b:function () {alert(this.a)}}; 
var fun =obj.b; 
fun()

答案:弹出undefined
解析:var b = function(){ alert(this.a); }, obj = { a:1, b:b // 把函数独立出来 }; var fun = obj.b;// 存储的是内存中的地址 fun(); 答案:C 虽然fun是obj.b的一个引用,但是实际上,它引用的是b函数本身,因此此时的fun()其实 是一个不带任何修饰的函数调用,所以this指向window。


9. 下面符合javascript变量定义规则的是?

A _$te$t2
B with
C a bc
D 2a
答案:A
解析: 第一个字符必须是一个字母、下划线(_)或一个美元符号($);其他字符可以是字母、下划线、美元符号或数字
B中with是保留字,C中带空格,D不能以数字开头


10 请问以下JS代码会输出什么
var a = 10; 
(function a() {
    a = 20;
    console.log(a); 
})()

答案:输出函数a的内容
解析:首先存在变量提升和函数提升,所以一开始变量a被提升,值为undefined,由于函数可以在函数体中访问自己的标识符(函数名),而且函数提升优先级更高所以a先被赋值为函数。
又因为是立即执行函数所以执行了函数a输出a目前的值(即函数),之后才是被赋值为10.


✨11.以下代码的执行后,str 的值是:

var str = "Hellllo world";
str = str.replace(/(a)\1/g, '$1');

答案:Hello world
解析: 对于正则表达式 /(a)\1/g,其中(a)是第一个分组,\1指向第一个分组,即\1重复了第一个分组的内容,所以该正则表达式等价于/(aa)/g
对于str.replace(a,b) 用第二个参数b替换掉第一个参数a,这里‘$1’也是指向第一个分组(a), 也就是使用 'a 去替换掉 ‘aa’


  1. 以下符合 ES6 写法的有:()

    A class Foo { constructor() {return Object.create(null);} } Foo()
    B var m=1; export m;
    C export var firstName=’Michael’;
    D 在A模块中export{readFile}后,在B模块中import readFile from ‘A’可以获取到readFile

答案:C
解析:
A:类必须使用new调用,否则会报错。这是它跟普通构造函数的一个主要区别,后者不用new也可以执行。
B:export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。
// 报错
export 1;
// 报错
var m = 1;
export m;
上面两种写法都会报错,因为没有提供对外的接口。第一种写法直接输出 1,第二种写法通过变量m,还是直接输出 1。1只是一个值,不是接口。正确的写法是下面这样。
// 写法一
export var m = 1;
// 写法二
var m = 1;
export {m};
// 写法三
var n = 1;
export {n as m};

D:A模块对外暴露了一个对象,引入的时候需要使用解构赋值

import {readFile} from ‘A’

来源:牛客网


13.请给出下面这段代码的运行结果( )

var bb = 1;
function aa(bb) {
    bb = 2;
    alert(bb);
};
aa(bb);
alert(bb);

答案:2 1
解析:这道题考察是局部变量和参数传递的问题。 function aa(bb) { bb = 2; alert(bb); }; 在aa函数中,bb是以传值的方式传入的,在函数中,会重新定义一个bb变量,并将其值覆为2,并不影响函数体外的bb变量,所以其值仍然为1.


14.请问以下JS代码最后输出的len值是多少?
var len = 117;
let func = {
  len: 935,
  showLen: function() {
    console.log(this.len);
  },
  show: function() {
    (function(cb) {
      cb();
    })(this.showLen)
  }
}
func.show();

答案:117
解析:立即执行函数的this指向是window(非严格模式下),因为作为一个匿名函数,在被调用的时候,我们往往就是直接调用,因此它的this是非常确定的,那么len就取window下的len值了即117。


15. 以上 JavaScript 代码,在浏览器中运行的结果是
var foo = {n:1};
(function(foo){
    console.log(foo.n);
    foo.n = 3;
    var foo = {n:2};
    console.log(foo.n);
})(foo);
console.log(foo.n);

答案:1 2 3
解析:第一步:进行预编译,var全局变量foo、匿名函数 function、var局部变量foo 第二步:代码自上而下、自左向右执行计算: 对全局变量foo进行赋值foo={n:1};注意:此值为对象,属于引用类型; 匿名函数传入参数foo={n:1}自执行; console.log(foo);打出数字1; 由于存在foo局部变量,那么对foo变量进行赋值foo={n:3},同时更改了引用类型的参数值,全局foo变量被重新赋值foo={n:3}; 对局部变量foo进行重新赋值foo={n:2}; console.log(foo);打出数字2; 全局变量foo={n:3},因此,console.log(foo);打出数字3;

15题的升级版,断点调试一步步看原因


❤️16.页面有一个按钮button id为button1,通过原生的js如何禁用?()

A document.getElementById(“button1”).setAttribute(“Readolny”,true);
B document.getElementById(“button1”).setAttribute(“disabled”,”true”);
C document.getElementById(“button1”).Readonly=true;
D document.getElementById(“button1”).disabled=true;
答案:B D
解析:<input id=“btnShow” type=“button” value=“点击” class=“btn”> 上面是一段按钮的html代码 如果要用原生的js来禁用这个按钮 可以用这样: document.getElementByIdx_x_x(“btnShow”).disabled=true;(这样就把按钮禁用了) 如果要重新开启按钮,则可以让disabled=false;即可 那么在jquery下面要如何设置呢?其实也很简单 利用jquery的attr的方法即可 $(“#btnShow”).attr({“disabled”:“disabled”}); 如要让按钮恢复可用,可以采用removeAttr方法把disabled属性删除即可。 $(“#btnShow”).removeAttr(“disabled”);


17.以下哪些操作会触发Reflow:
var obj = document.getElementById(“test”);

A alert(obj.className)
B alert(obj.offsetHeight)
C obj.style.height = “100px”
D obj.style.color = “red”

答案:B C
解析:Reflow是重排 重排的本质是影响了布局树,页面的渲染就需要从布局开始走接下来的五步 [不知道重绘的可以参考这篇文章] (https://juejin.cn/post/7240333779221987384#heading-27)
A 只是读取类名不会影响布局树 不会触发reflow
B 因为offset和scroll其实都是“相对”来计算的。有其他元素做参照物,所以会回流一次,确保准确。
C 改变元素的高 会影响布局树 所以需要reflow
D 改变元素的元素 不影响布局树 需要repaint 重绘 repaint 的本质就是重新根据分层信息计算了绘制指令。当某些元素的外观被改变,就需要重新计算。计算样式和绘制阶段之后的阶段都要重新过一遍。
在这里插入图片描述


18.代码var foo = “10”+3-“1”;console.log(foo);执行后,foo的值为( )

A “102”
B 102
C 12
D “12”

答案:B 102
解析:对于“+”来说,有两个含义:第一个含义是做字符串拼接,第二个含义是加减法中的加法。

  1,如果操作数里有一个是字符串,其他的值将被转换成字符串; 

  2,其他情况,操作数转换成数字执行加法运算。 

而对于“ - ”来说,只有一个含义,就是做减法,自然不会转化成字符串了。


19.执行以下程序,输出结果为()
function Person(age){

       this.age = age;

 }

Person.prototype = {

       constructor:Person,

       getAge:function(){

            console.log(this.age);

        },

 }

var ldh = new Person(24);

Person.prototype.age = 18;

Object.prototype.age = 20;

ldh.getAge();

答案:24
解析:对象在调用方法和属性时依靠原型链的顺序进行查找,先从自身查找,然后是构造函数的原型对象,接着是Object的原型对象,一旦找到时停止查找,找不到则返回undefined。同时,原型对象中的this仍然指向实例对象,而非原型对象,在本题中,实例对象先调用原型对象的getAge()方法,然后输出age属性值,由于该实例对象已经有age属性,同时其原型链中,原型对象和原型对象的原型对象即Object对象均有age属性,依据上述查找规则,最终输出结果为实例对象的age,即为24。


20.下列哪些会返回false?

A null
B undefined
C 0
D ‘0’
答案:ABC
解析:其他类型转Boolean类型的规则: null, undefined, “”, 0, -0, NaN 转换成布尔值是false, 剩下的全转化 true;
针对D ‘0’是字符串 ‘’转字符串才是fasle 别的都是true
其它相关类型转换可见


🎶21.执行以下程序,下列选项中,说法错误的是()

function fn(value){

console.log(arguments instanceof Array); ...①

console.log(arguments.length);...②

console.log(value);...var arr = [...arguments];...}

fn(1,2,3);

A :①式的输出结果为false

B: ②式输出结果为2

C: ③式的输出结果为1

D: ④式可以利用arguments对象新生成一个数组

答案: BD

解析: arguments是函数(除了箭头函数外)的内置对象,它是一个伪数组,因此①式结果为false;arguments对象用来获得函数的全部实参,因此②式输出结果为3而非2;value是函数的形参,匹配第一个实参,因此③式输出结果为1;④式是参数解构,可以新生成一个真正意义上的数组。


🎊22.以下哪些语句触发了隐式的类型转换

A:parseInt(12.34, 10)
B:0 ? 1 : 2
C:2e1 * 0xaa
D:1 + ‘1’

答案: ABD

解析:
A:parseInt() 函数可解析一个字符串,并返回一个整数。
所以说,number类型的12.34发生隐式转换为string。
B:三元运算符,会判断?前的表达式为true或者false。所以number类型的0发生了隐式转换为boolean。
C:e是js里面指数的一种表示形式。也就是10的多少次方。
2e1 等价于 2 *(10^1) = 20
2e2 等价于 2 (10^2)= 200
0xaa是16进制的表示方法。相当于十进制的170。
这里都是number类型,发生了数字的乘法运算:20
170,没有发生类型转换。

D:+运算发生了字符串的隐式转化。原本number类型的1,和string类型的’1’进行了+运算,连接了字符串。返回’11’。


❤️23.var a =[1,4,5,2,9];

下面求a中最大值的代码正确的是

A:Math.max(a)
B:Array.max(a)
C:Math.max.call(null,a)
D:Math.max.apply(null,a)
E:以上均不是

答案: D

解析: 使用apply方法,方法有两个参数,用作 this 的对象和要传递给函数的参数的数组。 可以为方法指定调用对象与传入参数,并且可以让传入的参数以数组的形式组织。 Math.Max.Apply(Math,tmp); 也可以写成 Math.Max.Apply({},tmp);的简写形式


✨24.执行以下程序,输出结果为()

class Phone{
  constructor(price){
    this.price = price;
  }
  get price(){
    return 999;
  }
}
var p = new Phone(888);
console.log(p.price);

A:999
B:undefined
C:抛出异常
D:888

答案: C

解析: 当类中一个属性只有get()方法而无set()方法时,该属性是无法进行赋值的,连构造方法中的初始化都不行,因此,当对象的price属性在构造方法中进行初始化,会抛出异常。


🍿25.对于代码 var a = 10.42; 取出 a 的整数部分,以下代码哪些是正确的?

A:parseInt(a);
B:Math.floor(a);
C:Math.ceil(a);
D:a.split(‘.’)[0];

答案: AB

解析:
A. parseInt转换为整数,默认为10进制,结果为10
B. floor向下取整,结果为10
C. ceil向上取整,结果为11
D. split操作数必需为正则或字符串不能是number,所以不报错


🎀26. 执行以下代码,5 秒后内输出的结果为()

for(var i = 0; i < 5; i++){
    setTimeout(function(){
        console.log(i);
    }, 1000 * i);
}

A:1 2 3 4 5
B:0 1 2 3 4
C:4 4 4 4 4
D:5 5 5 5 5

答案: D

解析: setTimeout()是一个异步函数,由于js会先执行所有同步任务,再执行异步任务,所以当开始执行setTimeout()异步任务时,for循环早已结束,并且由var声明的变量i不具有块级作用域的特点,当for循环结束时,i值为5,故再执行setTimeout()函数时,输出结果为5 5 5 5 5,D选项正确。


🎄27. 执行以下程序,输出结果为()
var uname = "window";

var object = {

            uname :"object",

            fun:function(){

                console.log(this.uname);

                return function(){

                   console.log(this.uname);

                }

            }

}

object.fun()();

A:object

B:window

C:object window

D:window object

答案: C

解析: object.fun()()等效于var fn = object.fun(); fn();实际上是调用函数两次,第一次是调用object对象的fun函数,第二次是调用fun函数的返回函数。第一次调用fun函数时,this指向上一级对象,即object对象,因此输出对象object的uname属性值object,第二次调用的返回函数,其this指向window对象,这是因为匿名函数具有全局性,匿名函数的this指向window对象,因此输出结果为window对象的uname属性值window。


🎉28. 执行以下程序,下列选项中,说法正确的是()
class Dog{
  static dog(){
    console.log(this); // ①
    }
  bark(){
    console.log('狗会叫');
    }
}
var dog = new Dog();

A:①式的this指代类的实例对象

B:调用dog方法,既可以使用Dog.dog(),也可以使用dog.dog()

C:调用bark方法,只能使用dog.bark(),不能使用Dog.bark()

D:在类中,不允许静态方法和非静态方法重名

答案: C

解析: dog方法为静态方法,bark方法为实例方法,静态方法本身不能使用实例对象来调用,所以this不会指向实例对象,A选项错误;静态方法只能由类进行调用,实例方法只能由实例对象进行调用,B选项错误,C选项正确;D选项,由于类内部的静态方法的调用者只能为类,实例方法的调用者只能为实例对象,不会在调用时造成歧义,因此允许重名。


🎏29. 如何阻止IE和各大浏览器默认行为( )

A:window.event.cancelBubble = true;
B:window.event.returnValue = false;
C:event.stopPropagation();
D:event.preventDefault();

答案: BD

解析:
阻止默认事件: e.preventDefault() | e.returnValue = false (IE)

阻止冒泡:e.stopPropagation() | e.cancelBubble = true (IE)


🍧30. 下面哪些语句可以 在JS里判断一个对象是否为String类型?

A:oStringObject instanceof String
B:typeof oStringObject == ‘string’
C:oStringObject is String
D:以上答案都不正确

答案: A

解析: 针对 B 注意题干问的是判断一个对象是否为String类型 typeof 对象 ==>“object”

‘hello’ 和 new String(‘hello’) 的区别,前者是字符串字面值,属于原始类型,而后者是对象

typeof 'hello';  // 'string'
typeof new String('hello');  // 'object'

### 🎀31.下列代码输出什么
["1","2","3"].map(parseInt)

答案: [1,NaN,NaN]
解析: 考察的就是 parseInt 有两个参数。 map 传入的函数可执行三个参数:

// ele   遍历的元素
// index 遍历的元素索引
// arr   数组
arr.map(function(ele, index, arr){})

[‘1’,‘2’,‘3’].map(parseInt)相当于执行了以下三次过程:

parseInt('1', 0, ['1','2','3'])
parseInt('2', 1, ['1','2','3'])
parseInt('3', 2, ['1','2','3'])
  • parseInt(‘1’, 0, [‘1’,‘2’,‘3’]): radix为0时,采用radix的默认值10,即返回一个10进制的结果, ‘1’会先转为1,最后返回1
  • parseInt(‘2’, 1, [‘1’,‘2’,‘3’]): 因为radix取值为2~36,这里是1,所以返回NaN
  • parseInt(‘3’, 2, [‘1’,‘2’,‘3’]): radix取值为2,二进制只包括0,1,返回NaN

本题参考

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐