bilibili2020校园招聘前端笔试卷(一)考点总结与&拓展

443 阅读11分钟

前言

刚刚做完牛客网的选择题,就喜欢做错题然后去理解然后学到了新知识然后很开心,下面来分享一下我觉得有价值的选择题。里面会涉及到网络的知识,JavaScript中map等知识。大家可以结合自己的情况来看看。

第一题:考计网同源策略

这题考的是同源策略,同源策略就是同端口,同协议,同域名。(同源策略是由浏览器来执行。所有的限制都是浏览器的作用。这是浏览器为了保护用户的数据安全而采取的策略)。其中http是协议,域名是store.company.com。端口号默认81。关于url地址栏中内容代表什么意思不懂可以点击https://juejin.cn/post/6844904016569171981查看。

第二题 DOMContentLoaded和load的区别

DOMContentLoaded事件不需要图片等资源都加载完再触发,dom数生成后就会触发。load事件是等所有的资源,图片音频视频等加载完后才会触发。

第六题 css3的box-sizing

这个题在编辑器里试一试,放一张官方文档的截图。

第八题考移位运算符

这道题考点是三个大于号的无符号的右移,会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用1填充。这里就是将-1向右移动32位,然后再去掉末尾的1。

如果要深入理解的话,就涉及到原码反码补码的知识了,正数的的原码补码反码都是一样的,负数的原码最高位1表示负数,其他的与正数一样。负数的反码是除符号位外,其他的与原码相反。补码是反码最末尾加1。

负数是以原码的补码存在的,-1的原码是 10000000 0000000 0000000 00000001,其补码是反码加1, 11111111 11111111 11111111 11111111是其补码,也表示-1。

无符号右移符号位考虑,右移动32位。结果为11111111 11111111 11111111 11111111。因为2^32=1 00000000 00000000 00000000 00000000 ,所以2^32-1就是我们需要的结果。

知识点补充

关于移位运算符,有无符号左移无符号右移,有符号右移,想了解的更多,请点击这里。<a blog.csdn.net/u012436639/…

第九题 考优先级&类型转换。

这个题我想了好久大于小于号是什么运算符,百度是关系运算符。哈哈哈哈脑子不好使这些很基础的东西都记不清楚。运算符分为关系运算符,算术运算符,位运算符,逻辑运算符。 多个同级的运算符是从左到右的。

1<2 的结果是true,布尔值true遇到小于号转换成数字1。1 < 3 结果为真。后面的也是一样的道理。

第十题考数组的map方法(细节题)

这道题考点有parseInt方法和数组的map方法,如果这两个方法不懂那么很难做出来。

1.首先来说一下map函数,map方法返回一个新数组,数组里面的3元素为原始数组执行调用函数返回的结果,其中map不会对空数组进行改变检测,也不会改变原数组。map的参数有两个,一个是要执行的函数(必须要有),一个是this对象(不一定要有).执行的函数也有三个参数,前面两个必须要有,第一个是当前元素的值,第二个是当前元素的索引,第三个是素组本身。

2.该题目中没有this对象,那么this就指向全局。parseint就是要执行的函数。

3.再来说说parseInt函数,这个函数有两个参数,后面的是基底,前面的参数是一个以该基底来表示的一个数。基底范围在2~36之间,如果基底=0或者不给出基底这个参数,默认的会以10进制表示这个数。如果基底小于2或者大于36那么返回的结果就是NAN。

4.parseInt这方法就是将该基底作为进制的一个数转化为十进制的数。比如下面的一个例子中,就是将以二进制数11转化成对应的十进制数。结果就是3。

parseInt("11",2);		//返回 3 (2+1)

回归到这个题目里面,将数组['1','2','3']执行parseInt的时候,第一个元素的索引为0,那么返回的结果是将10进制的1转成十进制那么就是1,第二个元素的索引值是1,将1进制的2转换成十进制,那么结果是NAN,同理,第三个元素的结果NAN。通过map函数返回新数组就是答案D。

笔试卷2的扩充

['10', '10', '10', '10', '10'].map(parseInt); 笔试卷2中有这么一道题。2019.12.21号又弄了半天,我犯了两个错误。

第一个是(10,3)我误认为是3进制的十,这种是错误的,应该是3进制的一零(1 0)。

第二个错误是map方法里面只有两个参数。第一个是一个回调函数(item,index,arr)前面两个位置千万不能记混淆,第二个this。

某进制转十进制的方法: 如:(333)4转十进制是34^2+34^1+3*4^0;

所以这道题0进制的10===10进制的10转化成10进制,结果是10;1进制的10转成10进制,结果是NAN;然后2进制的10转成10进制,结果是2;3进制的10转成10进制,就是3;

第十二题 考js的执行机制

js的执行机制参考博文可以参考博文链接。js是单线程的,但是单线程也分同步任务和异步任务。首先执行conlse,再promise微任务,最后settimeout宏任务

第15题 数组的方法

slice方法返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素。这个例子里面就是截取数组里下标为1的元素到从末尾开始的第一位元素(不包括该元素)作为新数组返回,实现了删除第一位和最后一位。

