1.對象方法
2.新建對象時,new操作符干了什么?var a = new A;
3.bem,bfc
4.永久性重定向(301)和臨時性重定向(302)對 SEO 有什么影響?
5.一個div,左邊固定,右邊、自適應(yīng),有幾種方法?
6.清除浮動
7.div水平垂直居中
8.VUE雙向綁定原理,對MVVM的理解
9.diff算法時間復(fù)雜度及原理
10.webpack打包時如何優(yōu)化減少打包時間?webpack loader和plugin有什么區(qū)別?
11.尾遞歸優(yōu)化,尾調(diào)用優(yōu)化?
12.遇到過哪些兼容性問題?
13.深度優(yōu)先遍歷
14.嵌套數(shù)組展開
15.跨域
16.文本溢出顯示省略號,一行或多行的情況分別處理
17.Git命令,從指定分支新建分支。
18.找出數(shù)組中重復(fù)次數(shù)最多的元素
19.Linux命令,打印執(zhí)行過的命令
20.proxy
21.將數(shù)字反轉(zhuǎn),63->36
1.對象方法
答:
- Object.defineProperty() 修改對象屬性的默認(rèn)特性,創(chuàng)建新屬性
- Object.defineProperties() 多個
- Object.getOwnPropertyDescriptor() 取得給定屬性的描述符
- instanseOf()檢測對象類型
- a.isPrototypeOf(b) a是否是b的原型
- Object.getPrototypeOf(a) 找到a的原型
- hasOwnProperty()返回實例屬性
- in 操作符 存在原型鏈上的屬性
- hasPrototypeProperty() 返回原型屬性
- Object.keys()返回實例上的可枚舉屬性
- Object.getOwnPropertyNames()返回實例上的所有屬性,無論是否可枚舉
2.新建對象時,new操作符干了什么?var a = new A;
答:這種方式調(diào)用構(gòu)造函數(shù),實際經(jīng)歷了以下4個步驟:
(1)創(chuàng)建一個新對象;
(2)將構(gòu)造函數(shù)的作用域賦給新對象;(因此this就指向了新對象)
(3)執(zhí)行構(gòu)造函數(shù)中的代碼;(為這個新對象添加屬性)
(4)返回新對象。
- bem,bfc
瓜子二手車、微店
答:原文鏈接:https://juejin.im/post/5909db2fda2f60005d2093db
BFC(Block Formatting Context)翻譯為塊級格式化上下文,它其實就是一個css布局的概念,是一個上下文環(huán)境, 是一塊區(qū)域,是一個隔離的獨立容器,容器里的子元素不會影響到外面的元素, 反之亦然。
formatting context 是一個決定如何渲染的容器。
BFC布局規(guī)則:
(1)內(nèi)部的box會在垂直方向一個接一個的放置。
(2)box之間垂直間距由margin決定,屬于同一個BFC的兩個相鄰的box的margin會重疊。
(3)每個元素的marginbox的左邊與包含塊borderbox的左邊相接觸,即使存在浮動也如此。???
(4)BFC的區(qū)域不會與floatbox重疊。
(5)BFC就是頁面上的一個獨立區(qū)域,區(qū)域里面的子元素布局不會影響到外面的布局排列,反之亦然。
(6)計算BFC高度時,浮動元素也參與計算。
(7)位于不同BFC下的元素不會發(fā)生margin重疊。BFC有哪些用途?
(1)自適應(yīng)兩欄布局
(2)可以阻止元素被浮動元素覆蓋,把不浮動的元素添加overflow:hidden ,觸發(fā)該元素的bfc,讓自己免受外界影響。
(3)可以清除內(nèi)部浮動(清除浮動的原理是兩個div都位于同一個浮動的BFC區(qū)域之中。)
(4)分屬于不同的BFC 可以阻止margin重疊。
(5)解決浮動問題。給父元素加overflow:hidden觸發(fā)bfc,形成一個獨立的渲染區(qū)域,所以內(nèi)部的元素不會影響外面的布局,bfc把浮動子元素的高度算作自己的高度處理溢出,所以外界不會受到影響。觸發(fā)BFC有哪些方式?
(1)根元素HTML
(2)float不為none
(3)display為inline-block或table-cell
(4)overflow不為visible
(5)position不為static
(6)flex-boxes
概括來說就是脫離了文檔流的元素-
文本環(huán)繞?
image.png
image.png
div會被float覆蓋而文本不會,這是因為float當(dāng)初設(shè)計的時候就是為了讓文本在浮動對象周圍。
BEM( Block,Element和Modifier的縮寫)是一個高可用的,強(qiáng)大的,而且簡單的命名規(guī)范,它可以使得你的前端代碼更加易讀和理解,容易與他人協(xié)作,容易擴(kuò)展,更加強(qiáng)壯和明確,關(guān)鍵是更加嚴(yán)謹(jǐn)
- 永久性重定向(301)和臨時性重定向(302)對 SEO 有什么影響?
github 124
答:從SEO角度出發(fā),301優(yōu)于302。
- 301:(Permanently Moved),從搜索引擎優(yōu)化角度來講, 301是轉(zhuǎn)移網(wǎng)址最好的辦法,因為當(dāng)網(wǎng)站的域名改變后,搜索引擎只對新網(wǎng)址進(jìn)行搜索,舊網(wǎng)址下的所有外部鏈接全部轉(zhuǎn)移到新網(wǎng)址下, 舊網(wǎng)址排名清零作廢,從而不會讓網(wǎng)站的排名受到影響。另外,使用301命令讓多個域名指向網(wǎng)站主域時,也不會對網(wǎng)站的排名產(chǎn)生負(fù)面影響。
- 302:(Temporarily Moved ),使用302重定向時, 絕大部分瀏覽器會把鏈接成績向多個域名分?jǐn)?,因此就會削弱網(wǎng)站主站的鏈接總量,作為網(wǎng)站排名的關(guān)鍵因素之一的外鏈數(shù)量受到影響,網(wǎng)站排名自然會降低。目前為止, 只有谷歌對302的這個行為進(jìn)行了優(yōu)化,當(dāng)其他域名指向主域時,會把其他域名的鏈接成績計入主域。
5.一個div,左邊固定,右邊、自適應(yīng),有幾種方法?
博彥科技
bfc、左邊position:absolute,右邊margin-left、flex、計算屬性、table
(1)bfc方法(最優(yōu),左邊菜單拖拽的情況下,可以監(jiān)聽左邊元素的寬度,右邊什么值都不用改)
<div class="aside"></div>
<div class="text">
<div class="main">aaaaa</div>
</div>
.aside {
width: 100px;
height: 150px;
float: left;
background: #f66;
}
.main {
height: 200px;
overflow: hidden;
background: #fcc;
}
.text {
width: 100%;
}
注意:是右邊部分的父元素寬度100%,讓main自己形成一個bfc,bfc的區(qū)域不會與float-box重疊。

