当前位置:   article > 正文

2023面试题记录-更新(增加鸿蒙内容)_鸿蒙前端招聘面试题目

鸿蒙前端招聘面试题目

一、JS相关

1、js怎么判断对象为空?

判断对象是否为空的一个简单方法是检查对象的所有可枚举属性。如果一个对象没有可枚举属性,那么我们可以认为它是空的。你可以使用 Object.keys() 函数来获取对象的所有可枚举属性,然后检查得到的数组的长度。如果长度为0,那么对象是空的。

  1. function isEmpty(obj) {
  2. return Object.keys(obj).length === 0 && obj.constructor === Object;
  3. }
  4. var myObj = {};
  5. if (isEmpty(myObj)) {
  6. console.log("对象是空的");
  7. } else {
  8. console.log("对象不是空的");
  9. }

2、最新的 url 参数获取的 API

对于获取URL参数的API,你可以使用JavaScript的URLSearchParams接口

  1. const urlParams = new URLSearchParams(window.location.search);
  2. const myParam = urlParams.get('myParam');

3、新版本发布后,怎么用技术手段通知用户刷新页面?

新版本发布后,你可以使用Web Push通知用户刷新页面。

  1. if ('serviceWorker' in navigator) {
  2. navigator.serviceWorker.register('/service-worker.js')
  3. .then(() => console.log('Service Worker Registered'))
  4. .catch(err => console.log('Service Worker Registration Failed: ', err));
  5. }

4、缓存

        4.1、强缓存

        强制浏览器在一定时间内直接从本地缓存读取数据,不向服务器发送请求。强缓存可以通过设置响应头信息实现,常见的响应头有 Expires 和 Cache-Control。

        4.2、协商缓存

        在强缓存失效时,浏览器会向服务器发送请求,询问服务器该资源在最后一次访问后是否有修改。如果没有修改,服务器会返回 304 状态码,告诉浏览器可以继续使用本地缓存,否则会返回新的资源内容。协商缓存可以通过设置响应头信息实现,常见的响应头有 Last-Modified 和 ETag。

        4.3、浏览器缓存的主要流程可以概括为以下几个步骤:

            4.3.1、浏览器收到 HTTP 请求时,会根据 URL 判断该资源是否已经被缓存。如果已经被缓存,则直接从本地缓存读取资源。
            4.3.2、如果未被缓存或者缓存已经过期,浏览器会向服务器发送请求,并在请求中带上一些信息,例如上次访问时间、Etag 等。
服务器收到请求后,根据请求中的信息判断资源是否有更新。如果资源没有更新,则返回一个 304 响应码,告诉浏览器可以继续使用本地缓存;如果资源已经更新,则返回新的资源内容和一些缓存相关的头信息。
            4.3.3、浏览器收到响应后,会根据响应头信息来更新本地缓存,并将新的资源内容展示给用户

5、new一个构造函数的过程

  • 创建一个空对象。
  • 将这个新对象的原型指向构造函数的prototype属性。
  • 执行构造函数,并且将this指向新创建的对象。
  • 如果构造函数没有返回值或者返回一个非对象值,则返回新创建的对象。如果构造函数返回一个对象,则返回这个对象。
  1. function myNew(ctor, ...args) {
  2. // 创建一个新对象,并将该对象的原型指向构造函数的原型对象
  3. const obj = Object.create(ctor.prototype);
  4. // 调用构造函数,并将新对象作为 this 参数传递进去
  5. const result = ctor.apply(obj, args);
  6. // 如果构造函数返回了一个非空对象,则返回该对象;否则,返回创建的新对象
  7. if (typeof result === 'object' && result !== null) {
  8. return result;
  9. }
  10. return obj;
  11. }
  12. // 测试:
  13. function Person(name, age) {
  14. this.name = name;
  15. this.age = age;
  16. }
  17. const person = myNew(Person, '张三', 18);
  18. console.log(person.name); // 输出:张三
  19. console.log(person.age); // 输出:18

6、EventLoop

  1. 代码开始执行,创建一个全局调用栈,script作为宏任务执行
  2. 执行过程过同步任务立即执行,异步任务根据异步任务类型分别注册到微任务队列和宏任务队列
  3. 同步任务执行完毕,查看微任务队列
    • 若存在微任务,将微任务队列全部执行(包括执行微任务过程中产生的新微任务)
    • 若无微任务,查看宏任务队列,执行第一个宏任务,宏任务执行完毕,查看微任务队列,重复上述操作,直至宏任务队列为空
    • 宏任务(script、定时器、ajax、I/O);微任务(promise.then、async await、MutationObserve 监听dom变化)

7、什么是js原型链

        JavaScript中的每个对象都有一个原型,也就是它们继承属性和方法的对象。而这个原型又可以有自己的原型,形成了所谓的“原型链”。
        当我们访问一个JavaScript对象的属性或方法时,首先会在该对象本身查找是否存在该属性或方法。如果不存在,它会沿着该对象的原型链向上查找,一直到Object.prototype为止。如果还没有找到,则返回undefined。

        因此,通过原型链,我们可以实现继承和代码复用。例如,我们可以创建一个基础对象,并将其作为其他对象的原型,使得后者能够共享基础对象的属性和方法。

8、防抖&节流

  1. // 防抖-多次点击,只执行一次
  2. function debounces(fn, time) {
  3. let timer
  4. return function() {
  5. if(timer) {
  6. clearTimeout(timer)
  7. }
  8. timer = setTimeout(() => {
  9. fn.apply(this, arguments);
  10. }, time)
  11. }
  12. }
  13. // 节流-一定时间内,只执行一次
  14. function throttle(fn, time) {
  15. let timer
  16. return function() {
  17. if (timer) {
  18. timer = setTimeout(() => {
  19. fn.apply(this, arguments)
  20. timer = null
  21. }, time)
  22. }
  23. }
  24. }

9、typeOf和intanceOf 的区别

typeOf:用于检查基础数据类型

intanceOf:用于检查引用数据类型

注:准确检查类型可以使用原型链 

Object.prototype.toString.call():

10、作用域和作用域链

10.1 作用域

  • 全局作用域(只想windows)
  • 函数作用域(函数内部可见)
  • 块级作用域(代码块中可见或者let/const)

10.2 作用域链

        作用域链是指在嵌套函数中,内部函数可以访问外部函数中的变量。当内部函数访问一个变量时,如果当前作用域中找不到该变量,它会沿着作用域链向上查找,直到找到该变量或达到全局作用域。这种嵌套的作用域链关系允许内部函数访问外部函数的变量。

11、JSON深拷贝的问题

        无法正确处理包含函数正则表达式Date 对象非 JSON 数据类型的对象。

12、http和https的区别

  • HTTPS:通过使用 SSL/TLS 加密协议对数据进行加密、443端口、连接之前需要进行SSL/TLS 握手过程,包括服务器证书验证、密钥交换等。
  • HTTP:明文传输协议、80端口、TCP三次握手

13、深克隆的方式有哪些?