152. 面试官:在做文件断点续传时,如何判断2次选择的是同一个文件?

152期

1. 在做文件断点续传时,如何判断2次选择的是同一个文件?
2. 浏览器为什么有跨域限制,目的是什么?
3. 为什么推荐使用transform: translateX(10px);而不是left:10px;来实现动画?

上面问题的答案会在第二天的公众号(程序员每日三问)推文中公布

也可以小程序刷题,已收录500+面试题及答案aa50aed20af259afac4b5e3770df0c86.jpeg

151期问题及答案

1. 说说Pomise.all和Promise.race的区别并举例?

Promise.allPromise.racePromise 对象的两个静态方法,它们用于处理多个 Promise 实例的不同情况。

Promise.all

Promise.all 是一个用于将多个 Promise 实例包装成一个新的 Promise 实例的方法。该方法接受一个可迭代对象(例如数组),这个可迭代对象里面的成员都是 Promise 实例。它的工作原理是:

  • 当这个可迭代对象里的所有 Promise 实例全部进入 fulfilled 状态时,Promise.all 返回的新的 Promise 实例才会变为 fulfilled 状态,它的结果是一个数组,包含了所有 Promise 实例的结果。

  • 如果这个可迭代对象中有一个 Promise 实例进入 rejected 状态,Promise.all 返回的新 Promise 实例将立即变为 rejected 状态,它的结果是那个第一个变为 rejected 状态 Promise 实例的错误。

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values); // 输出 [3, 42, "foo"]
});

在这个例子中,Promise.all 等待三个 Promise 实例完成,并且输出它们的结果。

Promise.race

Promise.race 也接受一个可迭代对象里面全是 Promise 实例的数组。与 Promise.all 方法不同的是,Promise.race 将返回这个可迭代对象中第一个变为 fulfilledrejected 状态的 Promise 实例的结果。换句话说:

  • 如果一个 Promise 实例首先变为 fulfilled 状态,Promise.race 返回的新的 Promise 实例也将变为 fulfilled 状态。

  • 如果一个 Promise 实例首先变为 rejected 状态,Promise.race 返回的新的 Promise 实例也将变为 rejected 状态。

const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(reject, 100, 'two');
});

Promise.race([promise1, promise2]).then((value) => {
  console.log(value); // 这一行不会被执行
}).catch((reason) => {
  console.log(reason); // 输出 "two",因为 promise2 最先被 reject
});

在这个例子中,promise2promise1 更快地变成 rejected 状态,所以 Promise.race 返回的 Promise 实例也变成 rejected 状态,并输出 two

总结一下,Promise.all 需要等待所有的 Promise 实例都完成,返回的结果是所有 Promise 的结果组成的数组,而 Promise.race 只关心第一个被 settled(无论是 fulfilled 还是 rejected)的 Promise 实例,并且返回这个 Promise 实例的结果。

2. js对象中的可枚举是什么意思,如何控制它的可枚举性?

在 JavaScript 中,对象的属性分为可枚举(enumerable)和不可枚举(non-enumerable)。可枚举属性指的是该属性可以出现在对象的属性枚举中,例如使用 for...in 循环或者 Object.keys() 方法时,可以遍历到这些属性。

控制属性的可枚举性

在 JavaScript 中,可以通过以下方法来控制和查看某个对象属性的可枚举性:

  1. 使用 Object.defineProperty() 方法定义或修改属性的可枚举性

    通过 Object.defineProperty() 方法,你可以直接定义新属性或者修改现有属性的特性(包括可枚举性):

    let obj = {};
    
    Object.defineProperty(obj, 'a', {
      value: 1,
      enumerable: true // 属性 "a" 是可枚举的
    });
    
    Object.defineProperty(obj, 'b', {
      value: 2,
      enumerable: false // 属性 "b" 是不可枚举的
    });
    
    for (let key in obj) {
      console.log(key); // 输出:"a"
    }
    
    console.log(Object.keys(obj)); // 输出:["a"]

    在这个示例中,属性 "a" 是可枚举的,因此它会出现在 for...in 循环和 Object.keys() 的输出中。而属性 "b" 是不可枚举的,所以它不会被输出。

  2. 使用 Object.getOwnPropertyDescriptor() 方法查看属性的可枚举性

    想要知道某个属性的可枚举性,可以使用 Object.getOwnPropertyDescriptor() 方法:

    let propertyDescriptor = Object.getOwnPropertyDescriptor(obj, 'a');
    console.log(propertyDescriptor.enumerable); // 输出:true
    
    propertyDescriptor = Object.getOwnPropertyDescriptor(obj, 'b');
    console.log(propertyDescriptor.enumerable); // 输出:false