reserve是颠倒数组,tostring是转成字符串,js里面的没有replace方法,splice方法可以实现数组替换。

第13题 Math的方法

这个题选D,abs是返回该参数的绝对值,这题不难但是有两个知识点需要补充一下。

补充知识点1:

Math.round该方法是四舍五入给给定的一个数字返回一个整数。当数是正数的时候很好理解,当该数为负数的时候不是简单地四舍五入,而是将其+0.5后再向下取整。 我在控制台打印几句话就很好理解了。

简单说明,-5.87+0.5=-5.37,然后向下取整就是-6。

补充知识点2:

这个是关于精度的问题,出于好奇我试了一下在控制台输出1/3的结果。以及0.1+0.3的结果是0.3000000000000004小数点后共16位。

首先这不是一个错误,原因是十进制与二进制精度转换的问题。

计算机是01的世界,都是以二进制来存储的,就像十进制数无法表示1/3一样,二级制数也也无法正确的表示0.1,会无限的循环下去,所以会出现这种错误。

第16题 考原型(重点)

这是一道关于原型的题目,关于原型每次看的时候感觉明白了,但是做起题有点怂哈哈哈,哈还是做少了,这个题有一个构造函数。一个setname的构造函数,原型上有一个打印name的方法,new了一个对象,名字为cc,然后修改了姓名为dd。最后a原型上姓名改成了ee。所以最后的结果是ee和dd。我当时就是瞎选的一个选项啊哈哈哈。

关于16题的引申

原型的题仔细思考并不难,在这里我想额外的扩展一道题。

	   function Foo() {
            getName = function() {
                console.log(1);
            };
            return this;
        }
        Foo.getName = function() {
            console.log(2);
        };
        Foo.prototype.getName = function() {
            console.log(3);
        };
        var getName = function() {
            console.log(4);
        };
        function getName() {
            console.log(5);
        }

        //请写出以下输出结果:
        Foo.getName();  //2
        getName();  //4
        Foo().getName();  //1
        getName();  //1
        new Foo.getName();//2
        new Foo().getName();//3
        new new Foo().getName();

对于第一问

结果为2不用多说。

对于第二问

我第一次做的时候认为结果是5,这个题存在一个在预编译环节中变量声明提升的问题,对于预编译环节不清楚可以参考国庆节写的一篇讲预编译的博文。这里我要说的是预编译的第四不要函数声明的提升是函数整体提升,也就是先让getName=function(){console.log(5)},然后getName=function(){console.log(4)};最后的结果就是4。

这个图片中的例子最后打印的结果也是4,不是其他。

对于第三问

先执行构造函数Foo,执行构造函数的时候不会打印console.log(1)因为执行了函数赋值语句,没有执行函数里面的内容,里面的内容是执行getName的时候才会执行。该构造函数返回了this,这个时候的this指向全局,在构造函数中没有发现getNam这个变量,于是沿着作用域链往上面找,在全局中找到了,于是全局中的getName=function() { console.log(1); };最后的结果就是1。

对于第四问

同第三问一样,也是全局里面找,最后的结果是1.

对于第五问

使用了new操作符,这里new Foo.getName()相当于把Foo.getname()当成构造函数,执行了new (Foo.getName) (),所以结果是2。

对于第六问

new Foo().getName();是先new Foo()返回this这个实例化对象,然后再this.getName。 这道题必须明白new的原理。

new 一个对象的时候发生了以下几件事情:

1.创建一个新对象
2.获得构造函数
3.链接到原型
4.绑定this,执行构造函数
5.返回新对象

 function create() {
    // 创建一个空对象
    let obj = new Object();
    // 获得构造函数, arguments中去除第一个参数(第一个参数为构造函数)
    let Con = [].shift.call(arguments);
    // 链接到原型
    obj.__proto__ = Con.prototype;
    // 绑定this,执行构造函数
    let result = Con.apply(obj, arguments);
    // 优先返回构造函数返回的对象
    return typeof result === 'object' ? result : obj;
}


这里new Foo()后返回this指向对象实例化本身。然后没有构造方法里面没有getName方法就要去原型链中找。这里Foo.getName = function() { console.log(2); };只是Foo私有的一个方法,不会给它的实例化对象,除非Foo构造函数中有this.getName()

对于第七问

new new Foo().getName();等同于在把第六问的问题当成构造函数,然后再new操作,也就是对原型上面的getName方法为构造函数执行,执行后返回的结果是3.

第17题 数组内置方法

find返回符合测试条件的第一个数组元素的值,如果没有符合条件的则返回undefined

fliter是过滤出两项并返回。find是返回第一项,find()方法返回第一个满足过滤方法的元素,一个都没有满足的就返回undefined,遇到一个满足的元素后遍历就停止。

这里&gt 是‘>’的转义字符,&amp是“&”的转义字符。

总结

这是第一次在牛客网上刷题,多刷题才知道知道自己的不足。基本功很重要。其中我觉得16题的原型题是重点,拓展的题来自于click here。然后有一些细节题比如第八题的无符号右移以及数组的map方法和pareint方法中的参数分别是什么要弄清楚,12题异步的问题。拿出来分享给大家。