前端js面试题 (四)

文章目录

    • ES6新增的proxy
    • 手写,proxy访问某对象输出别的数字
    • 深度拷贝,为啥无法使用JSON.parse(JSON.stringify(obj))
    • 异步编程有哪些,async await来由,本质原理是什么
    • 事件队列输出题
      • 第一题
      • 第二题
      • 第三题
    • 粘性布局的原理,以及要自己实现应该怎么办
    • this指向题
    • `window.onload` 和 `jquery`的`$(document).ready()`的区别
    • 浏览器在渲染页面的时候到底做了些什么?

在这里插入图片描述

ES6新增的proxy

ES6引入了Proxy(代理)对象,它提供了一种拦截和自定义操作对象行为的机制。Proxy允许你在目标对象的基础上封装一个代理对象,通过定义各种拦截器来拦截对目标对象的访问和修改。

get(target, property, receiver): 拦截对目标对象属性的读取操作。
set(target, property, value, receiver): 拦截对目标对象属性的设置操作。
apply(target, thisArg, argumentsList): 拦截对目标对象的函数调用。
construct(target, argumentsList, newTarget): 拦截对目标对象的new操作符。

更多内容请参考
把es6 proxy 和 vue3.0的proxy一起学了

手写,proxy访问某对象输出别的数字

  const handler = {
    get: function (target, key) {
      return Math.random() * 10;
    },
  };

  const obj = {
    name: "dx",
    age: "18",
  };

 const p = new Proxy(obj, handler);

 console.log(p.name)

深度拷贝,为啥无法使用JSON.parse(JSON.stringify(obj))

因为转换过后,很多js的数据会发生变化,无法与原数据完全一致。

哪些js中的数据类型或者哪些场景下,JSON无法转化?

  1. new Date()
    转变后一个Date对象变成了时间字符串
 JSON.parse(JSON.stringify({a: new Date()})); // {a: '2023-11-11T07:13:19.302Z'}
  1. 对象中出现循环引用
// 循环引用
const jsonStr = '{ "key": {} }';
const obj = JSON.parse(jsonStr);
obj.key.circularReference = obj; // 循环引用
JSON.stringify(obj); // 在调用 JSON.stringify 时,会抛出 TypeError
  1. function
    转变后是一个空对象
JSON.parse(JSON.stringify({a: function(){}})); // {}
  1. undefined
    转变后是一个空对象
JSON.parse(JSON.stringify({a: undefined})); // {}
  1. NaN Infinity -Infinity
    转变后都会变为null
JSON.parse(JSON.stringify({a: NaN})); // {a: null}
  1. new RegExp()
    属性还在,但值变为空对象
JSON.parse(JSON.stringify({a: new RegExp('\\ww')})); // {a: {}}
  1. new Error()
    属性还在,但值变为空对象
JSON.parse(JSON.stringify({a: new Error('xxxx')})); // {a: {}}

所以,为了保证深度拷贝的万无一失,需要考虑各种情况,不是简单的JSON就能完成的,即使以上情况都没有,为了确保 JSON.parse() 不会失败,提供的 JSON 字符串应该是有效的、符合规范的,并且不包含不支持的数据类型。在处理可能导致异常的情况时,最好使用 try...catch 来捕获异常并进行相应的处理。

深度拷贝 leader:深拷贝有这5个段位,你只是青铜段位?还想涨薪?

异步编程有哪些,async await来由,本质原理是什么

异步编程的方式:回调函数,Promise,async await

async/await 的来由:
它的目标是简化和改善异步代码的可读性和可维护性,使开发者更容易理解和编写异步操作。

async/await 的本质原理:
async 函数: 使用 async 关键字声明的函数始终返回一个 Promise 对象。在 async 函数内部,通过 await 关键字等待异步操作的结果。当 await 后面的表达式解决时,函数将会从暂停的地方继续执行。

await 表达式: await 用于等待一个 Promise 解决,然后获取解决的值。在等待期间,async 函数会被暂停,允许其他代码执行。如果 Promise 解决为拒绝,await 将抛出一个异常,可以通过 try…catch 捕获。

async/await 的本质是基于 Promise,它提供了一种更直观的语法来编写异步代码,使得异步操作更容易理解和维护。在底层,async/await 仍然是依赖于 Promise 的实现。

promise成功时