(2)左邊position:absolute,右邊margin-left,這個方式和讓左邊f(xié)loat-left同理。
<div class="parent">
<div class="l-child">左邊固定1 左邊固定2 左邊固定3</div>
<div class="r-child">右邊自適應(yīng)1 右邊自適應(yīng)2 右邊自適應(yīng)3</div>
</div>
.parent {
display: relative;
background: #ddd
}
.l-child {
position: absolute;
width: 100px;
background: #bbb
}
.r-child {
margin-left: 100px;
background: #999
}

(3)flex
body{
display: flex;
}
.right{
flex:1
}
(4)table布局
body{
display: table;
width:100%;
}
.left{
display: table-cell;
}
.right{
display: table-cell;
}
6.清除浮動
大搜車、微店、
https://juejin.im/post/59e7190bf265da4307025d91
答:clear、父元素前加空標(biāo)簽做clear、在parent上加一個偽類,讓這個偽類清除浮動、浮動元素的父元素增加overflow不為visible的屬性(BFC)。
(1)在被float影響的元素上添加clear:both;
如下圖,浮動元素導(dǎo)致text元素和下面的other被遮擋。父元素高度撐不開。

解決辦法:

不過這種辦法也有漏洞,假如浮動元素在text后面,父元素高度依然撐不開,other依然會被影響。
(2)父元素結(jié)束標(biāo)簽之前插入清除浮動的塊級元素
原理同上。

(3)在parent上加一個偽元素,讓這個偽元素清除浮動,原理和上面兩種相同。

(4)浮動元素的父元素增加overflow不為visible的屬性,原理是,這樣會觸發(fā)BFC,而BFC高度包含浮動元素。

