打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
字节跳动最爱考的web前端面试题:计算机网络基础
userphoto

2022.11.23 上海

关注

能有大厂面试的机会,绝对要去珍惜,因为他真的可以帮你找出你太多的不足,准确命中你的弱点!还有,一定要善于总结经验,总结面试题,为后面的面试储蓄能量。下面小编就给大家总结了字节跳动最爱考的前端问题,小伙伴们快活学活用起来~

注意:每道题前面出现的 (xx) 数字代表这道题出现的频次,此 JS 基础是基于 30+ 篇前端面经整理出的问题和对应的回答、参考链接等。

问:js脚本加载问题,async、defer问题

· 如果依赖其他脚本和 DOM 结果,使用 defer

· 如果与 DOM 和其他脚本依赖不强时,使用 async

问:如何判断一个对象是不是空对象?

Object.keys(obj).length === 0

问: <script src=’xxx’ ’xxx’/>外部js文件先加载还是onload先执行,为什么?
onload 是所以加载完成之后执行的

问:怎么加事件监听,两种
onclick 和 addEventListener

问:事件传播机制(事件流)
冒泡和捕获

(4)问:说一下原型链和原型链的继承吧

· 所有普通的 [[Prototype]] 链最终都会指向内置的 Object.prototype,其包含了 JavaScript 中许多通用的功能

·  为什么能创建 “类”,借助一种特殊的属性:所有的函数默认都会拥有一个名为 prototype 的共有且不可枚举的属性,它会指向另外一个对象,这个对象通常被称为函数的原型

1. function Person(name) { 

2.  this.name = name; 

3.    } 

4.     

5. Person.prototype.constructor = Person 

· 在发生 new 构造函数调用时,会将创建的新对象的 [[Prototype]] 链接到 Person.prototype 指向的对象,这个机制就被称为原型链继承

· 方法定义在原型上,属性定义在构造函数上

·  首先要说一下 JS 原型和实例的关系:每个构造函数 (constructor)都有一个原型对象(prototype),这个原型对象包含一个指向此构造函数的指针属性,通过 new 进行构造函数调用生成的实例,此实例包含一个指向原型对象的指针,也就是通过[[Prototype]] 链接到了这个原型对象

· 然后说一下 JS 中属性的查找:当我们试图引用实例对象的某个属性时,是按照这样的方式去查找的,首先查找实例对象上是否有这个属性,如果没有找到,就去构造这个实例对象的构造函数的 prototype 所指向的对象上去查找,如果还找不到,就从这个 prototype 对象所指向的构造函数的 prototype 原型对象上去查找

· 什么是原型链:这样逐级查找形似一个链条,且通过[[Prototype]] 属性链接,所以被称为原型链

·  什么是原型链继承,类比类的继承:当有两个构造函数 A 和 B,将一个构造函数 A 的原型对象的,通过其 [[Prototype]] 属性链接到另外一个 B 构造函数的原型对象时,这个过程被称之为原型继承。

标准答案更正确的解释
什么是原型链?

当对象查找一个属性的时候,如果没有在自身找到,那么就会查找自身的原型,如果原型还没有找到,那么会继续查找原型的原型,直到找到 Object.prototype 的原型时,此时原型为 null,查找停止。这种通过 通过原型链接的逐级向上的查找链被称为原型链

什么是原型继承?

一个对象可以使用另外一个对象的属性或者方法,就称之为继承。具体是通过将这个对象的原型设置为另外一个对象,这样根据原型链的规则,如果查找一个对象属性且在自身不存在时,就会查找另外一个对象,相当于一个对象可以使用另外一个对象的属性和方法了。

问:说下对 JS 的了解吧
是基于原型的动态语言,主要独特特性有 this、原型和原型链。

JS 严格意义上来说分为:语言标准部分(ECMAScript)+ 宿主环境部分

语言标准部分
2015 年发布 ES6,引入诸多新特性使得能够编写大型项目变成可能,标准自 2015 之后以年号代号,每年一更

