代码输出结果
async function async1() {
console.log("async1 start");
await async2();
console.log("async1 end");
}
async function async2() {
console.log("async2");
}
async1();
console.log('start')
复制代码
输出结果如下:
async1 start
async2
start
async1 end
复制代码
代码的执行过程如下:
- 首先执行函数中的同步代码
async1 start,之后遇到了await,它会阻塞async1后面代码的执行,因此会先去执行async2中的同步代码async2,然后跳出async1; - 跳出
async1函数后,执行同步代码start; - 在一轮宏任务全部执行完之后,再来执行
await后面的内容async1 end。
这里可以理解为await后面的语句相当于放到了new Promise中,下一行及之后的语句相当于放在Promise.then中。
实现数组原型方法
forEach
语法:
arr.forEach(callback(currentValue [, index [, array]])[, thisArg])参数:
callback:为数组中每个元素执行的函数,该函数接受1-3个参数currentValue: 数组中正在处理的当前元素index(可选): 数组中正在处理的当前元素的索引array(可选):forEach()方法正在操作的数组thisArg(可选): 当执行回调函数callback时,用作this的值。返回值:
undefined
Array.prototype.forEach1 = function(callback, thisArg) {
if(this == null) {
throw new TypeError('this is null or not defined');
}
if(typeof callback !== "function") {
throw new TypeError(callback + 'is not a function');
}
// 创建一个新的 Object 对象。该对象将会包裹(wrapper)传入的参数 this(当前数组)。
const O = Object(this);
// O.length >>> 0 无符号右移 0 位
// 意义:为了保证转换后的值为正整数。
// 其实底层做了 2 层转换,第一是非 number 转成 number 类型,第二是将 number 转成 Uint32 类型
const len = O.length >>> 0;
let k = 0;
while(k < len) {
if(k in O) {
callback.call(thisArg, O[k], k, O);
}
k++;
}
}
复制代码
map
语法:
arr.map(callback(currentValue [, index [, array]])[, thisArg])参数:与
forEach()方法一样返回值:一个由原数组每个元素执行回调函数的结果组成的新数组。
Array.prototype.map1 = function(callback, thisArg) {
if(this == null) {
throw new TypeError('this is null or not defined');
}
if(typeof callback !== "function") {
throw new TypeError(callback + 'is not a function');
}
const O = Object(this);
const len = O.length >>> 0;
let newArr = []; // 返回的新数组
let k

这篇博客探讨了前端面试中常见的问题,包括代码输出逻辑、数组的forEach、map、filter、some、reduce方法的实现与应用,z-index属性的生效条件,以及深度克隆、CSS单位px、em、rem的差异和使用场景。此外,还讲解了阻塞渲染的因素、闭包的概念和作用,Virtual DOM的优势,以及如何防御XSS攻击。博客还涵盖了僵尸进程和孤儿进程、数组去重策略、函数防抖实现,死锁的原因与解决方法,以及柯里化原理。最后,讨论了浏览器如何管理和加载HTML5离线储存资源。
最低0.47元/天 解锁文章
426

被折叠的 条评论
为什么被折叠?