7.div水平垂直居中
作業(yè)幫、大搜車、
答:
- 未知父元素,未知子元素寬高
(1) flex
.parent {
display: flex;
justify-content: center;
align-items: center;
}
(2)table cell
子元素設(shè)置為inline或inline-block時,父元素display:table-cell
.parent {
border: 1px solid black;
display: table-cell;
width: 500px;
height: 500px;
vertical-align: middle;
text-align: center;
}
.child {
width: 100px;
height: 100px;
border: 1px solid red;
display: inline-block;
}
(3)絕對定位+子元素transform:translate(-50%,-50%);
.parent {
border: 1px solid black;
width: 500px;
height: 500px;
position: relative;
}
.child {
width: 100px;
height: 100px;
border: 1px solid red;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
- 已知子元素寬高,未知父元素寬高
(1)子元素絕對定位,top和left都設(shè)為50%,然后margin-top和margin-left設(shè)為負(fù)數(shù)自身的一半。
.parent {
width: 500px;
height: 500px;
border: 1px solid black;
position: relative;
}
.child {
height: 100px;
width: 100px;
border: 1px solid red;
position: absolute;
top: 50%;
left: 50%;
margin: -50px 0 0 -50px;
}
(2)子元素絕對定位,top,bottom,right,left值均為0,margin設(shè)為auto。
.parent {
border: 1px solid black;
position: relative;
}
.child {
width: 100px;
height: 100px;
border: 1px solid red;
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
margin: auto;
}
8.VUE雙向綁定原理,對MVVM的理解
酷家樂,博彥科技
答:VUE雙向綁定是通過Object.defineProperty的數(shù)據(jù)劫持能力,結(jié)合發(fā)布者訂閱者模式實現(xiàn)的。
vue中的data實際上是一個帶有訪問器屬性(getter和setter)的對象。
什么是訪問器屬性?
JS對象有兩種屬性:數(shù)據(jù)屬性和訪問器屬性,訪問器屬性不能直接定義,必須通過Object.defineProperty()來定義,它包含一對getter,setter函數(shù),在讀取訪問器屬性時,會調(diào)用getter,在寫入訪問器屬性時,會調(diào)用setter 并傳入新值。setter這個函數(shù)負(fù)責(zé)如何處理數(shù)據(jù)。
VUE 就是通過這個Object.defineProperty來實現(xiàn)數(shù)據(jù)劫持的。
VUE 的雙向綁定包括兩個方面,view更新data,data更新view。
view更新data比較簡單,通過事件監(jiān)聽即可,比如input標(biāo)簽綁定input事件。
比較困難的是data更新view。
這里面有兩個點:
1.如何知道數(shù)據(jù)變了?
2.數(shù)據(jù)變了如何更新DOM?
對以上兩點做出一些解答:
1.如何知道數(shù)據(jù)變了?
其實上面已經(jīng)給出答案了,就是通過Object.defineProperty()對屬性設(shè)置一個set函數(shù),數(shù)據(jù)改變時就會觸發(fā)這個函數(shù),我們將一些更新view的方法放在set函數(shù)的邏輯里,就可以實現(xiàn)data更新view了。

實現(xiàn)過程
(1)實現(xiàn)數(shù)據(jù)的雙向綁定,首先要對數(shù)據(jù)進(jìn)行劫持監(jiān)聽,所以第一步需要設(shè)置一個監(jiān)聽器Observer,用來監(jiān)聽所有屬性。
(2)如果屬性發(fā)生變化了,就要告訴訂閱者watcher看是否需要更新。
(3)因為訂閱者watcher有很多個,所以需要一個消息訂閱器Dep來專門收集這些訂閱者,在監(jiān)聽器Observer和訂閱器Watcher之間進(jìn)行統(tǒng)一管理。
(4)接著,為了解析view上的指令, 我們需要一個指令解析器Compiler,對頁面每個節(jié)點和元素進(jìn)行掃描和解析,將相關(guān)指令初始化成一個訂閱者watcher。通過解析指令綁定相應(yīng)的函數(shù)。
(5)此時,當(dāng)watcher收到來自O(shè)bserver的通知,就會執(zhí)行對應(yīng)的更新view的函數(shù)。

如果要自己實現(xiàn)一個雙向綁定也就大致需要以下三個步驟:
1.實現(xiàn)一個監(jiān)聽器Observer,用來劫持監(jiān)聽所有的屬性,有變動就通知watcher。
2.實現(xiàn)一個watcher,可以收到監(jiān)聽器傳來的屬性變化通知,并執(zhí)行相應(yīng)的函數(shù),從而更新視圖。
3.實現(xiàn)一個解析器Compile,可以掃描解析每個節(jié)點的指令,并初始化末班數(shù)據(jù)和初始化訂閱器。
以下詳細(xì)思考每個步驟如何實現(xiàn)?
1.實現(xiàn)Observer
Observer是一個數(shù)據(jù)監(jiān)聽器,其實現(xiàn)的核心方法就是前文所說的Object.defineProperty(),如果要對所有的屬性都進(jìn)行監(jiān)聽的話,可以用遞歸的方法遍歷所有屬性值,對其進(jìn)行Object.defineProperty處理。

還需要創(chuàng)建一個容納所有Watcher的訂閱器Dep,訂閱器主要負(fù)責(zé)收集訂閱者,然后屬性變化的時候,執(zhí)行對應(yīng)訂閱者的更新函數(shù),所以顯然訂閱者需要有一個容器,這個容器就是list,將上面的代碼稍微改造下,植入Dep。

在get里面添加一個訂閱器是為了初始化觸發(fā),所以初始化時要判斷是否需要添加watcher,這個要具體情況具體考慮。
接下來實現(xiàn)watcher.
2.實現(xiàn)監(jiān)聽器watcher
9.diff 算法時間復(fù)雜度及原理
大搜車、作業(yè)幫
https://user-gold-cdn.xitu.io/2019/8/1/16c49afec13e0416
10.webpack打包時如何優(yōu)化減少打包時間?webpack loader和plugin有什么區(qū)別?
北明軟件、瓜子二手車、博彥科技、滴滴
11.尾遞歸優(yōu)化,尾調(diào)用優(yōu)化?
http://www.itdecent.cn/p/0ed8ed003fe0
12.遇到過哪些兼容性問題?
答:
- js
(1)DOM2級定義的深度優(yōu)先遍歷器NodeIterator 和 TreeWalker在IE中沒有對應(yīng)的類型和方法,所以使用遍歷的跨瀏覽器解決方案非常少見。 - css
13.深度優(yōu)先遍歷
- 遞歸
function deepTraversal(node,nodeList) {
if (node) {
nodeList.push(node);
var children = node.children;
for (var i = 0; i < children.length; i++)
deepTraversal(children[i],nodeList);
}
return nodeList;
}
var root = document.getElementById('root')
console.log(deepTraversal(root,nodeList=[]))
- 非遞歸
function deepTraversal(node) {
var nodeList = [];
if (node) {
var stack = [];
stack.push(node);
while (stack.length != 0) {
var childrenItem = stack.pop();
nodeList.push(childrenItem);
var childrenList = childrenItem.children;
for (var i = childrenList.length - 1; i >= 0; i--)
stack.push(childrenList[i]);
}
}
return nodeList;
}
var root = document.getElementById('root')
console.log(deepTraversal(root))
- 嵌套數(shù)組展開
- 遞歸
function flattenMd(arr) {
var result = [];
for(var i = 0; i < arr.length; i++){
if(arr[i] instanceof Array) {
result = result.concat(flattenMd(arr[i]));
}
else {
result.push(arr[i]);
}
}
return result;
}
var arr=[1, [2, 3, [4, 5], 6], 7, 8]
console.log(flattenMd(arr));
- 非遞歸
function flattenDeep(arr){
const res = [];
const stack = [...arr];
while(stack.length){
let item = stack.shift();
Array.isArray(item)?stack.unshift(...item):res.push(item);
}
return res;
}
var arr = [1,[2,[3,[[5]]],[4]]];
console.log(flattenDeep(arr))
15.跨域解決辦法?同源策略是什么?
博彥科技,大搜車,酷家樂,滴滴,貝殼
答: 通過XHR實現(xiàn)ajax的一個主要限制就來源于跨域安全策略。
默認(rèn)情況下,XHR對象只能訪問與包含它的頁面位于同一個域中的資源。
以下簡要說明常用方法:
- CORS
- IE和其他瀏覽器對CORS的實現(xiàn)
- Preflighted Request
- withCredentials 帶憑據(jù)的請求
- 跨瀏覽器的CORS
CORS(Cross-Origin Resource Sharing)
CORS背后的思想是,使用自定義的HTTP頭部讓瀏覽器與服務(wù)器進(jìn)行溝通,從而決定請求或響應(yīng)應(yīng)該是成功還是失敗。
CORS的使用方法:
在發(fā)送請求時,需要給它附加一個額外的Origin頭部,其中包含請求頁面的信息(協(xié)議,域名,端口),以便服務(wù)器根據(jù)這個信息決定是否給予響應(yīng)。
Origin: http://www.nczonline.net
如果服務(wù)器認(rèn)為這個請求可以接受,就在Access-Control-Allow-Origin頭部中回發(fā)相同的源信息。
Access-Control-Allow-Origin:http://www.nczonline.net
如果沒有這個頭部,或者有這個頭部但是源信息不匹配,瀏覽器就會駁回請求,正常情況下,瀏覽器會處理請求。
請求和響應(yīng)都不包含cookie信息。
IE對CORS 的實現(xiàn):
微軟在IE8中引入了XDR(XDomainRequest)類型,與XHR相似,但是能實現(xiàn)跨域通信。
XDR使用方法和XHR類似,
(1)創(chuàng)建一個XDomainRequest對象
(2)open() //與XHR不同的是XDR只接受兩個參數(shù),請求類型和URL
(3)send()
缺點:
(1)所有的XDR都是異步的,不能用來創(chuàng)建同步請求。
(2)收到響應(yīng)后,只能訪問響應(yīng)的原始文本,沒有辦法確定響應(yīng)的狀態(tài)碼。成功觸發(fā)onload,響應(yīng)數(shù)組放在xhr.responseText中,失敗觸發(fā)onerror,但是除了錯誤本身之外,沒有其他信息可以用。
XDR也支持
onerror()檢測錯誤
abort()在請求返回前終止請求
timeout屬性 超時設(shè)定
ontimeout()事件處理程序 超時處理程序
其他瀏覽器對CORS的實現(xiàn)
Firefox3.5+,Sarafi4+,Chrome,ios版Safari和Android平臺中的webkit都通過XHR對象實現(xiàn)了對CORS的原生支持。
使用方法:
要請求另一個域中的資源,使用標(biāo)準(zhǔn)的XHR對象,并在open()方法中傳入絕對的URL即可。
對比IE中XDR的優(yōu)點:
(1)XHR可以訪問status和statusText屬性
(2)可以發(fā)送同步請求
但是出于安全考慮也有一些限制:
(1)不能使用setRequestHeader自定義頭部信息。
(2)不能發(fā)送接收cookie
(3)調(diào)用getAllResponseHeaders()總是返回空字符串。
因為同源請求和跨域請求使用相同的接口,所以建議本地資源使用相對URL,遠(yuǎn)程資源使用絕對URL,這樣能消除歧義,避免出現(xiàn) 限制訪問頭部或本地cookie信息等問題。
Preflighted Request
支持Preflight請求的瀏覽器有Firefox3.5+,Safari4+,Chrome
CORS 通過Preflighted Request的透明服務(wù)器驗證機(jī)制支持開發(fā)人員使用自定義的GET或POST之外的方法,以及不同類型的主題內(nèi)容。瀏覽器向服務(wù)器通過高級選項發(fā)送一個Preflight請求,服務(wù)器可以決定是否允許這種類型的請求。
withCredentials 帶憑據(jù)的請求
支持withCredentials的瀏覽器有Firefox3.5+,Safari4+,Chrome,IE10及更早版本都不支持。
默認(rèn)情況下,跨源請求不提供憑據(jù),(cookie,HTTP認(rèn)證及客戶端SSL等),
通過將withCredentials設(shè)置為true,可以指定某個請求應(yīng)該發(fā)送憑證。如果服務(wù)器接收帶憑據(jù)的請求,會用下面的HTTP頭部來響應(yīng)。
Access-Control-Allow-Credentials: true
16.文本溢出顯示省略號,一行或多行的情況?
答:
- 一行:
overflow: hidden;
text-overflow: ellipsis;
white-space:nowrap;
}
- 多行
.a {
display: inline-block;
width: 200px;
height: 200px;
overflow: hidden;
position: relative;
}
.a::after {
content: '...';
position: absolute;
right: 0;
bottom: 0;
}
17.Git命令,從指定分支新建分支。
git branch [branch name] [from branch name ]
18.找出數(shù)組中重復(fù)次數(shù)最多的元素
答:
var arr = [1];
var res = {};
var most = -1;
var ele = -1;
function findMost(arr) {
if (!arr.length) {
return
} else if (arr.length == 1) {
return arr[0];
} else if (arr.length > 1) {
for (let i = 0; i < arr.length; i++) {
res[arr[i]] ? res[arr[i]]++ : res[arr[i]] = 1;
if (res[arr[i]] > most) {
most = res[arr[i]];
ele = arr[i];
}
}
}
console.log(ele);
}
findMost(arr);
19.Linux命令,打印執(zhí)行過的命令
history [n] //n是數(shù)字,要打印的條數(shù)
20.proxy
VUE3.0的雙向數(shù)據(jù)綁定
proxy用于修改某些操作的默認(rèn)行為,等同于在語言層面做出修改,所以屬于一種“元編程”,即對 編程語言進(jìn)行編程。
Proxy可以理解成在目標(biāo)對象前架設(shè)一個攔截層,外界對該對象的訪問必須先通過這層攔截,因此提供了一種機(jī)制可以對外界的訪問進(jìn)行過濾和改寫。Proxy這個詞的愿意是代理,用在這里表示由他來”代理“某些操作,可以譯為代理器。
21.將數(shù)字反轉(zhuǎn)
答:
function reverseNum(n){
console.log(n.toString().split("").reverse().join("")) | 0;
}
reverseNum(123);