宿主环境部分
在浏览器宿主环境包括 DOM + BOM 等
在 Node,宿主环境包括一些文件、数据库、网络、与操作系统的交互等
问:数组能够调用的函数有那些?

· push

· pop

· splice

· slice

· shift

· unshift

· sort

· find

· findIndex

· map/filter/reduce 等函数式编程方法

· 还有一些原型链上的方法:toString/valudOf

问:如何判断数组类型
Array.isArray

问: 函数中的arguments是数组吗?类数组转数组的方法了解一下?
是类数组,是属于鸭子类型的范畴,长得像数组,

... 运算符
Array.from
Array.prototype.slice.apply(arguments)
问:用过 TypeScript 吗?它的作用是什么?
为 JS 添加类型支持,以及提供最新版的 ES 语法的支持,是的利于团队协作和排错,开发大型项目

问:PWA使用过吗?serviceWorker的使用原理是啥?
渐进式网络应用(PWA)是谷歌在2015年底提出的概念。基本上算是web应用程序,但在外观和感觉上与原生app类似。支持PWA的网站可以提供脱机工作、推送通知和设备硬件访问等功能。

Service Worker是浏览器在后台独立于网页运行的脚本,它打开了通向不需要网页或用户交互的功能的大门。现在,它们已包括如推送通知和后台同步等功能。将来,Service Worker将会支持如定期同步或地理围栏等其他功能。本教程讨论的核心功能是拦截和处理网络请求,包括通过程序来管理缓存中的响应。

问:ES6 之前使用 prototype实现继承
Object.create() 会创建一个 “新” 对象,然后将此对象内部的 [[Prototype]] 关联到你指定的对象(Foo.prototype)。Object.create(null) 创建一个空 [[Prototype]] 链接的对象,这个对象无法进行委托。

1. function Foo(name) { 

2. this.name = name; 

3. } 

4.     

5.Foo.prototype.myName = function () { 

6. return this.name; 

7. } 

8.     

9. // 继承属性,通过借用构造函数调用 

10. function Bar(name, label) { 

11.Foo.call(this, name); 

12.this.label = label; 

13. } 

14.  

15. // 继承方法,创建备份 

16. Bar.prototype = Object.create(Foo.prototype); 

17.  

18. // 必须设置回正确的构造函数,要不然在会发生判断类型出错 

19. Bar.prototype.constructor = Bar; 

20.  

21.  // 必须在上一步之后 

22. Bar.prototype.myLabel = function () { 

23.return this.label; 

24. } 

25.  

26. var a = new Bar("a", "obj a"); 

27.  

28. a.myName(); // "a" 

29. a.myLabel(); // "obj a" 

问:如果一个构造函数,bind了一个对象,用这个构造函数创建出的实例会继承这个对象的属性吗?为什么?
不会继承,因为根据 this 绑定四大规则,new 绑定的优先级高于 bind 显示绑定,通过 new 进行构造函数调用时,会创建一个新对象,这个新对象会代替 bind 的对象绑定,作为此函数的 this,并且在此函数没有返回对象的情况下,返回这个新建的对象

(3)箭头函数和普通函数有啥区别?箭头函数能当构造函数吗?

1.  普通函数通过 function 关键字定义, this 无法结合词法作用域使用,在运行时绑定,只取决于函数的调用方式,在哪里被调用,调用位置。(取决于调用者,和是否独立运行)

2.  箭头函数使用被称为 “胖箭头” 的操作 => 定义,箭头函数不应用普通函数 this 绑定的四种规则,而是根据外层(函数或全局)的作用域来决定 this,且箭头函数的绑定无法被修改(new 也不行)。

· 一个函数内部有两个方法:[[Call]] 和 [[Construct]],在通过 new 进行函数调用时,会执行 [[construct]] 方法,创建一个实例对象,然后再执行这个函数体,将函数的this 绑定在这个实例对象上

·当直接调用时,执行 [[Call]] 方法,直接执行函数体

·  箭头函数没有 [[Construct]] 方法,不能被用作构造函数调用,当使用 new 进行函数调用时会报错。