async function fetchDataAsync() {
  const data = await new Promise((res,rej) => {res(1)});
  console.log(data); // 1
}
const a = fetchDataAsync()
console.log(a) // Promise {<fulfilled>: undefined} 一个promise对象,状态是 fulfilled

promise报错时

async function fetchDataAsync() {
  const data = await new Promise((res,rej) => {rej('出错了')});
  console.log(data); // Uncaught (in promise) 出错了
}
const a = fetchDataAsync()
console.log(a) // Promise {<pending>}  promise 对象,状态是rejected

如果await后根本就不是promise

async function fetchDataAsync() {
  const data = await console.log('不是promise');
  console.log(data); // undefined
}
const d = fetchDataAsync()
console.log(d) // Promise {<pending>} 一个promise对象,状态是 fulfilled

事件队列输出题

第一题

console.log('Start');

setTimeout(function() {
  console.log('Timeout');
}, 0);

Promise.resolve().then(function() {
  console.log('Promise');
});

new Promise((res,rej) => {
	console.log('Promise2')
	res(1)	
}).catch((e) => {
	console.log('出错了')
})

console.log('End');

Start 最先,
setTimeout属于宏任务,往宏任务队列里放,
Promise then里面的回调,属于微任务,往微任务队列里放,
Promise2是同步的,它第二,
res(1) 这儿是resolve了,所以catch不会执行,不用放到微任务队列里
End 第三
所有同步执行完了,开始执行异步,先将微任务队列全部执行(队列先进先出)。
Promise 第四
微任务队列执行完了,执行一个宏任务队列里的任务
Timeout 最后

第二题

async function asyncFunction() {
  console.log('Async Start');

  const promise = new Promise((resolve) => {
    setTimeout(() => {
      resolve('Async Timeout');
    }, 0);
  });

  const result = await promise;
  console.log(result);

  console.log('Async End');
}

console.log('Script Start');
asyncFunction();
console.log('Script End');

Script Start 第一,
asyncFunction执行函数体 Async Start第二,
setTimeout 放入宏任务队列,先不执行
遇到await ,不执行asyncFunction函数体await后的内容,跳出函数体
Script End 第三
同步执行完,开始执行异步,微任务队列全部执行,没有,执行一个宏任务
宏任务 resolve('Async Timeout')执行,result拿到了值,接着执行asyncFunction未执行完的函数体
Async Timeout 第四
Async End 第五

第三题

async function async1() {
	console.log('async1 start');
	await async2();
	console.log('asnyc1 end');
}
async function async2() {
	console.log('async2');
}
console.log('script start');
setTimeout(() => {
	console.log('setTimeOut');
}, 0);
async1();
new Promise(function (reslove) {
	console.log('promise1');
	reslove();
}).then(function () {
	console.log('promise2');
})
console.log('script end');

同步任务

// script start
// async1 start
// async2
// promise1
// script end

微任务

// asnyc1 end
// promise2

宏任务

// setTimeOut

粘性布局的原理,以及要自己实现应该怎么办

原理就是监听滚动条的变化,每一次滚动条变化后,就计算dom距离顶部或者底部的距离,如果距离小于我们设计的值,就让dom 的position改为fixed 或者absolute(当粘性布局不是对于window来说时)。
请参考Affix组件 vue3 组件篇 affix

this指向题

var name = 1
var obj = {
    name: 2,
    getName: function () {
        console.log(this.name)
    }
}
setTimeout(obj.getName, 0)

输出结果是什么? 1 怎么改才能是2

var name = 1
var obj = {
    name: 2,
    getName: function () {
        console.log(this.name)
    }
}
setTimeout(function(){ obj.getName() }, 0)

原题不改的情况下,严格模式会发生什么? // 会报错,严格模式,this在全局作用域中指向undefined。

JavaScript 的严格模式(strict mode)是一种在语言层面上的约束,它被设计用来提供更强的错误检测和更安全的代码。启用严格模式的方式是在脚本或函数的开头添加 'use strict';

