面試十題(4)
阿新 • • 發佈:2021-09-15
1. 介紹下 BFC 及其應用。
BFC 就是塊級格式上下文,是頁面盒模型佈局中的一種 CSS 渲染模式,相當於一個獨立的容器,裡面的元素和外部的元素相互不影響。
- 建立 BFC 的方式有:
- html 根元素
- float 浮動
- 絕對定位
- overflow 不為 visiable
- display 為表格佈局或者彈性佈局
- BFC 主要的作用是:
- 清除浮動
- 防止同一 BFC 容器中的相鄰元素間的外邊距重疊問題
2. 在 Vue 中,子元件為何不可以修改父元件傳遞的 Prop?如果修改了,Vue 是如何監控到屬性的修改並給出警告的。
-
因為vue設計是單向資料流,資料的流動方向只能是自上往下的方向;但是反過來則不行。這樣會防止從子元件意外變更父級元件的狀態,從而導致你的應用的資料流向難以理解。額外的,每次父級元件發生變更時,子元件中所有的 prop 都將會重新整理為最新的值。這意味著你不應該在一個子元件內部改變 prop。如果你這樣做了,Vue 會在瀏覽器的控制檯中發出警告。
-
在initProps的時候,在defineReactive時通過判斷是否在開發環境,如果是開發環境,會在觸發set的時候判斷是否此key是否處於updatingChildren中被修改,如果不是,說明此修改來自子元件,觸發warning提示。
-
需要特別注意的是,當你從子元件修改的prop屬於基礎型別時會觸發提示。 這種情況下,你是無法修改父元件的資料來源的, 因為基礎型別賦值時是值拷貝。你直接將另一個非基礎型別(Object, array)賦值到此key時也會觸發提示(但實際上不會影響父元件的資料來源), 當你修改object的屬性時不會觸發提示,並且會修改父元件資料來源的資料。
3. js 實現sleep函式
- es6 非同步處理
// promise
const sleep = time => {
return new Promise(resolve => setTimeout(resolve, time))
}
sleep(1000).then(() => {
console.log('業務程式碼')
})
// async/await
const sleepPromise = (time) => {
return new Promise((resolve, reject) => {
setTimeout(resolve, time);
})
}
async function sleep (time) {
await sleepPromise(time);
console.log('業務程式碼')
}
sleep(5000)
// generator
const sleepPromise = (time) => {
return new Promise((resolve, reject) => {
setTimeout(resolve, time);
})
}
function* sleep(time) {
yield sleepPromise(time);
}
sleep(5000).next().value.then(()=>{
console.log('業務程式碼')
})
- 偽死迴圈
function sleep(delay) {
var start = (new Date()).getTime();
while ((new Date()).getTime() - start < delay) {
continue;
}
}
console.log('1')
sleep(5000)
console.log('2')
- 定時器+回撥函式
function sleep(time, callback) {
setTimeout(callback, time)
}
sleep(time, () => {
console.log('業務程式碼')
})
4. 雙向繫結和 vuex 是否衝突
5. 為什麼通常在傳送資料埋點請求的時候使用的是 1x1 畫素的透明 gif 圖片?
- 能夠完成整個 HTTP 請求+響應(儘管不需要響應內容)
- 觸發 GET 請求之後不需要獲取和處理資料、伺服器也不需要傳送資料
- 跨域友好
- 執行過程無阻塞,只要 new Image 物件就好了,一般情況下也不需要 append 到 DOM 中,通過它的 onerror 和 onload 事件來檢測傳送狀態。
- 相比 XMLHttpRequest 物件傳送 GET 請求,效能上更好
- GIF 的最低合法體積最小(最小的 BMP 檔案需要 74 個位元組,PNG 需要 67 個位元組,而合法的 GIF,只需要 43 個位元組)
6. 實現 (5).add(3).minus(2) 功能。
- 方法一
Number.prototype.add = function (number) {
if (typeof number !== 'number') {
throw new Error('請輸入數字~');
}
return this.valueOf() + number;
};
Number.prototype.minus = function (number) {
if (typeof number !== 'number') {
throw new Error('請輸入數字~');
}
return this.valueOf() - number;
};
console.log((5).add(3).minus(2));
- 方法二
// 這裡的~寫成加號+ 減號- 都可以。但必須是一元表示式
// 匿名函式前面加~一元運算子就會轉變成函式表示式,函式表示式後面加()
~ function(){
function add(n){
return this + n
}
function minus(n){
return this - n
}
Number.prototype.add = add
Number.prototype.minus = minus
}()
console.log((5).add(3).minus(2))
- 方法三
function addmin(){
function add(n){
return this + n
}
function minus(n){
return this - n
}
Number.prototype.add = add
Number.prototype.minus = minus
}
addmin()
console.log((5).add(3).minus(2))
7. Vue 的響應式原理中 Object.defineProperty 有什 麼缺陷? 為什麼在 Vue3.0 採用了 Proxy,拋棄了 Object.defineProperty?
- Object.defineProperty 無法監控到陣列下標的變化,導致通過陣列下標新增元素,不能實時響應;
- Object.defineProperty 只能劫持物件的屬性,從而需要對每個物件,每個屬性進行遍歷,如果,屬性值是物件,還需要深度遍歷。Proxy 可以劫持整個物件,並返回一個新的物件。
- Proxy 不僅可以代理物件,還可以代理陣列。還可以代理動態增加的屬性。
補充回答:Object.defineProperty 本身有一定的監控到陣列下標變化的能力,但是在 Vue 中,從效能/體驗的價效比考慮,尤大大就棄用了這個特性。
8. div 水平垂直居中
- 方法一
// 父元素
box {
display: flex;
justify-content: center;
align-items: center;
}
- 方法二
// 絕對定位
.div {
width: 200px;
height: 200px;
background: green;
position:absolute;
left:0;
top: 0;
bottom: 0;
right: 0;
margin: auto;
}
- 方法三
// margin 負間距
div {
width:200px;
height: 200px;
background:green;
position: absolute;
left:50%;
top:50%;
margin-left:-100px;
margin-top:-100px;
}
- 方法四
// transform 變形
div {
width: 200px;
height: 200px;
background: green;
position:absolute;
left:50%; /* 定位父級的50% */
top:50%;
transform: translate(-50%,-50%); /*自己的50% */
}
9. 下面程式碼執行結果及原因
var a = {n:1}
var b = a;
a.x = a = {n:2}
console.log(a.x) // undefined
console.log(b.x) // {n: 2}
考察運算子的優先順序,雖然賦值是從右往左,但是.的運算子比=的優先順序高。所以先執行a.x = {n: 2}再執行a = {n: 2}
10. 氣泡排序如何實現,時間複雜度是多少, 還可以如何改進?
- 氣泡排序
var a = [11,2,55,123,88,3,67];
function bubbleSort(arr) {
console.time('time')
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]){
let temp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = temp
}
}
}
console.timeEnd('time')
console.log(arr)
return arr
}
bubbleSort(a)
- 改進氣泡排序
var a = [11,2,55,123,88,3,67];
function bubbleSort1(arr) {
console.time('time')
var i = arr.length - 1;
while(i > 0) {
let pos = 0;
for (var j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
pos = j
let temp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = temp
}
}
i = pos
}
console.timeEnd('time')
console.log(arr)
return arr
}
bubbleSort1(a)