·  箭头函数常用于回调函数中,包括事件处理器或定时器

·  箭头函数和 var self = this,都试图取代传统的 this 运行机制,将 this 的绑定拉回到词法作用域

· 没有原型、没有 this、没有 super,没有 arguments,没有 new.target

· 不能通过 new 关键字调用

1. function foo() { 

2. return (a) => { 

3. console.log(this.a); 

4. } 

5. } 

6.     

7. var obj1 = { 

8. a: 2 

9. } 

10.  

11. var obj2 = { 

12. a: 3  

13. } 

14.  

15. var bar = foo.call(obj1); 

16. bar.call(obj2); 

问:知道 ES6 的 Class 嘛?Static 关键字有了解嘛
为这个类的函数对象直接添加方法,而不是加在这个函数对象的原型对象上

(3)问:事件循环机制 (Event Loop)
事件循环机制从整体上告诉了我们 JavaScript 代码的执行顺序Event Loop即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。

先执行宏任务队列,然后执行微任务队列,然后开始下一轮事件循环,继续先执行宏任务队列,再执行微任务队列。

·宏任务:script/setTimeout/setInterval/setImmediate/ I/O / UI Rendering

· 微任务:process.nextTick()/Promise

上诉的 setTimeout 和setInterval 等都是任务源,真正进入任务队列的是他们分发的任务。

优先级

· setTimeout = setInterval 一个队列

· setTimeout > setImmediate

· process.nextTick > Promise

1. for (const macroTask of macroTaskQueue) {   

2. handleMacroTask();     

3. for (const microTask of microTaskQueue) {     

4. handleMicroTask(microTask);   

5. } 

6. } 

(2)手写题:数组扁平化

1. function flatten(arr) { 

2.  let result = []; 

3.     

4. for (let i = 0; i < arr.length; i++) { 

5. if (Array.isArray(arr[i])) { 

6. result = result.concat(flatten(arr[i])); 

7.  } else { 

8. result = result.concat(arr[i]); 

9.  } 

10.   } 

11.  

12. return result; 

13. } 

14.  

15. const a = [1, [2, [3, 4]]]; 

16. console.log(flatten(a)); 

手写题:实现柯里化
预先设置一些参数

柯里化是什么:是指这样一个函数,它接收函数 A,并且能返回一个新的函数,这个新的函数能够处理函数 A 的剩余参数

1.function createCurry(func, args) { 

2. var argity = func.length; 

3. var args = args || []; 

4.       

5.  return function () { 

6. var _args = [].slice.apply(arguments); 

7. args.push(..._args); 

8.         

9. if (args.length < argity) { 

10. return createCurry.call(this, func, args); 

11. } 

12.      

13.return func.apply(this, args); 

14. } 

15. } 

手写题:数组去重

1.    Array.from(new Set([1, 1, 2, 2])) 

问:let 闭包
let 会产生临时性死区,在当前的执行上下文中,会进行变量提升,但是未被初始化,所以在执行上下文执行阶段,执行代码如果还没有执行到变量赋值,就引用此变量就会报错,此变量未初始化。

问:变量提升
函数在运行的时候,会首先创建执行上下文,然后将执行上下文入栈,然后当此执行上下文处于栈顶时,开始运行执行上下文。

在创建执行上下文的过程中会做三件事:创建变量对象,创建作用域链,确定 this 指向,其中创建变量对象的过程中,首先会为 arguments 创建一个属性,值为 arguments,然后会扫码 function 函数声明,创建一个同名属性,值为函数的引用,接着会扫码 var 变量声明,创建一个同名属性,值为 undefined,这就是变量提升。

文章来源:网络  版权归原作者所有

上文内容不用于商业目的,如涉及知识产权问题,请权利人联系小编,我们将立即处理

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
修改构造函数原型——JavaScript中的对象(二)
js的原型及继承实现 | 一锅乱炖
前端整理——javaScript部分
javascript——prototype与
10、JS | 给已有的类原型添加属性和方法
JavaScript 面向对象编程
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服