以下是严格模式的一些主要特性:

  1. 变量声明必须使用 varletconst

    • 在严格模式下,未经声明直接赋值给变量会导致引发错误。
  2. 全局变量显式声明:

    • 在严格模式下,全局变量必须使用 var 关键字显式声明。
  3. 删除不可删除的属性时会引发错误:

    • 在严格模式下,尝试删除不可删除的属性会引发错误。
  4. 函数参数命名唯一性:

    • 在严格模式下,函数的参数不能有重复的名称。
  5. 禁止使用 with 语句:

    • 在严格模式下,使用 with 语句会导致引发错误。
  6. 禁止给只读属性赋值:

    • 在严格模式下,给只读属性(如 Math.PI)赋值会引发错误。
  7. 禁止删除变量:

    • 在严格模式下,使用 delete 操作符删除变量、函数或函数参数会引发错误。
  8. 保留字的限制:

    • 在严格模式下,一些在 ECMAScript 5 中被保留但没有特定用途的关键字变得不能用作变量名或函数名。
  9. this 在全局作用域中为 undefined

    • 在严格模式下,全局作用域中函数的 this 值为 undefined,而不是全局对象。
  10. 禁止使用 arguments.calleearguments.caller

    • 在严格模式下,arguments.calleearguments.caller 都会引发错误。
  11. eval 在其自己的词法作用域中运行:

    • 在严格模式下,eval 不再在调用时共享变量环境,它有自己的词法作用域。
  12. evalarguments 不能被重新赋值:

    • 在严格模式下,evalarguments 不能被重新赋值。
  13. 不允许给 evalarguments 传递字符串:

    • 在严格模式下,给 evalarguments 传递字符串会创建新的变量,而不是使用当前作用域中的变量。

使用严格模式有助于减少一些常见的编码错误,提高代码的可维护性和安全性。

window.onloadjquery$(document).ready()的区别

window.onload 浏览器所有的资源(图片,视频等多媒体文件)加载后触发load事件
$(document).ready() 是在dom解析完成后就触发。$(document).ready()window.onload 之前触发。

浏览器在渲染页面的时候到底做了些什么?

这里从建立tcp链接之后开始讲起,之前的过程中,浏览器经历了什么暂时不讨论,如果关心这一部分的同学,可以查阅一下,在浏览器输入url后,浏览器做了。

  1. 客户端向服务器请求下载index.html
  2. 下载完成后,解析index.html文件,从上至下。解析的同时,创建Document对象,没错就是平时用的document,比如document.createElement('div'), 解析HTML元素,和它们的文本内容,添加Element对象和Text节点到文档中, 这个阶段,document.readyState = 'loading',我们也称之为开始创建DomTree。
  3. 如果遇到link外部css,创建线程加载,我们称之为创建CssTree,与此同时继续解析文档。
  4. 遇到script外部js,并且没有设置asyncdefer,浏览器停止解析html,开始下载对应的js,下载完成后,执行js,等执行完成后,继续解析html。
  5. 遇到script外部js,设置了 async, 浏览器创建新的线程下载js,于此同时继续解析html,等js下载完成后,暂停html的解析,开始执行下载的js,js执行完成后,继续解析html。(异步禁止使用document.write() 这会清空之前解析的dom)。
  6. 遇到script外部js,设置了 defer(只对ie9之前的版本有效),浏览器创建新的线程下载js,于此同时继续解析html,等js下载完成后,js不会执行,浏览器继续解析html。(异步禁止使用document.write() 这会清空之前解析的dom)
  7. 遇到 img,video,audio,iframe等多媒体标签时,浏览器会创建新的线程,去异步加载src,同时继续解析html。
  8. html文档全部解析完成后,document.readyState='interactive'所有设置defer的js脚本会按照顺序执行。
  9. document对象触发DOMContentLoader事件,这也标志着程序执行从同步脚本阶段,转化为事件驱动阶段。
  10. 当所有的异步脚本加载完成并执行后,img等多媒体资源加载完成后,document.readyState = 'complete',window对象会触发load事件。
  11. 从此,异步响应方式处理用户输入,网络事件等。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
</body>
</html>

<script>
    console.log(document.readyState) // loading

    document.onreadystatechange = function () {
        console.log(document.readyState) // 先后打印 interactive, complete
    }
    
	// 当dom解析完成时执行
    document.addEventListener('DOMContentLoaded', function () {
        console.log('DOMContentLoaded') // 在interactive之后打印
    }, false)

    window.addEventListener('load', function () {
        console.log('load') // 在complete之后打印,最后
    })

</script>
loading 
interactive
DOMContentLoaded
complete
load

