# 第 51 - 60 题
# 51、Vue 的响应式原理中 Object.defineProperty 有什么缺陷?
为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty?
原因:
- object.defineProperty无法感知数组下标变化,导致数组下边变化,无法实时响应。所以 重写了8中方法,除此之外其他方法
- 只能劫持对象的属性,需要对每个对象的每个属性进行遍历。递归 + 遍历。
基于以上两点,采用proxy代替
- 可以劫持整个对象,并返回一个新对象
- 有13种劫持操作
# 52、怎么让一个 div 水平垂直居中
<style>
/*flex*/
.wrapper {
display: flex;
align-items: center;
justify-content: center;
}
/*position*/
.wrapper {
position: relative;
}
.content {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
/*gird*/
.wrapper {
display: grid;
}
.content {
align-self: center;
justify-self: center;
}
</style>
<div class="wrapper">
<div class="content"></div>
</div>
# 53、输出以下代码的执行结果并解释为什么
var a = { n: 1 };
var b = a;
a.x = a = { n: 2 };
console.log(a.x)
console.log(b.x)
undefind、{n:2}
a.x = a = {n: 2};
/*这一行比较复杂。先获取等号左侧的a.x,但a.x并不存在, 于是JS为(堆内存中的)对象创建一个新成员x,这个成员的初始值为undefined,
(这也是为什么直接引用一个未定义的变量会报错,但是直接引用一个对象的不存在的成员时, 会返回undefined.)
创建完成后,目标指针已经指向了这个新成员x,并会先挂起,单等等号右侧的内容有结果了, 便完成赋值。
接着执行赋值语句的右侧,发现a={n:2}是个简单的赋值操作,于是a的新值等于了{n:2}。
这里特别注意,这个a已经不是开头的那个a,而是一个全新的a,这个新a指针已经不是指向原来的值的那个堆内存, 而是分配了一个新的堆内存。但是原来旧的堆内存因为还有b在占用,所以并未被回收。
然后,将这个新的对象a的堆内存指针,赋值给了刚才挂起的新成员x,
此时,对象成员x便等于了新的对象a。
所以,现在b={n:1,x:{n:2}};a={n:2};a===b.x(true,注意对象的相等, 不是值的相等,而是引用的相等,也就是说,相等表示指针是指向同一个堆内存。)
# 54、冒泡排序如何实现,时间复杂度是多少, 还可以如何改进?
function bubbleSort(arr) {
const len = arr.length;
for (let i = 0; i < len; i++) {
// 区别在这里,我们加了一个标志位
let flag = false
// 改进
for (let j = 0; j < len - 1 - i; j++) {
if (arr[j] < arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
flag = true;
}
}
// 最好的情况,复杂度为O(n) 默认O(n^2)
if (flag === false) return arr;
}
return arr;
}
# 55、某公司 1 到 12 月份的销售额存在一个对象里面
如下:{1:222, 2:123, 5:888},请把数据处理为如下结构:
[222, 123, null, null, 888, null, null, null, null, null, null, null]。
let obj = { 1: 222, 2: 123, 5: 888 };
const result = Array.from({ length: 12 }).map((_, index) => obj[index + 1] || null);
console.log(result)
# 56、要求设计 LazyMan 类,实现以下功能。
LazyMan('Tony');
// Hi I am Tony
LazyMan('Tony').sleep(10).eat('lunch');
// Hi I am Tony
// 等待了10秒...
// I am eating lunch
LazyMan('Tony').eat('lunch').sleep(10).eat('dinner');
// Hi I am Tony
// I am eating lunch
// 等待了10秒...
// I am eating diner
LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food');
// Hi I am Tony
// 等待了5秒...
// I am eating lunch
// I am eating dinner
// 等待了10秒...
// I am eating junk food
class LazyManClass {
constructor(name) {
this.queue = [];
console.log(`Hi I am ${name}`)
setTimeout(() => {
this.next();
}, 0)
}
eat(name) {
const fn = () => {
console.log(`I am eating ${name}`);
this.next();
}
this.queue.push(fn);
return this;
}
sleepFirst(time) {
const fn = setTimeout(() => {
console.log(`等待了${time}秒...`)
this.next()
}, time);
this.queue.unshift(fn);
return this;
}
sleep(time) {
const fn = setTimeout(() => {
console.log(`等待了${time}秒...`)
this.next()
}, time)
this.queue.push(fn);
return this;
}
next() {
const fn = this.queue.shift();
fn && fn();
}
}
function LazyMan(name) {
return new LazyManClass(name);
}
# 57、分析比较 opacity: 0、visibility: hidden、display: none 优劣和适用场景。
# 结构:
- display:none: 会让元素完全从渲染树中消失,渲染的时候不占据任何空间, 不能点击,
- visibility: hidden:不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,不能点击
- opacity: 0: 不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,可以点击
# 继承:
- display: none和opacity: 0:是非继承属性,子孙节点消失由于元素从渲染树消失造成,通过修改子孙节点属性无法显示。
- visibility: hidden:是继承属性,子孙节点消失由于继承了hidden,通过设置visibility: visible;可以让子孙节点显式。
# 性能:
- display:none : 修改元素会造成文档回流,读屏器不会读取display: none元素内容,性能消耗较大
- visibility:hidden: 动态改变此属性时会引起重绘,性能较高;
- opacity: 0 : 提升为合成层,不会触发重绘,性能较高;
联系:它们都能让元素不可见
# 58:箭头函数与普通函数(function)的区别是什么?构造函数(function)可以使用 new 生成实例,那么箭头函数可以吗?为什么?
最大区别是箭头函数没有自身this;继承当前执行栈上层this执行。
# 59、给定两个数组,写一个方法来计算它们的交集。
例如:给定 nums1 = [1, 2, 2, 1],nums2 = [2, 2],返回 [2, 2]。
function intersection(nums1, num2) {
const map = new Map();
const result = [];
for (let i = 0; i < nums1.length; i++) {
if (map.has(nums1[i])) {
map.set(nums1[i], map.get(nums1[i] + 1));
} else {
map.set(nums1[i], 1);
}
}
for (let j = 0; j < num2.length; j++) {
if (map.has(num2[j]) > 0) {
result.push(num2[j]);
map.set(num2[j], map.get(num2[j]--));
}
}
return result;
}
# 60、已知如下代码,如何修改才能让图片宽度为 300px ?注意下面代码不可修改。
<img src="1.jpg" style="width:480px!important;”>
max-width: 300px;
box-sizing: border-box; padding: 0 90px
;transform: scale(0.625, 0)
; 图片dom大小不变zoom: 0.625
;图片dom大小改变。区别上方;scale;