默认的属性可枚举性

在通过普通的方式创建对象时(即使用对象字面量),对象属性的默认特性是可枚举的:

let obj = {
  x: 10
};

console.log(Object.keys(obj)); // 输出:["x"]

但是,通过对象构造函数定义的内置属性通常是不可枚举的。例如,原型链中的方法 obj.toString 或者数组的 length 属性都是不可枚举的。

总结来说,JS 对象属性的可枚举性控制其在枚举对象属性时是否会出现。更改属性的可枚举性大多数时候是通过 Object.defineProperty 方法实现的。这在控制对象属性在 for...inObject.keys() 或者 JSON.stringify 方法中的表现时很有用。

3. 常见的左右布局有哪些实现方式,请举例说明?

左右布局是Web开发中常见的页面布局模式,意在将页面分为左右两个区域,通常用于侧边栏和主要内容区的布局设计。以下是几种常见的实现方法,每种方法都有其自身的使用场景和优缺点:

1. 浮动(Float)

浮动布局是早期最常用的左右布局实现方式之一。

<div class="container">
  <div class="sidebar" style="float: left; width: 200px;">侧边栏</div>
  <div class="content" style="margin-left: 200px;">主要内容</div>
</div>

浮动可能需要清除浮动(clearfix)以防止高度塌陷的问题。

2. 定位(Positioning)

绝对定位可以用来创建左右布局,将侧边栏或内容区设置为固定宽度。

<div class="container" style="position: relative;">
  <div class="sidebar" style="position: absolute; left: 0; width: 200px; top: 0;">侧边栏</div>
  <div class="content" style="margin-left: 200px;">主要内容</div>
</div>

这种方法可能会导致重叠,特别是当内容高度超过视窗高度时。

3. 内联块(Inline-Block)

使用 display: inline-block; 也可以实现左右布局,要确保两个内联块元素合在一起的宽度不超过其容器宽度。

<div class="container">
  <div class="sidebar" style="display: inline-block; width: 200px; vertical-align: top;">侧边栏</div>
  <div class="content" style="display: inline-block; vertical-align: top;">主要内容</div>
</div>

该方法可能需要解决内联块元素之间的空白间隔问题。

4. Flexbox(弹性盒布局)

Flexbox 提供了更灵活的布局选项。

<div class="container" style="display: flex;">
  <div class="sidebar" style="flex: 0 0 200px;">侧边栏</div>
  <div class="content" style="flex-grow: 1;">主要内容</div>
</div>

在这个例子中,侧边栏有一个固定的宽度,而主要内容区则占据剩余的空间。

5. CSS Grid(网格布局)

CSS Grid 是一个强大的布局系统,可以创建复杂的网格布局。

<div class="container" style="display: grid; grid-template-columns: 200px auto;">
  <div class="sidebar">侧边栏</div>
  <div class="content">主要内容</div>
</div>

这里,我们定义了两列,其中 200px 为侧边栏固定的宽度,auto 表示主要内容区占用剩余的空间。

6. 表格布局(Table)

虽然不建议用于页面布局,但表格布局也可以实现左右布局。

<div class="container" style="display: table; width: 100%;">
  <div class="sidebar" style="display: table-cell; width: 200px;">侧边栏</div>
  <div class="content" style="display: table-cell;">主要内容</div>
</div>

侧边栏设置为表格单元格并分配固定宽度,而主要内容区随后也是一个表格单元。

总结

以上所示的方法各有特点,不同的实现选择取决于具体的布局需求和所支持的浏览器。随着前端技术的发展,现代布局通常更推荐使用 Flexbox 和 CSS Grid,因为它们提供了更高的灵活性、更简洁的代码,且易于维护。

我要提问

如果你遇到有趣的面试题,或者有想知道的前端面试题,可以在下面的小程序提问,收到问题后会在第一时间为你解答。

我要出题

学习不打烊,充电加油只为遇到更好的自己,每天早上9点纯手工发布面试题,每天坚持花20分钟来学习与思考,在千变万化,类库层出不穷的今天,不要等到找工作时才狂刷题,提倡每日学习。

  • 18
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值