DOMContentLoaded 是比较重要的监听事件,会在dom解析完成时执行,与jquery的$(document).ready(function(){})功能一致。
而上文第10步也提到了,load事件是在所有资源加载完成后才触发。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/147699.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Live800:2023年客服团队管理有哪些思路和方法?

在数字化时代&#xff0c;客服团队成为企业与客户之间的重要桥梁。随着技术不断发展&#xff0c;客服团队管理也在不断进化。到了2023年&#xff0c;最新的客服团队管理将会有哪些思路和方法呢&#xff1f; 一、智能化客服系统 随着人工智能技术的不断发展&#xff0c;智能化客…

redis-5.0.8主从集群搭建、不重启修改配置文件

一、环境准备 192.168.5.100 redis-01 192.168.5.101 redis-02 192.168.5.102 redis-03 关闭防火墙、能够通网 二、安装redis [rootlocalhost ~]# wget http://download.redis.io/releases/redis-5.0.8.tar.gz [rootlocalhost ~]# tar xf redis-5.0.8.tar.gz -C /usr/loca…

2023.11.15 hive sql之函数标准,字符串,日期,数学函数

目录 一.函数分类标准 二.查看官方函数,与简单演示 三.3种类型函数演示 四.字符串函数 1.常见字符串函数 2.索引函数 解析函数 五.日期函数 1.获取当前时间 2.获取日期相关 3.周,季度等计算 4.时间戳 六.数学函数 一.函数分类标准 目前hive三大标准 UDF:&#xff08…

十大适合外贸企业邮箱的Gmail替代品推荐

电子邮件仍然是许多人选择的媒介&#xff0c;因为它是交换信息的最可靠和正式的方法。无论是个人还是小型企业&#xff0c;电子邮件仍然是个人和专业用途的重要通信工具。它提供了一种安全、可靠且正式的方法来交换信息和文档以及共享文件。 对于大多数人来说&#xff0c;Googl…

RT-Thread STM32F407 DMA

这里以串口的DMA方式接收为例&#xff0c;串口1进行调试&#xff0c;串口2进行DMA接收 第一步&#xff0c;进入RT-Thread Settings配置DMA 第二步&#xff0c;进入board.h&#xff0c;定义串口及DMA宏 第三步&#xff0c;回到main.c&#xff0c;配置串口及DMA模式 第四步…

uniapp开发ios上线(在win环境下使用三方)

苹果 1、win环境下无法使用苹果os编译器所以使用第三方上传工具&#xff0c;以下示例为 初雪云 &#xff08;单次收费&#xff0c;一元一次&#xff09; 初雪云&#xff08;注册p12证书&#xff09;&#xff1a;https://www.chuxueyun.com/#/pages/AppleCertificate 苹果开发者…

将ECharts图表插入到Word文档中

文章目录 在后端调用JS代码准备ECharts库生成Word文档项目地址库封装本文示例 EChartsGen_DocTemplateTool_Sample 如何通过ECharts在后台生成图片&#xff0c;然后插入到Word文档中&#xff1f; 首先要解决一个问题&#xff1a;总所周知&#xff0c;ECharts是前端的一个图表库…

websocket学习笔记【springboot+websocket聊天室demo】

文章目录 WebSocket是什么&#xff1f;为什么需要WebSocket?WebSocket和Http连接的区别WebSocket的工作原理基本交互过程&#xff1a; Java中的WebSocket支持WebSocket的优势springboot websocket themlef 一个聊天室demopom.xmlWebSocketConfigChatControllerWebController…

数字人,虚拟数字人——你看好数字人领域的发展吗?

你看好数字人领域的发展吗&#xff1f; 目录 一、虚拟人、数字人、虚拟数字人基本概念 1.1、虚拟人&#xff08;Virtual Person&#xff09; 1.2、 数字人&#xff08;Digital Human&#xff09; 1.3、虚拟数字人&#xff08;Virtual Digital Human&#xff09; 1.4、侧重…

Java魔法解密:HashMap底层机制大揭秘

文章目录 一、 源码深度解析1.1 窥探Java集合框架中的设计思想1.2 逐行解读HashMap的源代码1.2.1 类信息1.2.2 常量属性1.2.3 变量属性1.2.4 节点信息1.2.5 构造方法1.2.6 put方法1.2.6.1 putVal方法1.2.6.2 putTreeVal方法1.2.6.3 tieBreakOrder方法1.2.6.4 treeifyBin方法1.2…

菜单栏图标隐藏管理Bartender 5.0.44

Bartender是一款Mac上的菜单栏图标隐藏管理软件&#xff0c;它可以帮助用户轻松整理和管理菜单栏上的图标&#xff0c;使其更加整洁和有序。 以下是Bartender的一些主要特点和功能&#xff1a; 菜单栏图标隐藏&#xff1a;Bartender允许用户将一些不常用的菜单栏图标隐藏起来&a…

Uniapp-小程序自定义导航栏

一、项目背景 制作小程序页面时候发现原生导航栏有一定的高度是没有背景渲染的会出现这种情况 但是我们需要的是 二、原因 小程序的原生导航栏存在。一般可以使用 纯色填充顶部栏 可以直接使用navigationBarBackgroundColor完成 在style中添加 "navigationBarBackgrou…

【跨境电商独立站新手入门手册】

一直想要更新一个独立站的系列合集&#xff0c;用小白也看得懂的方式阐述怎么从0到1搭建并运营一个独立站&#xff0c;并且后续我也会录制成视频。 今天&#xff0c;它来了。 这是《跨境电商独立站新手入门手册》系列的第一篇。 你是否有过这样的经历&#xff1a;当你在网上浏…

AMEYA360分析:蔡司工业CT中的自动缺陷检测

蔡司自动缺陷检测&#xff1a;适用于您的应用领域的AI软件 蔡司自动化缺陷检测机器学习软件将人工智能应用于3D CT和2D X射线系统&#xff0c;树立了新的标杆&#xff0c;可对缺陷或异常(不规则)进行检测、定位与分类&#xff0c;同时通过读取CT扫描和X射线结果对其进行详细分析…

ACM/IEEE Fellow、欧洲科学院院士王义教授将在2023年CCF中国软件大会上作特邀报告...

2023年CCF中国软件大会&#xff08;CCF ChinaSoft 2023&#xff09;邀请王义作大会特邀报告。 特邀嘉宾 王义 ACM/IEEE Fellow、欧洲科学院院士 Wang is a chair professor at Uppsala University. He has a Ph.D. in Computer Science from Chalmers. His interests are mainl…

LLMs可以遵循简单的规则吗?

深度学习自然语言处理 原创作者&#xff1a;wkk 由于大型语言模型在现实世界中的责任越来越大&#xff0c;因此如何以可靠的方式指定和约束这些系统的行为很重要。一些开发人员希望为模型设置显式规则&#xff0c;例如“不生成滥用内容”&#xff0c;但这种方式可能会被特殊技术…

Mysql数据备份 —xtrabackup

一 备份介绍 ### 优点&#xff1a; 1. **在线备份&#xff1a;** XtraBackup 支持在线备份&#xff0c;这意味着你可以在 MySQL 服务器运行的同时进行备份&#xff0c;而无需停止数据库服务。这对于生产环境中的数据库是非常关键的&#xff0c;因为可以最小化停机时间。 2. **…

【工具流】WSL2安装

一些废话 最近看到了PKU出品的cs自学指南&#xff0c;想要跟着里面的自学路径学国外的优质课程&#xff0c;无奈大多数pre教程里面都是直接Linux环境下的操作&#xff0c;并且我在CSwiki看到了那个熟悉的上学期学了一点的missing-semester课。 上学期自学missing-semester的时候…

Git 修改历史 commit message

一. 修改最新的 commit log 修改最近一次commit message&#xff0c; 直接使用命令 git commit --amend 就可以完成修改二. 修改历史 commit log 查看日志(按 q 退出) git log --oneline # 查看5步的log。 git log --oneline -5选择要修改的commit 信息 # 要修改的 commit log…

实际使用Elasticdump工具对Elasticsearch集群进行数据备份和数据还原

文/朱季谦 目录一、Elasticdump工具介绍二、Elasticdump工具安装三、Elasticdump工具使用 最近在开发当中做了一些涉及到Elasticsearch映射结构及数据导出导入的工作&#xff0c;怕以后会把这过程忘记&#xff0c;可谓好记性不如烂笔头&#xff0c;故而记录成一篇博文。 玩El…