Promise.resolve方法容許調用時不帶參數,直接返回一個resolved狀態的 Promise 對象。當即resolve的 Promise 對象,是在本輪「事件循環」(event loop)的結束時,而不是在下一輪「事件循環」的開始時。好比,setTimeout(fn, 0)在下一輪「事件循環」開始時執行,Promise.resolve()在本輪「事件循環」結束時執行,console.log('one')則是當即執行。javascript
優勢:php
1) 將異步操做以同步操做的流程表達出來,避免了寫層層嵌套的回調函數css
2) Promise對象提供了統一的接口,使得控制異步操做更加容易。html
缺點:前端
1) 沒法取消html5
2) 當處於pending狀態時,沒法得知目前進展到哪個階段(剛剛開始仍是即將完成)java
宏任務:script(全局任務/JS主代碼塊)、定時器(setTiemout和setInterval)、I/O、渲染等node
微任務:Promise、MutationObserver(突變觀察者)css3
當執行棧空了的時候,先執行一個宏任務,而後執行所有的微任務;宏任務和微任務的區別就是執行順序的不一樣。nginx
1) 全部同步任務都在主線程上執行(這個主線程就是JS線程),造成一個執行棧
2) 主線程以外,還存在一個任務隊列,當異步任務有告終果,就在任務隊列裏放置一個任務(每個任務都有一個與之關聯的用於處理這條任務的函數)
3) 一旦執行棧(主線程)中的全部同步任務執行完畢,任務隊列中的任務就進入執行棧(主線程)執行(優先級:Promise>DOM事件>定時器)
4) 主線程不斷重複上述步驟,這就是事件循環
PS:
1) 瀏覽器多線程,JS線程是其中的一個,此外還有渲染線程、定時器線程、DOM事件線程、HTTP請求線程
2) 渲染線程和JS線程是互斥的,因此下載、解析、執行JS會阻塞頁面渲染(<script>用async或defer屬性能夠使下載JS時不阻塞頁面渲染)
3) 默認,瀏覽器按<script>元素的出現順序依次解析(下載能夠並行)
setTimeout(function () {
for (var i = 0; i < 100000000; i++) { }
console.log('timer a');
}, 0)
for (var j = 0; j < 5; j++) {
console.log(j);
}
setTimeout(function () {
console.log('timer b');
}, 0)
function waitFiveSeconds() {
var now = (new Date()).getTime();
while (((new Date()).getTime() - now) < 5000) { }
console.log('finished waiting');
}
document.addEventListener('click', function () {
console.log('click');
})
console.log('click begin');
waitFiveSeconds();
0
1
2
3
4
click begin
finished waiting
click
click
timer a
imer b
click
click
有權訪問另外一個函數做用域中的變量的函數。
建立閉包的常見方式,就是在一個函數內部建立另外一個函數(注意不是調用)。
閉包的做用:
1) 模仿塊級做用域(當即調用函數)
2) 在對象中建立私有變量
基本類型+淺複製的複雜類型去重:
1) 用Set
2) arr = arr.filter(function (item, index, array) {return array.indexOf(item) === index;})
filter()方法對數組中的每一項運行給定函數,返回該函數會返回true的項組成的數組。但會把NaN去得一個都不剩(由於NaN不等於NaN),除非:
arr = arr.filter(function (item, index, array) {
var flag = true;
if (flag && typeof item === 'number' && isNaN(item)) {
flag = false;
return true;
}
return array.indexOf(item) === index;
});
基本類型+深複製的複雜類型去重:
var hash = {};
arr = arr.filter(function(item) {
if (hash[JSON.stringify(item)]) {
return false;
}
hash[JSON.stringify(item)] = true;
return true;
});
解析:用JSON.stringify()是爲了區分像這種狀況:字符串1和數字1
用parseInt()函數解析字符串時,若是字符串以"0x"開頭且後跟數字字符,就會將其看成一個十六進制整數,但若是字符串以"0"開頭且後跟數字字符,不會將其看成一個八進制整數,仍然看成十進制,除非是以0開頭的數字(不是字符串)
三個階段:事件捕獲階段、處於目標階段、事件冒泡階段。
當一個事件發生在具備父元素的元素上時,瀏覽器運行兩個不一樣的階段 - 捕獲階段和冒泡階段。
在捕獲階段:
從<html>元素開始,直到實際發生事件的元素,按順序檢查每一個元素是否有相應的事件處理器,若是有,就運行
在冒泡階段,則相反:
從實際發生事件的元素開始,直到<html>元素,按順序檢查每一個元素是否有相應的事件處理器,若是有,就運行
在F12中開啓嚴格模式只會當前回車內生效
1) GET
2) HEAD:響應和GET的響應徹底相同,除了沒有響應體
3) POST
4) PUT:替換資源
5) DELETE
6) CONNECT:創建一個由目標資源標識的隧道
7) OPTIONS:描述通訊選項
8) TRACE:執行消息環回測試
9) PATCH(補丁):部分修改資源
1) GET一般用於向服務器查詢信息,POST一般用於向服務器發送應該被保存的數據;因此GET是安全的(這裏的安全指的是不修改服務器的資源),POST是不安全的;但這只是規範,實際上有用GET修改服務器資源的狀況,GET也就不安全了
2) GET是冪等的,POST不是冪等的(冪等的意思是指同一個請求方法執行屢次和僅執行一次的效果徹底相同);但這也只是規範,是否真的冪等要看服務器實現
3) GET消耗的資源比POST少(GET的請求頭少了幾個字段)
4) GET的速度比POST快(緣由是GET能夠緩存、GET的請求頭少了幾個字段,等)
5) GET傳送的數據放在URL中,POST傳送的數據放在請求體中
6) GET傳送的數據的大小有限(不是HTTP限制的,是因爲瀏覽器/服務器/操做系統(通常是瀏覽器)對URL長度的限制),POST無限
7) POST更安全(這裏的安全就是一般理解的安全了),由於在瀏覽器的歷史記錄裏能夠找到GET傳送的數據
主要的區別是性能提高:
1) 新增二進制分幀層(HTTP/2採用二進制格式傳輸數據,而HTTP/1.x用文本格式),這是HTTP/2性能提高的基礎
2) 能夠多路複用(全部請求和響應能夠經過一個TCP鏈接併發完成的;在 HTTP/1.x 中,若是客戶要想發起多個並行請求以提高性能,則必須使用多個 TCP 鏈接)
3) 能夠設置數據流的優先級
4) 服務器推送(服務器能夠對一個客戶請求發送多個響應。即,當服務器已經知道瀏覽器下一步要請求什麼資源,服務器就提早推送這些資源,而無需客戶明確地請求)
5) 頭部壓縮(壓縮方式爲HPACK )
1) margin: 0 auto 前提條件:元素定寬、塊級元素
2) 在父元素上設置text-align: center 前提條件:內聯元素
3) 絕對定位(已知元素寬度):可先設置left: 50%再設置負的margin-left爲元素的寬度的一半,也可用calc一步到位計算left
4) 絕對定位(未知元素寬度):也是先設置left: 50%,再用transform: translate(-50%, 0) 使元素移動相對於自身的寬度的一半。
5) 在須要水平垂直居中的元素的父元素上設置display: flex和在須要水平垂直居中的元素上設置margin: auto(若是看上去垂直位置沒有變化,就多是父元素沒設置高度)。水平居中還可在父元素上同時設置display: flex;和justify-content: center;
6) position: absolute; top: 0; right:0; bottom:0; left:0; margin: auto;也可讓元素水平垂直居中。前提條件:元素定寬、定高
1) 將line-height設置成和父元素的height的值同樣 前提條件:不是替換元素(好比img和input)的內聯元素;不是內聯元素就只能居中其中的文本。
2) vertical-align: middle 前提條件:有點複雜
3) 絕對定位(已知元素寬度):和水平居中的相似
4) 絕對定位(未知元素寬度):和水平居中的相似
5) 在須要水平垂直居中的元素的父元素上設置display: flex和在須要水平垂直居中的元素上設置margin: auto(若是看上去垂直位置沒有變化,就多是父元素沒設置高度)。文本垂直居中則要在父元素上同時設置display: flex;和align-items: center; (若是看上去位置沒有變化,就多是父元素沒設置高度)
6) position: absolute; top: 0; right:0; bottom:0; left:0; margin: auto;也可讓元素水平垂直居中。前提條件:元素定寬、定高
1) 最初,客戶的TCP進程處於關閉(CLOSED)狀態,服務器的TCP進程處於收聽(LISTEN)狀態,服務器在等待客戶的鏈接請求
2) 客戶向服務器發出鏈接請求報文段(SYN置1,初始序號seq=x),並進入同步已發送(SYN-SENT)狀態
3) 服務器收到鏈接請求報文段後,向客戶發送確認(SYN置1,ACK置1,確認號ack=x+1,初始序號seq=y),並進入同步已收到(SYN-RCVD)狀態
4) 客戶收到服務器的確認後,向服務器發送確認(ACK置1,確認號ack=y+1,序號seq=x+1),並進入鏈接已創建(ESTABLISHED)狀態
5) 服務器收到客戶的確認後,也進入鏈接已創建(ESTABLISHED)狀態
三次是爲了防止已失效的鏈接請求報文段忽然又傳送到了服務器。具體來講就是,當客戶發出鏈接請求,但鏈接請求報文段在網絡中長時間滯留了,客戶就沒有及時收到確認,因而客戶重傳鏈接請求,此次請求沒出現問題,創建了鏈接並傳輸了數據,最後釋放了鏈接。但釋放了鏈接後,以前滯留在網絡種的鏈接請求報文段忽然傳送到了服務器,若是不使用三次握手,那麼服務器就覺得客戶如今請求創建鏈接,因而分配資源,等待客戶發送數據,但客戶並無想要創建鏈接,因此不會向服務器發送數據。因而,服務器傻乎乎地等客戶發送數據,浪費了資源。
1) 首先,客戶和服務器都處於鏈接已創建(ESTABLISHED)狀態,雙方均可以主動釋放鏈接,假設客戶主動釋放鏈接
2) 客戶向服務器發出鏈接釋放報文段,並中止發送數據,進入終止等待1(FIN-WAIT-1)狀態
3) 服務器收到鏈接釋放報文段後,向客戶發出確認,服務器就進入關閉等待(CLOSE-WAIT)狀態,此時,服務器還能夠發送數據
4) 客戶收到服務器的確認後,進入終止等待2(FIN-WAIT-2)狀態,等待服務器發出鏈接釋放報文段
5) 服務器發完數據後,向客戶發出鏈接釋放報文段,進入最後確認(LAST-ACK)狀態
6) 客戶收到服務器的鏈接釋放報文段後,向服務器發出確認,進入時間等待(TIME-WAIT)狀態,等待必定時間後(兩倍最長報文段壽命的時間),若是沒有收到服務器重傳的鏈接釋放報文段,進入關閉(CLOSED)狀態
7) 服務器收到客戶的確認後,進入關閉(CLOSED)狀態
PS:之因此有時間等待狀態,是爲了保證客戶發送的最後一個確認報文段能被服務器收到,由於這個報文段有可能丟失,而後服務器收不到確認就會重傳鏈接釋放報文段,客戶就會在時間等待狀態期間收到這個重傳的鏈接釋放報文段,而後客戶就重傳確認,並重置時間等待計時器。若是客戶沒有時間等待狀態,那服務器就可能不能正常進入關閉狀態(服務器重傳以後客戶沒反應)。
盒模型是佈局的基礎,每個元素被表示爲一個矩形盒子,這個矩形盒子由content、padding、border盒margin組成。
標準盒模型(即box-sizing: content-box)的width和height只包括content;IE盒模型(指老的IE,即box-sizing: border-box)的width和height包括content、padding和border
1) static:靜態定位,默認值,把元素放在正常的文檔流(normal flow)中,沒有什麼特別的
2) relative:相對定位,它和靜態定位很像,也把元素放在正常的文檔流中,只不過能夠修改它的最終位置
3) absolute:絕對定位,使元素脫離正常的文檔流,相對於它的第一個不是靜態定位的父元素定位,若是沒有不是靜態定位的父元素,就相對於「第一屏」定位
4) fixed:固定定位,與絕對定位很像,也會使元素脫離正常的文檔流,可是它是相對於瀏覽器視口定位
5) sticky:靜態定位和固定定位的結合,使元素的行爲一開始像靜態定位,直到它的位置被滾動到設定的值,行爲就像固定定位了
6) inherit、initial、unset
冒泡、選擇、插入、快排、歸併、計數
冒泡、選擇、插入的平均、最壞狀況的時間複雜度都是O(n^2),快排平均是O(nlogn)、最壞是O(n^2),歸併平均、最壞都是O(nlogn),計數平均、最壞都是O(n)(空間複雜度須要O(n))
冒泡、插入、歸併、計數是穩定的,選擇、快排是不穩定的
基本思想:兩兩比較相鄰元素,若是反序就交換,直到沒有反序爲止。
function bubbleSort(arr) {
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
}
}
}
return arr;
}
1)在序列中選一個基準
2)把全部小於基準的數放到基準左邊,把全部大於基準的數放到基準右邊
3)分別對基準左右兩邊的子集重複上述步驟,直到全部的子集都只剩一個元素
function quickSort(arr) {
if (arr.length <= 1) {
return arr;
}
var pivotIndex = Math.floor(arr.length / 2);
var pivot = arr[pivotIndex];
var left = [],
right = [];
for (var i = 0; i < arr.length; i++) {
if (i !== pivotIndex) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
}
return quickSort(left).concat(pivot, quickSort(right));
}
最壞狀況是當數組已經排好序時(或者說每次劃分時取的樞軸都是最大值或最小值)。
避免最壞狀況的方法有:
1) 隨機取基準(有極小的可能仍是會出現最壞狀況)
2) 三數取中(第一項、中間項、最後一項)
3) 用快排的思想求中位數,平均時間複雜度是O(n)(這種方法也適用於在無序序列中找第k大/小的值)。
1) 拆分數組,直到每一個數組只有一個元素
2) 每兩個數組爲一組,進行排序併合並
3) 重複第二步
function merge(left, right) {
var result = [],
i = 0,
j = 0;
while (i < left.length && j < right.length) {
if (left[i] < right[j]) {
result.push(left[i++]);
} else {
result.push(right[j++]);
}
}
return result.concat(left.slice(i), right.slice(j));
}
function mergeSort(arr) {
if (arr.length < 2) {
return arr;
}
var mid = Math.floor(arr.length / 2),
left = arr.slice(0, mid),
right = arr.slice(mid);
return merge(mergeSort(left), mergeSort(right));
}
function countSort(arr) {
var c = [];
for (var i = 0; i < arr.length; i++) {
if (c[arr[i]]) {
c[arr[i]]++;
} else {
c[arr[i]] = 1;
}
}
var res = [];
for (var i = 0; i < c.length; i++) {
while (c[i]) {
res.push(i);
c[i]--;
}
}
return res;
}
1) 200(OK,請求成功)
2) 301(Moved Permanently,永久重定向)
3) 302(Found,臨時重定向)
4) 304(Not Modified,命中協商緩存)
5) 403(Forbidden,服務器拒絕響應,可能由於客戶沒有權限訪問相應的內容)
6) 404(Not Found,找不到頁面)
7) 405(Method Not Allowed,請求方法不被容許)
8) 500(Internal Server Error,內部服務器錯誤,服務器遇到了不知道如何處理的狀況)
PS:1**表示信息響應,2**表示成功響應,3**表示重定向,4**表示客戶端錯誤,5**表示服務器端錯誤
瀏覽器緩存:分爲強緩存(用Expires(絕對時間)或Cache-Control(相對時間))和協商緩存(用Last-Modified(最後修改時間)或ETag(標識符),Etag的優點是當資源修改後又改回來時仍不變,而Last-Modified會變,這就坑了)。若是命中強緩存(返回200,由於返回的響應頭是以前緩存下來的),瀏覽器直接從本身的緩存中加載資源,不會發請求到服務器;若是沒有命中強緩存,瀏覽器就發請求到服務器,看是否命中協商緩存;若是命中協商緩存(返回304),服務器就返回一個沒有資源的響應,告訴瀏覽器能夠直接從緩存中加載資源,而後瀏覽器就從本身的緩存中加載資源。若是協商緩存也沒有中,那瀏覽器從服務器加載資源。
代理服務器:又稱爲萬維網高速緩存。代理服務器就像箇中介,把最近的一些請求和響應暫存在本地磁盤中。當新請求到達時,若是代理服務器發現這個請求與暫時存放的請求相同,就返回暫存的響應,而不須要按URL的地址再次去源點服務器訪問該資源。
1) Expires:用於強緩存,設置緩存過時的絕對時間。當Cache-Contorl設置了緩存過時的相對時間時Expires會被忽略
2) Cache-Control:用於強緩存,設置緩存過時的相對時間。值有public(你們,包括瀏覽器和代理服務器,均可以緩存響應)、private(響應只能被瀏覽器緩存)、no-cache(使用緩存以前要向服務器驗證,即協商緩存)、no-store(禁止緩存)、max-age(緩存有效期)。
3) Last-Modified(請求時帶上If-Modified-Since):用於協商緩存,表示資源的最後修改時間
4) ETag(請求時帶上If-None-Match):用於協商緩存,表示資源每次修改後會得到的新的標識符
1) HTTPS是HTTP的安全版,利用SSL(Secure Socket Layer)或TLS(Transport Layer Security)來加密數據,而HTTP的數據是明文傳輸的
2) HTTPS的URL的開頭是https,HTTP的URL的開頭是http
3) HTTPS的默認端口是443,HTTP的默認端口是80
4) HTTPS貴(好比,好的HTTPS證書要錢)
5) HTTPS能夠防止運營商劫持
6) HTTPS比較慢(加解密、交換公鑰私鑰、輸入簡寫網址時的跳轉)
7) HTTPS有利於SEO(用HTTPS的網站的搜索排名會更前)
1) 瀏覽器向服務器發送HTTPS請求
2) 服務器返回證書公鑰
3) 瀏覽器驗證證書公鑰,不合法就警告用戶,合法就下一步
4) 瀏覽器生成一個密鑰,並用證書公鑰加密這個密鑰
5) 瀏覽器把加密過的密鑰發送給服務器
6) 服務器收到加密過的密鑰後,用證書私鑰解密密鑰,而後用密鑰加密要返回的內容,並返回給瀏覽器
7) 瀏覽器用密鑰解密內容
5) 多窗口共享:Cookie和localStorage能夠多窗口共享,sessionStorage不能夠
Cookie經常使用來識別、跟蹤用戶(兼職本地存儲),localStorage可用來保存購物車,sessionStorage可用來保存由於內容特別多而被拆分紅多個子頁面的表單頁面的表單信息(localStorage、sessionStorage全職本地存儲)。
1)加載、解析HTML,生成DOM樹
2)加載、解析CSS
3)把解析出來的樣式添加到DOM節點上,生成渲染樹
4)根據渲染樹,計算節點信息
5)根據計算結果,渲染頁面
1) 把<script>標籤放在<body>標籤的底部:避免阻塞。在解析JS代碼以前,頁面的內容將徹底呈如今瀏覽器中,而用戶也會由於瀏覽器窗口顯示空白頁面的時間縮短而感到打開頁面的速度加快了
2) 雪碧圖:減小HTTP請求、減少請求的資源大小(既加快了傳輸速度又加快了解析速度)
3) 合併CSS、JS文件:減小HTTP請求
4) 壓縮代碼(刪除空白、註釋,減短變量名)、圖片:減少請求的資源大小
5) 合理設置緩存
6) 按需加載資源,好比沒出如今視野裏的圖片先不加載:減小向服務器發出的併發請求數量(這就使得頁面的其它部分的加載速度更快),減小瀏覽器的內存使用率(更少的圖片,更少的內存)
7) 啓用HTTP/2
8) 事件委託:事件處理器數量直接關係到頁面的性能,緣由是:首先,每一個函數都是對象,會佔用內存;其次,必須事先指定全部事件處理器而致使的DOM訪問次數,會延遲整個頁面的交互就緒時間
9) 減小DOM操做(減小重排重繪)
10)減小DOM元素數量
11)多用GET少用POST
12)本地存儲用localStorage、sessionStorage代替cookie
13)用animation、transform和transition時開啓硬件(GPU)加速(transform: translateZ(0))
14)對再也不須要的全局變量和全局對象的屬性及時解除引用(局部變量會在它們離開做用域時自動被解除引用)
重繪:即從新繪製,好比當元素的顏色改變或文字內容更新時會觸發重繪。
重排:即從新生成佈局,好比當元素的位置或尺寸改變、獲取某些值、DOM結構改變、瀏覽器窗口大小改變、頁面初始化時會觸發重排。
發生了重排,就必定會發生重繪;發生了重繪,不必定發生重排。
重排重繪嚴重影響性能,尤爲是重排。
怎麼減小:
1) 把DOM 的多個讀操做(或多個寫操做)放在一塊兒,不要兩個讀操做之間加入一個寫操做
2) 緩存須要屢次用到且經過重排才能獲取的值,好比offsetWidth(offsetWidth包括border、水平padding、豎直的滾動條(若是有的話)和width)
3) 不要一條條地改變樣式,而經過改變class,一次性地改變樣式
4) DocumentFragment
5) display: none
6) position設爲absolute或fixed,重排的開銷會比較小,由於不用考慮它對其餘元素的影響
7) 用requestAnimationFrame,它能夠積累屢次重排,而後一次性完成
8) 能用transform就不用postion/width/height
谷歌瀏覽器的network和performance裏能夠看(DOMContentLoaded和Load,前者意味着HTML已加載、解析,而無論CSS、圖片等,後者則是全部的資源徹底加載後)
咱們建立的每個函數都有一個名字叫prototype的屬性,這個屬性是一個指針,指向一個對象,而這個對象的用途是包含能夠由特定類型的全部實例共享的屬性和方法,這個對象就叫原型。
一個實例包含一個指向原型的內部指針,若是這個原型是另外一個類型的實例,那麼這個原型將包含一個指向另外一個原型的內部指針,如此層層遞進,就構成了原型鏈。(原型鏈規定了對象的屬性和方法的查找規則)
[[Prototype]],它被兩對方括號括起來,表示是內部屬性。在JS中沒有標準的方式訪問它,但一些瀏覽器支持使用__proto__屬性訪問它。
面向對象:基本的 OOP 思想就是使用對象來模仿咱們想要在程序中表現的現實世界的事物, 同時提供一種簡單的方式來訪問這些事物的功能。
做用域:定義了變量和函數有權訪問的其它數據,決定了變量和函數的生命週期。(每一個做用域都有一個與之關聯的變量對象,做用域中定義的全部變量和函數都保存在這個對象中。)
做用域鏈:做用域依次相連就構成了做用域鏈。做用域鏈的用途是,保證對做用域有權訪問的全部變量和函數的有序訪問。(做用域鏈定義了變量的查找規則)
當某個函數被調用時,會建立一個做用域及相應的做用域鏈。
1) 瀏覽器判斷是否命中強緩存,若是命中(返回200),從緩存中加載資源,若是沒命中
2) 瀏覽器經過DNS解析URL,得到相應的IP地址
3) 瀏覽器用三次握手和服務器創建TCP鏈接
4) 瀏覽器經過HTTP請求,向服務器請求展現頁面須要的資源
5) 服務器判斷是否命中協商緩存,若是命中(返回304),就經過HTTP響應告訴瀏覽器從緩存中加載資源,若是沒命中,就經過HTTP響應把資源返回給瀏覽器
6) 瀏覽器獲取到資源後:
a) 加載、解析HTML,生成DOM樹
b) 加載、解析CSS
c) 把解析出來的樣式添加到DOM節點上,生成渲染樹
d) 根據渲染樹,計算節點信息
e) 根據計算結果,渲染頁面
1) typeof操做符:檢測一個變量是否是基本數據類型的最佳工具。返回值是字符串,包括'undefined','boolean','string','number','symbol','object','function'
2) instanceof操做符:(根據原型鏈)檢測引用類型的值的類型。若是使用instanceof操做符檢測基本數據類型的值,則返回false,由於基本數據類型的值不是對象(對象===引用類型的值)。
PS:當要肯定某個對象是否是數組時,若是存在一個以上的全局做用域時(好比網頁中包含多個框架),用instanceof就會有問題,由於不一樣全局做用域中的數組的構造函數不一樣
3) 對象的constructor屬性保存着用於建立當前對象的函數
4) isPrototypeOf()方法。好比:Object.prototype.isPrototypeOf(Function.prototype)
5) Object.prototype.toString.apply(value):返回 '[object Null/ Undefined/ Boolean/ String/ Number/ Symbol/ Object/ Array/ Function/ RegExp/ Date/ Window/ Math]'(全部類型均可以檢測)
6) Array.isArray():檢測數組
沒有,最近忙着秋招呢,解決溫飽問題要緊。
JS具備自動垃圾收集機制,原理是垃圾收集器週期性地找出那些再也不繼續使用的變量,而後釋放其佔用的內存。垃圾收集有兩種策略:標記清除和引用計數。引用計數只有IE9之前的IE在用。標記清除的思想是給當前不使用的變量加上標記,而後再回收其內存。
(寫完組合繼承後)組合繼承這種方式有不足的地方,還能夠優化。(等面試官迴應)不足的地方是會調用兩次超類型構造函數:一次是在建立子類型原型的時候,另外一次是在建立子類型實例的時候。結果就是,子類型的原型中有超類型的實例屬性,子類型的實例中也有超類型的實例屬性,而實例中的屬性會覆蓋原型中的同名屬性,因此子類型的原型中的超類型的實例屬性是多餘的。解決辦法是用寄生組合式繼承。(寫寄生組合式繼承)這樣,就只用調用一次超類型構造函數,從而提升了效率,而且所以避免了在子類型的原型上建立多餘的屬性。Object.create()在傳入一個參數的狀況下,它的行爲就像這樣(寫),咱們把超類型的原型傳進去後,能夠理解成,new了一個構造函數爲空的超類型的實例並返回,因此它的返回結果仍然是指向超類型的原型的,只不過沒有了超類型的構造函數裏的那些屬性。
Object.create = function (proto) {
function F() {}
F.prototype = proto;
return new F();
};
function Super(name) {
if (this === window) {
return new Super(name) ;
} else {
this.name = name;
}
}
Super.prototype.sayName = function () {
alert(this.name);
};
function Sub(name, age) {
Super.call(this, name);
this.age = age;
}
// Sub.prototype = new Super();
Sub.prototype = Object.create(Super.prototype);
// Sub.prototype.constructor = Sub;
Object.defineProperty(Sub.prototype, 'constructor', {
value: Sub
});
PS:Sub.prototype = Object.create(Super.prototype)重寫了Sub.prototype,因此Sub.prototype.constructor再也不指向Sub(Sub.prototype沒有名爲constructor的實例屬性,在它上面訪問到的constructor是原型鏈上的)(默認,原型都會自動得到一個constructor屬性,這個屬性指向prototype屬性所在的(構造)函數),指向Super(構造函數)。此時,instanceof操做符(加號、減號那些也是操做符)仍然能夠返回正確的結果,但經過constructor已經沒法肯定對象的類型了,因此有了後面的Sub.prototype.constructor = Sub
PPS:以Sub.prototype.constructor = Sub這種方式重設constructor屬性會致使它的[[Enumerable]]特性被設置爲true(原生的constructor屬性是不可枚舉的),由於開發人員定義的全部屬性都是可枚舉的(除非用Object.defineProperty())。強迫症晚期患者能夠使用Object.defineProperty()來代替上述方式。
PPPS:在調用Object.defineProperty()方法建立一個新的屬性時,若是不指定,configurable、enumerable、writable特性的默認值都是false。若是調用Object.defineProperty()方法只是修改已定義的屬性的特性,則無此限制。[[Configurable]]表示可否經過delete刪除屬性從而從新定義屬性,可否修改屬性的特性,或者可否把屬性修改成訪問器屬性。
PPPPS:直接在對象上定義的屬性,它們的[[Configurable]]、[[Enumerable]]和[[Writable]]特性都被設置爲true,而[[Value]]特性被設置爲指定的值。
63. 三列布局(兩邊固定,中間自適應)?
1) 浮動法
#left, #right {
width: 300px;
}
#mid {
width: calc(100% - 600px);
}
section {
float: left;
}
或(HTML中#mid標籤要放最後)
#left {
width: 300px;
float: left;
}
#right {
width: 300px;
float: right;
}
2) 絕對定位法
body {
margin: 0;
}
#left {
width: 300px;
position: absolute;
left: 0;
top: 0;
}
#right {
width: 300px;
position: absolute;
right: 0;
top: 0;
}
#mid {
margin: 0 300px;
}
3) flex
#contain {
display: flex;
}
#left, #right {
flex: 300px 0;
}
#mid {
flex: 1;
}
1) 給浮動元素後面的兄弟元素加clear: both;
2) 若是浮動元素後面沒兄弟元素了,就本身建立個
3) 給浮動元素的容器添加::after僞元素,再設置clear: both、display: block和content: ''
4) 給浮動元素的容器添加overflow: hidden;或overflow: auto;
5) 給浮動元素的容器添加浮動
6) 給浮動元素的容器設置高度
當容器的高度爲auto,且容器的內容中有浮動(float爲left或right)的元素,在這種狀況下,容器的高度不能自動伸長以適應內容的高度,這個現象叫浮動溢出。爲了防止這個現象的出現而進行的CSS處理,就叫清除浮動。
Nginx
Nginx解決跨域的原理:既然瀏覽器不能跨域,那就讓瀏覽器訪問同源的url,而後讓Nginx拿着這個url去找要跨的域,即nginx至關於一箇中介。
跨(源)域/同源策略限制不一樣源之間的交互(具體來講,限制Cookie、loaclStorage、IndexedDB、DOM、Ajax等)。只要協議、域名、端口有任何一個不一樣,就是跨(源)域/不一樣源。
目的是保證用戶信息的安全,防止惡意網站竊取數據。設想這樣一種狀況:用戶訪問了一個使用了Cookie的網站A後, 又去訪問網站B,若是沒有同源策略,那網站B就能夠拿到網站A的Cookie。而Cookie經常使用來保存用戶的登陸狀態,那網站B就能夠冒充用戶隨心所欲。
Nginx、設置document.domain、HTML5的postMessage、圖像PING、JSONP、CORS等
動態添加<script>標籤來執行服務器提供的JS代碼。由兩部分組成:回調函數和數據
1) 只能發GET請求
2) 不安全。由於是從其它域加載代碼執行,若是其它域不安全,極可能響應中會有惡意代碼
3) 不容易肯定JSONP請求是否失敗。有些瀏覽器不支持<script>元素的onerror事件處理器,因此,不得不經過檢測指定時間內是否接收到了響應來肯定是否失敗,但這樣也不太行,由於每一個用戶的網速都不同。
function handleResponse(response){
alert(response);
}
var script = document.createElement("script");
script.src = "http://www.test.com/json/?callback=handleResponse";
document.body.appendChild(script);
異步JS+XML的縮寫,這一技術可以向服務器請求額外的數據而不用刷新頁面,會帶來更好的用戶體驗。Ajax技術的核心是XHR對象。(最初,XHR對象不能跨域,直到後來出現了CORS(跨域資源共享)。在CORS出現之前,開發人員就想出了一些辦法實現跨域Ajax通訊,好比圖像Ping(即用<img>標籤)、JSONP(即動態建立<script>標籤))
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
alert(xhr.statusText);
} else {
alert(xhr.status);
}
};
xhr.open('get', url); // 第三個參數爲false時則請求爲同步的
xhr.send(null); // 參數是要做爲請求體發送的數據,POST時的數據就在這
Fetch是Ajax的衆多實現中的一種,它們不是並列關係,不適合談它們的區別。
我猜你想問的是Ajax傳統的實現XHR和Fetch的區別。
Fetch是用來替代XHR的,Fetch包括了XHR的全部功能,並且更增強大。Fetch是基於 Promise 的。
XSS,跨站腳本攻擊,容許惡意用戶將惡意代碼注入到網頁上,其餘用戶瀏覽網頁時就會加載並執行惡意代碼。持久型舉例:一個能夠評論的論壇,若是這個論壇不採起任何防範措施,那就能夠把惡意腳本放在評論裏,提交評論到數據庫。當評論被展現給其它用戶時,惡意腳本就會被執行。反射型舉例:假設有一個搜索函數,搜索項會做爲URL參數的一部分,搜索項會和搜索結果一塊兒展現。攻擊者能夠構造一個由惡意腳本做爲URL參數的搜索連接而後把它發給其它用戶,若是其它用戶點擊了這個連接,當搜索結果被展現時惡意腳本就會被執行。
防範XSS:
1) 針對能夠運行代碼的內容,進行輸入過濾、轉義(實體化轉義)(許多框架默認都會過濾用戶在表單的輸入),對於HTML來講,包括<script>和<link>等等。輸入過濾還包括限制輸入類型和輸入內容的長度(增長XSS的難度)
2) 純前端渲染。在純前端渲染中,咱們會明確的告訴瀏覽器:下面要設置的內容是文本(.innerText),仍是屬性(.setAttribute),仍是樣式(.style)等等。瀏覽器不會被輕易的被欺騙,執行預期外的代碼了。缺點:性能很差且不利於SEO
3) CSP(內容安全策略),就像一個白名單,瀏覽器只執行來自白名單的腳本,忽略其它腳本,包括內聯腳本和HTML屬性形式的事件處理器)
4) HTTPOnly(保護Cookie以避免被XSS獲取,HTTPOnly會禁止JS訪問Cookie)
CSRF,跨站請求僞造,容許惡意用戶在其它用戶不知情的狀況下利用其身份信息執行操做。舉例:假設我是壞蛋,我知道一個網站容許登陸的用戶經過一個POST請求把錢轉給一個帳號,這個POST請求包含金額和要轉入的帳號,那我就能夠構造一個包含必定金額和個人帳號的表單,而後把它發給其它用戶。若是其它已登陸的用戶點擊了表單的提交按鈕,那我就發財了。假設我是壞蛋,我知道一家銀行用以執行轉帳操做的URL的格式,那麼,我就能夠在一個網站上放置一個<img>標籤,這個<img>標籤的src屬性就是我僞造的URL,URL的含義是轉帳給個人帳號,若是其它用戶訪問了這個網站,而這個用戶以前登陸過了那家銀行,登陸信息還沒過時,那我就發財了。
防範CSRF:
1) 服務器要求用戶的請求都帶上一個token,這個token是服務器提供給用戶的,當服務器收到請求時,就檢查token,token正確才響應。
2) 服務器檢查HTTP請求頭中的Referer(能夠僞造)
3) 驗證碼
XSS 利用的是瀏覽器對網站的信任,CSRF 利用的是網站對瀏覽器的信任。
深度優先遍歷分爲先序遍歷、中序遍歷、後序遍歷。
廣度優先:
用迭代:用一個輔助隊列,初始化時根節點入隊,而後進入迭代。每一步迭代中,先取出並訪問位於隊首的節點,而後其左、右孩子若是存在,順序入隊。若是進入下一次迭代前發現隊列爲空,則遍歷完成。
function bfs(node) {
var arr = [];
arr.push(node);
while (arr.length) {
var temp = arr.shift();
console.log(temp.value);
if (temp.left) {
arr.push(temp.left);
}
if (temp.right) {
arr.push(temp.right);
}
}
}
1) let、const有塊級做用域
2) let、const沒有變量提高
3) let、const不能重複聲明
4) let、const存在暫時性死區(即在代碼塊內,在聲明以前使用變量會報錯,即便代碼塊外聲明瞭同名的變量)
5) const聲明的是常量
6) const必須初始化
1) 箭頭函數簡潔
2) 沒有本身的this和arguments(用this和arguments時就像用普通變量同樣,去外層做用域查找this和arguments)
3) 不能用做構造函數
4) 無視apply和call方法的第一個參數
內聯:
a span th td label input textarea button em strong b i u img video audio
塊級:
h1-h6 p div header nav main aside footer article section ul ol li dl dt dd figure figcaption table caption tr form
空元素:
img input br hr meta link
替換元素:
iframe video img (audio canvas)
是元數據元素,元數據就是用來描述數據的數據。<meta>的屬性有name,定義頁面的做者,content,定義頁面的內容描述,charset,定義頁面的字符集(,viewport,響應式設計時會用到)。
建立型模式:工廠模式、構造函數模式、原型模式、組合使用構造函數模式和原型模式。
在JS中,當咱們用對象字面量建立不少對象時,有個明顯的缺點:會產生大量的重複代碼。工廠模式能夠用來解決這個問題。工廠模式抽象了建立對象的過程,經過定義一個函數,用這個函數來封裝以特定接口建立對象的細節,建立對象時調用這個函數並傳入相應的參數就能夠了。
定義了對象間的一種一對多的依賴關係,當一個對象的狀態改變時,全部依賴於它的對象都將獲得通知。
this指向的是函數的做用域,在運行時才綁定。this的值取決於調用的模式,有4種調用模式:方法調用模式、函數調用模式、構造函數調用模式和apply/call調用模式。
1) 方法調用模式:一個對象的方法中的this指向這個對象
2) 函數調用模式:函數中的this指向全局對象,即window(這裏的函數特指除了方法之外的函數)(不包括箭頭函數)
3) 構造函數調用模式:構造函數中的this指向新建立的對象
4) apply/call調用模式:函數調用apply()、call()方法會把函數的this改爲指向傳給apply()、call()方法的第一個參數
PS:箭頭函數修復了方法中的函數的this指向window的問題,即指向了對象
語義化的意思是HTML標籤的使用要符合它們被設計的目的
語義化的好處:
1) 有利於人讀懂代碼
2) 有利於機器讀懂代碼(好比SEO、屏幕閱讀器)
3) 能夠輕鬆得到一些樣式和功能。好比若是用div作按鈕,這個按鈕的樣式就所有要本身寫,並且默認不能經過Tab鍵來選擇按鈕、不能用回車點擊按鈕;用button作按鈕就不會這樣。
基本類型的值在內存中佔據的空間的大小固定,所以保存在棧內存中;引用類型的值可能由多個基本類型值和引用類型值構成,因此在內存中佔據的空間的大小不固定,所以保存在堆內存中。在複製基本類型的值時,複製的就是真正的數據;而在複製引用類型的值時,複製的是指針,指針指向的纔是真正的數據。
谷歌瀏覽器的network
1) let和const
2) 解構賦值
3) 箭頭函數
4) 數組的擴展運算符…,Array.from()
5) Symbol
6) 新的數據結構Set和Map
7) Promise
8) for-of循環
9) Class
相似於對象,也是鍵值對的集合,但鍵的類型不限於字符串,好比對象也能夠做爲鍵。
91. for-of?
for-of輸出的是value,for-in輸出的是key;for-of不能循環普通的對象(不過能夠經過和Object.keys()搭配使用實現);通常,遍歷數組的時候用for-of,遍歷對象時用for-in
1) undefined派生自null,相等運算符返回ture,全等運算符返回false
2) 聲明變量但沒有初始化,那這個變量的值就是undefined;一個變量的值要是null則必須明確設置
3) typeof undefined返回'undefined',typeof null返回'object'
4) undefined和數字相加時undefined轉換爲NaN, null和數字相加時null轉換爲0
我實習時作的就是SPA。整個網站只有一個<html>元素,不少資源都是公用的。優勢是頁面切換時都是頁面局部的更新,速度快,用戶體驗好。缺點是對搜索引擎不友好
防抖:
事件觸發n秒後再執行回調,若是在這n秒內又被觸發,則從新計時。實現:事件觸發後,用定時器延遲必定時間執行事件,若是還沒到達設定的時間事件又觸發了,就取消以前的定時器,設置新的定時器。
應用場景:
1) 改變窗口大小而觸發的事件
2) 滾動滾動條而觸發的事件
3) 文本輸入(補全提示、輸入驗證)
function debounce(func, wait) {
var timeoutID;
return function () {
clearTimeout(timeoutID)
timeoutID = setTimeout(func, wait);
}
}
節流:
必定時間內只有一次事件的觸發有效。實現:若是持續觸發事件,在一段時間內,也只執行一次。能夠用時間戳實現也能夠用setTimeout實現。使用時間戳是,當事件觸發時,取出當前的時間戳,減去以前的時間戳,若是大於設置的時間間隔,就執行,而後更新時間戳爲當前的時間戳,不然就不執行;使用setTimeout是,當事件觸發時,用定時器延遲必定時間執行事件(或執行事件後設置一個定時器),再次觸發事件的時候,若是定時器存在,就無視再次觸發的事件,定時器執行後,清空定時器。
應用場景:
1) 拖拽
2) 射擊遊戲的子彈射速
3) 計算鼠標移動的距離
function throttle(func, wait) {
var timeout = null;
return function () {
if (timeout === null) {
timeout = setTimeout(function () {
func();
timeout = null;
}, wait);
}
}
}
輸入提示:datalist
輸入完成後才提示:setTimeout和clearTimeout
用hash或History API
createElement、appendChild、insertBefore 、remove、querySelector、querySelectorAll
視圖的更改會反映到數據模型,數據模型的更改也會反映到視圖(Angular是MVVM)。
原理:當一個事件(包括DOM事件、Ajax和定時器)發生後,數據模型被改變(視圖到數據模型的映射),同時會觸發髒檢查,進入digest循環,遍歷並檢查全部的watcher,若是發現數據變了,就執行相應的函數更新視圖(數據模型到視圖的映射)(只要有watcher監聽的數據改變過,那麼就會再遍歷並檢查一遍,直到全部的值都沒有變化)。
是一種數據模型到視圖的映射機制,當一個事件發生後,會觸發髒檢查,進入digest循環,遍歷並檢查全部的watcher,若是發現數據變了,就執行相應的函數更新視圖Angular1的優缺點?
優勢:
1) 雙向數據綁定,免去了繁瑣的DOM操做
2) 適合作單頁面應用
缺點:
1) 中文資料少
2) 社區小
3) 難學
4) 難以作複雜的DOM操做(或者說難以作交互頻繁的網站)
5) 性能差(髒檢查,注意強調是Angular1)
6) 不利於SEO
function F(name) {
if (this === window) {
return new F(name) ;
} else {
this.name = name;
}
}
注意清除浮動
給這些列的父元素設置display: flex
用當即調用函數表達式來傳參,或者用let代替var
HTML5:
1) 新元素(包括語義化、音視頻、圖形):header nav main aside footer article section audio video canvas
2) 表單加強:<input>的type屬性新增值,好比date、email、number、search、tel;<input>新增屬性,好比autofocus、required
3) localStorage和sessionStorage
4) History API
CSS3:
1) 圓角boder-radius
2) 陰影box-shadow、text-shadow
3) 多重背景
4) 漸變linear-gradient
5) 變形transform
6) 過渡transition
7) box-sizing
8) 彈性盒子flex box
9) RGBA、HSLA
10)更多的選擇器(子串屬性選擇器和屬於僞類選擇器的子元素選擇器)
簡單選擇器(包括標籤名、class、id選擇器)、屬性選擇器、僞類選擇器、僞元素選擇器、組合選擇器、多選選擇器、通用選擇器
優先級:
!important > 內聯樣式 > id選擇器 > class選擇器、屬性選擇器、僞類選擇器 > 標籤名選擇器、僞元素選擇器 > 組合選擇器、多選選擇器、通用選擇器
優化:
1) 關鍵選擇器儘可能用id、class選擇器、標籤名選擇器,儘可能不用屬性、僞類選擇器(瀏覽器讀取選擇器的順序是由右到左,最右的選擇器稱爲關鍵選擇器)
2) 不要在id選擇器前加class或標籤名,不要在class選擇器前加標籤名
3) 儘可能少用後代選擇器
可繼承:font color text-align letter-spacing visibility
不可繼承:display float position top right bottom left margin border padding width height background vertical-align
1) global
2) ignoreCase
3) multiline:布爾值,表示是否設置了m標誌。m表示多行模式,即在到達一行文本末尾時還會繼續查找下一行
4) lastIndex:整數,表示開始下一次搜索時的字符位置
5) source:正則表達式的字符串表示
AngularJS:善於構建單頁Web應用,免去了繁瑣的DOM操做。
jQuery:極大地簡化了 JavaScript 編程,寫的少,作的多。
Bootstrap:提供了功能強大的、易於定製的組件,使得 Web 開發更加快捷。
Less:簡化了CSS的編寫,同時又擴充了CSS語言(變量、嵌套、運算)。
RequireJS:實現模塊化開發,提升代碼的加載速度和質量。
對URI編碼,以便發送給瀏覽器。(由於有效的URI中不能包含某些字符,例如空格。)
encodeURI()主要用於對整個URI編碼,encodeURIComponent()主要用於對URI中的某一段編碼。
encodeURI()不會對自己屬於URI的特殊字符編碼,例如冒號、正斜槓、問號和井字號,encodeURIComponent()則會對全部非標準字符編碼。
異步模塊定義。要用define函數來定義模塊。
1) 好的IDE,好比VS Code
2) 好的插件,好比Emmet、GitLens、Less
3) 好的調試工具,好比Chrome
4) 模塊化、組件化
5) 先後端分離
6) 遵照代碼規範
em:相對單位,好比,2em表示是當前元素(或者說父元素,由於 當前元素的字體是繼承自父元素的)的字體大小2倍。
rem:相對單位,工做方式和em相同,只不過它是相對於默認基礎字體的大小
百分比:相對單位,參照物有點複雜,好比:width、padding、margin、left、right相對於父元素的width,height、top、bottom相對於父元素的height,font-size相對於父元素的font-size
1) slice()、concat()、Array.from()、[…array]、map()(都是淺複製)
2) JSON(弊端:數組中的項若是是undefined,那麼轉換後將變爲null;若是數組的項爲對象,那麼對象之間不可相互引用,不然會形成循環引用,沒法JSON序列化而報錯。)
a
由於解釋分兩個階段,第一個階段是預解釋(把變量和函數聲明提高),第二個階段才一行行執行代碼
解析(解釋)以後才能執行
function knapsack(weights, values, capacity) {
var arr2d = [];
for (var i = 0; i < weights.length; i++) {
arr2d[i] = [];
}
for (var i = 0; i < weights.length; i++) {
for (var j = 0; j <= capacity; j++) {
if (i === 0) {
arr2d[i][j] = j < weights[i] ? 0 : values[i];
} else {
if (j < weights[i]) {
arr2d[i][j] = arr2d[i - 1][j];
} else {
arr2d[i][j] = Math.max(arr2d[i - 1][j], arr2d[i - 1][j - weights[i]] + values[i]);
}
}
}
}
return arr2d[weights.length - 1][capacity];
}
console.log(knapsack([2, 2, 6, 5, 4], [6, 3, 5, 4, 6], 10))
編譯型語言:程序在運行前須要用編譯器編譯,轉換成機器代碼(彙編語言或目標機器的目標代碼);程序運行效率通常比較高。
解釋型語言:程序在運行前不須要編譯,在運行時用解釋器邊解釋成機器代碼邊運行;程序運行效率通常比較低。
1) TCP面向鏈接,UDP面向非鏈接
2) TCP提供可靠的傳輸,UDP提供不可靠的傳輸
3) TCP速度慢,UDP速度快
4) TCP首部開銷大(至少20個字節),UDP開銷小(8個字節)
5) TCP有擁塞控制,UDP沒擁塞控制
6) TCP只支持一對一,UDP支持一對1、一對多、多對1、多對多
7) TCP面向字節流(即TCP對應用層交下來的報文,可能合併,也可能拆分,根據對方給出的窗口值和網絡擁塞程度),UDP面向報文(即UDP對應用層交下來的報文,既不合並,也不拆分,而是保留這些報文的邊界)
應用進程自己能夠在不影響實時性的前提下,增長一些提升可靠性的措施,好比重傳已丟失的報文。
1) JSON
限制:
a) 須要深複製的對象不能存在循環引用,即不能像下面那樣
var a = {};
a.b = a;
b) 對象中值爲undefined的屬性會消失;對象中的方法會被無視掉;自定義的原型鏈中斷,[[Prototype]]都指向Object.prototype
c) 數組中的undefined項會變成null
d) 不能複製函數(對函數用JSON.stringify()返回的是undefined,而對undefined用JSON.parse()會報錯)
e) 不能複製undefined(對undefined用JSON.stringify()返回的是undefined)
2) 遞歸
function deepCopy(obj) {
var newObj = Array.isArray(obj) ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
}
}
return newObj;
}
PS:沒有考慮函數、正則表達式、日期等特殊狀況,原型也沒考慮
方法一:
function f(i) {
setTimeout(function () {
console.log(i);
if (i < 9) {
f(i + 1);
}
}, 1000);
}
f(0);
方法二:
for (var i = 0; i < 10; i++) {
(function (i) {
setTimeout(function () {
console.log(i);
}, i * 1000);
})(i)
}
PS:全部實例最終都繼承自Object,而Object.prototype裏有valueOf()和toString(),爲何會出現對象沒有這兩個方法的狀況?由於能夠在對象上定義同名的方法屏蔽原型鏈上的方法。
Host Connection User-Agent Accept-Language Cookie Content-Type If-Modified-Since If-None-Match Origin Referer
常見的響應頭字段?
Location Set-cookie Content-Type Expires Cache-Control Last-Modified Etag
Access-Control-Allow-Origin
淺複製只複製一層(注意與賦值不一樣),深複製全部層級都會複製。
內存泄漏:再也不用到的內存,沒有及時釋放
發生內存泄露的狀況:
1) 再也不須要的全局變量
2) 再也不須要的對象的屬性或方法
3) 閉包:閉包的做用域鏈引用着外部函數的做用域,假設外部函數的做用域有變量a和變量b,而閉包只用到了變量a,這樣,雖然閉包沒用到變量b,但b佔用的內存也不能獲得釋放,因而就發生了內存泄露
4) IE9之前的IE,循環引用會致使內存泄露,由於它們的垃圾收集策略是引用計數
5) 若是使用innerHTML替換頁面中某一部分的時候,把帶有事件處理器的元素刪除了,那這個事件處理器可能沒法被看成垃圾回收,要看瀏覽器
6) 若是在頁面被卸載(unload)(包括在兩個頁面間來回切換或刷新)以前沒有清理乾淨事件處理器,那它們就可能會滯留在內存中,要看瀏覽器。
function EventEmitter() {
this.events = {};
this.on = function (eventNmae, f) {
this.events[eventNmae] = f;
};
this.emit = function (eventNmae) {
if (this.events[eventNmae]) {
this.events[eventNmae](...Array.from(arguments).slice(1));
}
}
this.off = function (eventNmae) {
delete this.events[eventNmae];
}
}
PS:Array.from(arguments).slice(1)也能夠換成Array.prototype.slice.call(arguments, 1)
/^[\w-]+(\.[\w-]+)*@[A-Za-z0-9]+(\.[A-Za-z]+)+$/
能夠用location.search:
function getQueryStringArgs() {
var qs = decodeURIComponent(location.search.slice(1)),
res = {},
items = qs ? qs.split('&') : [];
for (var i = 0; i < items.length; i++) {
var item = items[i].split('=');
res[item[0]] = item[1];
}
return res;
}
傳入URL做爲參數:
function getQueryStringArgs(url) {
var begin = url.indexOf('?') === -1 ? url.length : url.indexOf('?') + 1,
end = url.indexOf('#') === -1 ? url.length : url.indexOf('#');
var qs = decodeURIComponent(url.slice(begin, end)),
res = {},
items = qs ? qs.split('&') : [];
for (var i = 0; i < items.length; i++) {
var item = items[i].split('=');
res[item[0]] = item[1];
}
return res;
}
————————————————aaa——————————————————
筆試
Hybrid App是指介於Web App和Native App之間的App,兼具「Native App良好用戶交互體驗的優點」和「Web App跨平臺的優點」。
優點:開發成本低、維護簡單、跨平臺。
劣勢:基本沒有,硬要說,就是交互體驗差一點,網費貴一點,速度慢一點(受限於網速)。
A、箭頭函數能夠使用 yield
B、 箭頭函數不能夠用做構造函數
C、 不會改變 this 的指向
D、箭頭函數是 Function 的實例
E、 箭頭函數函數體沒有花括號能夠作爲返回值
F、 內部不能訪問到 arguments 對象
<div id="div2">
<div id="div1">點我</div>
</div>
var div2 = document.getElementById('div2');
var div1 = document.getElementById('div1');
div1.addEventListener('click', function (event) { console.log("A"); }, true);
div2.addEventListener('click', function (event) { console.log("B"); });
div1.addEventListener('click', function (event) { console.log("C"); }, false);
div2.addEventListener('click', function (event) { console.log("D"); }, true);
A、A B C D
B、D A C B
C、A D B C
D、D C A B
E、B D A C
IE:Trident
FireFox:Gecko
Safari:Webkit
Chrome和Opera:Blink
Edge:EdgeHTML
1) opacity(佔據空間,可響應交互)
2) visibility(佔據空間,不響應交互)
3) display(不佔據空間,不響應交互)
4) position
1) 把img元素的display設爲block
2) 把img元素的vertical-align設爲bottom或middle
3) 把img元素的父元素的line-height設爲0(line-height即top 和 bottom 之間的值)
4) 把img元素的父元素的font-size設爲0(line-height 的默認值是基於 font-size 的)
1) 動態建立<script>
2) onload事件
3) XHR+eval:經過 ajax 獲取js的內容,而後 eval 執行
4) <script>的defer、async屬性
混雜模式下瀏覽器的行爲不符合標準,做用是向後兼容舊的網站,不一樣瀏覽器在混雜模式下的行爲差別很是大;標準模式會讓瀏覽器的行爲更接近標準。
1) margin在border外,padding在border內
2) 元素的背景在padding中顯示,但不能在margin中顯示
3) 不一樣元素之間的margin會發生外邊距塌陷,即兩個相鄰margin只會取最大的那個,而不一樣元素之間的padding不會互相影響
4) 能夠給margin設置負值,而padding設置負值沒用。
var a = 1;
(function(window) {
console.log(a);
console.log(window.a);
})({a: 2})
function Person(name) {
this.name = name;
}
Person.prototype.name = 'default'
Person.prototype.getName = function () {
return this.name;
}
var li = new Person('li')
for (var prop in li) {
console.log(prop)
}
var lowerCase = /^[a-z]+$/
console.log(lowerCase.test(null), lowerCase.test())
true true
var a = [0, 1, 2],
b = '0,1,2'.split(',');
console.log(a == b);
console.log(a === b);
false
false
點我達筆試
單選題
不定向選擇題
簡答題
console.log(1);
setTimeout(function () {
console.log(2);
}, 0);
Promise.resolve().then(function() {
console.log(3);
});
console.log(4);
function f(a) {
var ret = [];
while (a.length) {
var n = Math.floor(Math.random() * a.length);
ret.push(a.splice(n, 1)[0]);
}
return ret;
}
l append(num):往鏈表尾部插入數字num
l prepend(num):往鏈表頭部插入數字num
l delete(num):刪除鏈表中值爲num的全部項,並返回刪除的項的數量
function LinkList() {
this.a = [];
this.append = function (x) {
this.a.push(x);
};
this.prepend = function (x) {
this.a.unshift(x);
}
this.delete = function (x) {
var n = 0;
this.a = this.a.filter(function (item, index, a) {
if (item === x) {
n++;
return false;
} else {
return true;
}
});
return n;
}
}
Teambition筆試
單選題
setTimeout(() => {
console.log(1);
}, (100));
Promise.resolve().then(function() {
console.log(2);
})
setTimeout(() => {
console.log(3);
});
console.log(4);
多選題
填空題
編程題
function f(n) {
if (n < 10) {
return -1;
}
a = ('' + n).split('');
for (var i = a.length - 1; i > 0; i--) {
if (a[i] > a[i - 1]) {
[a[i], a[i - 1]] = [a[i - 1], a[i]];
return + a.join('');
}
}
return -1;
}
function f(n) {
var second = n % 60;
n = (n - second) / 60;
var minute = n % 60;
n = (n - minute) / 60;
var hour = n % 24;
n = (n - hour) / 24;
var day = n % 365;
n = (n - day) / 365;
var year = n;
var a = [year, day, hour, minute, second];
var a2 = ['year', 'day', 'hour', 'minute', 'second'];
var res = '';
a.forEach(function (item, i, array) {
if (item > 0) {
var temp = item + ' ' + (item === 1 ? a2[i] : a2[i] + 's');
temp += ', ';
res += temp;
}
});
res = res.slice(0, -2);
var index = res.lastIndexOf(',');
if (index !== -1) {
res = res.slice(0, index) + ' and' + res.slice(index + 1);
}
return res;
}
輸出?
true true。由於Number(true)返回1,Number(false)返回0
攜程筆試
單選題(幾乎全是牛客網專項訓練裏的題)
編程題
function f(n) {
for (var i = 2; i < n / 2 + 1; i++) {
if (n % i === 0) {
return false;
}
}
return true;
}
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<title>攜程編程題第3題</title>
<style>
div {
border: solid;
position: absolute;
width: 40px;
height: 40px;
text-align: center;
line-height: 40px;
transition: 0.5s;
}
</style>
</head>
<body>
<script>
// 若是有重複的數字就會出BUG
// 初始化
var arr = [];
for (var i = 0; i < 10; i++) {
arr.push(Math.floor(Math.random() * 100));
}
var frag = document.createDocumentFragment();
for (var i = 0; i < arr.length; i++) {
var div = document.createElement('div');
div.textContent = arr[i];
div.style.left = 50 * i + 'px';
div.id = 'div' + arr[i];
frag.appendChild(div);
}
document.body.appendChild(frag);
// 排序
var count = 0;
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
count++;
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
setTimeout(function (j, arr) {
return function () {
document.querySelector('#div' + arr[j + 1]).style.left = 50 * (j + 1) + 'px';
document.querySelector('#div' + arr[j]).style.left = 50 * j + 'px';
}
}(j, arr.slice()), 500 * count);
}
}
}
</script>
</body>
</html>
多益網絡筆試
單選、填空題
var b = new Array(3);
var c = b.forEach(item => item +1);
var b = Array.apply(null, Array(3));
var c = b.map(item => item + 1);
var a = new Array(1024);
a[0102] = 3;
function fun3() {
console.log('fun3')
}
function fun2() {
fun3();
}
function fun1() {
fun2();
}
fun1();
var a = b = 1;
(function() {
console.log(a + ", " + this.b);
var a = 2;
})()
console.log(3)
}
console.log(a);
var a = 1;
var a = function() {
console.log(2)
}
function a() {
console.log(3)
}
JPG:照片
PNG:須要透明背景時
SVG:數據可視化(由於能夠用JavaScript操縱)
解析:在html裏追加的僞元素是位於標籤內的(國內不少網站的翻譯是「在元素前/元素後追加僞元素」,是錯的),因此不能內嵌元素的元素都不能添加僞元素。
簡答題
localStorage和sessionStorage是Web Storage API,瀏覽器經過它在本地存儲鍵值對。
localStorage用法:
1) 添加或更新數據項:localStorage.setItem('myCat','Tom');,
2) 讀數據項:var cat = localStorage.getItem('myCat');,
3) 移除數據項:localStorage.removeItem('myCat');或localStorage.clear();,後者不接受參數,只是簡單地清空域名對應的整個存儲對象。
div {
height: 0;
width: 0;
border-top: 100px solid transparent;
border-right: 100px solid transparent;
border-left: 100px solid transparent;
border-bottom: 100px solid green;
}
PS:若是要畫扇形,就再加個border-radius: 100px;
有length屬性的對象,能夠用方括號並提供基於0的數字索引來訪問成員,但沒有數組的方法。
Array.prototype.slice.call()、Array.prototype.concat.call()、Array.from()均可以把僞數組轉化爲數組;前二者把Array.prototype換爲[]或把call換成apply也行。
阿里筆試
a: 1,
b: [ 1, 2, { c: true }, [ 3 ] ],
d: { e: 2, f: 3 },
g: null,
}
function flatten(input) {
var ret = {};
function f(input, previousItem) {
for (var item in input) {
if (input[item] === null || input[item] === undefined) {
} else {
if (typeof input[item] === 'object') {
if (Array.isArray(input[item])) {
f(input[item], previousItem + (previousItem ? '[' : '') + item + (previousItem ? ']' : ''));
} else {
if (Array.isArray(input)) {
f(input[item], previousItem + (previousItem ? '[' : '') + item + (previousItem ? ']' : ''));
} else {
f(input[item], previousItem + (previousItem ? '.' : '') + item);
}
}
} else {
if (Array.isArray(input)) {
ret[previousItem + (previousItem ? '[' : '') + item + (previousItem ? ']' : '')] = input[item];
} else {
ret[previousItem + (previousItem ? '.' : '') + item] = input[item];
}
}
}
}
}
f(input, '');
return ret;
}
1) 依賴全局變量,全部的編譯單元都載入一個公共全局對象中,程序越大,全局變量越難管理。新特性的解決辦法:ES6模塊。
2) 沒有塊級做用域。新特性的解決辦法:let,const。
3) 自動插入分號,有時它會不合時宜地插入分號。個人解決辦法:不期望它,始終手動加分號。
4) typeof null返回'object'。個人解決辦法:用my_value === null來檢測null。
5) 若是傳入parseInt()的字符串第一個字符是0,那麼該字符串會基於八進制而不是十進制來求值。個人解決辦法:始終給parseInt()傳入第二個參數。
6) 加法操做符的複雜行爲是bug的常見來源。個人解決辦法:作數學加法前確保兩個運算數都是數字。
7) 0.1+0.2不等於0.3。個人解決辦法:作浮點數的加法前先經過乘個10的n次方把浮點數變成整數,作完加法後再除以這個10的n次方。
8) typeof NaN === 'number' 返回true,因此沒有現成的函數來判斷一個值是否能用來作數學運算。個人解決辦法:判斷typeof value === 'number' && isFinite(value)(這樣還排除了Infinity)
9) 數組不是真正的數組,性能可能比真正的數組糟糕。
10)==和!=運算符會轉換值的類型,而轉換的規則又複雜又難記,==還缺少傳遞性(0 == '0'且0 == ''但'0' != '')。個人解決辦法:不用==和!=。
11)with語句。個人解決辦法:不用它。
12)eval()函數、Function構造函數、接受字符串參數時的setTimeout()和setInterval(),下降性能、安全性。個人解決辦法:不用它們。
13)能夠訪問基本包裝類型Boolean、Number和String是徹底不必的。個人解決辦法:不用它。
三七互娛筆試
function Hero(str) {
var o = {
time: 0,
kill: function (num) {
if (this.time === 0) {
console.log('Kill ' + num + (num > 1 ? ' bugs;' : ' bug;'));
} else {
setTimeout(() => {
console.log('Kill ' + num + (num > 1 ? ' bugs;' : ' bug;'));
}, this.time);
this.time = 0;
}
return this;
},
recover: function (num) {
console.log('Recover ' + num + ' bloods;');
return this;
},
sleep: function (num) {
this.time = num * 1000;
return this;
}
};
console.log('Hi! This is ' + str + '!');
return o;
}
虎牙筆試
for (var i = 0; i < 2; i++) {
}
貓眼一面
應用層、表示層、會話層、運輸層、網絡層、數據鏈路層、物理層。HTTP在應用層,TCP、UDP在運輸層,IP在網絡層。
function mergeArray(a, b) {
var c = [],
length1 = a.length,
length2 = b.length;
for (var i = 0, j = 0; i < length1 && j < length2;) {
if (a[i] < b[j]) {
c.push(a[i]);
i++;
} else {
c.push(b[j]);
j++;
}
}
while (i < length1) {
c.push(a[i]);
}
while (i < length1) {
c.push(b[j]);
}
return c;
}
虎牙一面
1) Array.isArray(obj)
2) Object.prototype.toString.apply(obj) === '[object Array]'
3) instanceof
第四範式一面
div {
height: 0;
width: 0;
border-top: 100px solid transparent;
border-right: 100px solid transparent;
border-left: 100px solid yellow;
border-bottom: 100px solid transparent;
border-radius: 100px;
}
第四範式二面
function f(str) {
var arr = str.toLowerCase().slice(0, -1).split(/[\s,\.]+/),
ret = {};
for (var i = 0; i < arr.length; i++) {
if (ret.hasOwnProperty(arr[i])) {
ret[arr[i]]++;
} else {
ret[arr[i]] = 1
}
}
for (var key in ret) {
if (ret[key] === 1) {
delete ret[key];
}
}
return ret;
}
var x = 1;
var objA = {
x: 2,
fn: function () {
console.log(this.x);
}
};
var objB = {
x: 3,
fn: objA.fn
}
objA.fn.call(objB);
objB.fn();
var fn = objB.fn;
fn();
function fnA(options) {
this.x = options.x;
}
fnA.prototype.y = 3;
fnA.prototype.print = function () {
console.log(this.x, this.y);
}
var options = {
x: 1,
y: 2
}
var A1 = new fnA(options);
options.x = 3;
A1.print();
fnA.prototype.y = 1;
A1.print();
var obj1 = {
x: 1
};
var num1 = 1;
var array1 = [obj1, num1];
obj1 = {
x: 2
};
num1 = 2;
console.log(array1[0].x, array1[1]);
var array2 = array1;
obj1.x = 3;
array1[1] = 3;
console.log(array2[0].x, array2[1]);
var stack1 = [],
stack2 = [];
function push(node)
{
return stack1.push(node);
}
function unshift()
{
if (stack2.length === 0) {
while (stack1.length) {
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
京東筆試
用友筆試
1) display: none
2) visibility: hidden
3) opacity: 0
4) 用定位把元素移動屏幕外
PS:特性(Attribute)雖然是節點,但不被認爲是DOM文檔樹的一部分
BIGO筆試
斐波那契
Unicode對世界上大部分的文字系統進行了整理、編碼,使得計算機能夠用更爲簡單的方式來呈現和處理文字。 UTF-八、UTF-1六、UTF-32是Unicode的 實現,它們之間的區別主要是表示一個字符的字節數不一樣
圖森將來一面
1) 用viewport元標籤,一個典型的針對移動端優化的站點包含相似下面的內容:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
width控制視口的寬度,能夠像width=600這樣設爲確切的像素數,或者設爲device-width這一特殊值來指代比例爲100%時屏幕寬度的CSS像素數值。initial-scale屬性控制頁面最初加載時的縮放等級。maximum-scale、minimum-scale及user-scalable(值yes 或no,若果設置爲no,用戶就不能縮放頁面,默認值是yes)屬性控制容許用戶以怎樣的方式放大或縮小頁面。
2) 使用相對單位,好比百分比、em、rem、vw、vh
3) 使用浮動
4) 用媒體查詢根據屏幕寬度選擇不一樣的CSS(<link>的media屬性和CSS的@media規則)
5) 根據屏幕大小加載不一樣的圖片(srcset、SVG(爲不一樣分辨率屏幕提供不一樣分辨率的圖片)和<picture>(爲不一樣佈局提供不一樣剪裁的圖片))
1) 打開多幾個別的頁面,看慢不慢,若是都慢,那可能就是網絡的問題
2) 若是就這個頁面慢,那就打開谷歌瀏覽器的開發者工具,查看network或performance的狀況
3) 考慮緩存的設置合不合理
在用戶點擊播放視頻以前,不要預加載視頻。(把<video>的preload設爲none)
堆排序。把數據構形成一個最大堆,取出堆頂,把剩下的數據從新構形成一個最大堆,再取出堆頂,如此重複K次。
用下標或get方法
金山WPS筆試
function f1() {
var n = 99;
nAdd = function() {
n += 1;
};
function f2() {
console.log(n);
}
return f2;
}
var result = f1();
result();
nAdd();
result();
var div = document.querySelector('div');
div.style.transition = '1s';
div.style.transform = 'rotate(0)';
setTimeout(function () {
div.style.transform = 'rotate(45deg)';
setTimeout(function () {
div.style.transition = '10s';
div.style.transform = 'translate(' + 500 / Math.SQRT2 + 'px,' + (- 500 / Math.SQRT2) + 'px) rotate(45deg)';
}, 1500);
}, 0);
PS:transition的初始和結束狀態都要在JS裏指定才能生效,並且結束狀態要放在setTimeout裏
宜信筆試
多益網絡一面
我不以爲它有什麼缺點
動態(由於有交互)
三七互娛一面
沒出如今視野中的圖片的src屬性用很是小的圖片,把圖片的真實路徑保存在一個自定義屬性中,用JS監聽圖片的位置,當圖片出如今視野中時,就把src換成真實路徑。
迅雷筆試
var x = 1;
var output = (function() {
delete x;
return x;
})();
解析:在window上直接定義的屬性能夠被delete刪除,在全局做用域用var聲明的變量不能夠(雖然它也會變成window的屬性)
function foo() {
let print;
for (let i = 0; i < 3; i++) {
if (i === 2) {
print = function() {
return i;
};
}
}
console.log(print());
}
foo();
if (10 > 9 > 8 == true) {
console.log('html5');
}else {
console.log('css3');
}
搜狐筆試
var reachNumber = function(target) {
if (target < 0) {
return reachNumber(-target);
}
for (var i = 0; (1 + i) * i / 2 < target; i++) {
}
if ((1 + i) * i / 2 === target) {
return i;
} else {
if (((1 + i) * i / 2 - target) % 2 === 0) {
return i;
} else {
if (i % 2 === 0) {
return i + 1;
} else {
return i + 2;
}
}
}
};
搜狗筆試
1) 遞歸 + push + …/concat
function f(arr) {
var res = [];
for (var i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
// res = res.concat(f(arr[i]));
res.push(...f(arr[i]));
} else {
res.push(arr[i]);
}
}
return res;
}
2) 遞歸 + reduce + concat
function f(arr) {
return arr.reduce(function (acc, cur) {
return acc.concat(Array.isArray(cur) ? f(cur) : cur);
}, []);
}
3) arr.toString().split(',')(針對數字數字)
歡聚時代筆試
1) 事件(包括Ajax)
2) 定時器
3) Promise
for循環優於forEach優於map
5(58的8被無視掉了,由於是看成八進制數解析)
1) 函數聲明
2) 函數表達式
3) Function構造函數
百度筆試
0 + 0 - (-1) + 0.5 = 1.5
function output(str) {
var content = document.querySelector('.content');
var blink = document.querySelector('.blink');
while (content.children.length !== 1) {
content.children[0].remove();
}
for (var i = 0; i < str.length; i++) {
(function (i) {
setTimeout(function () {
if (str[i] === '\n') {
content.insertBefore(document.createElement('br'), blink);
} else {
var span = document.createElement('span');
span.textContent = str[i];
span.className = 'word color' + Math.floor(Math.random() * 24);
content.insertBefore(span, blink);
}
}, 200 * (i + 1));
})(i)
}
}
output('hello world\n你好世界');
function Women(name) {
this.name = name;
}
function Men(name) {
this.name = 'yy1';
}
Object.defineProperty(Women, 'name', {
configurable: true,
enumerable: false,
set: function() {
name = 'yy2';
},
get: function() {
return 'yy3'
}
});
Women.prototype = new Men();
var a = new Women();
var b = new Men();
順豐筆試
1) 對方沒有正常工做
2) 對方不理睬外界發送過來的這種報文
3) 沒有連網
var user = {
count: 1,
get: function() {
return this.count;
}
}
var f = user.get;
console.log(f());
function compare(t1, t2) {
var t1 = new Date(t1);
var t2 = new Date(t2);
if (t1 == 'Invalid Date' || t2 == 'Invalid Date') {
return 0;
} else {
var ret = Math.abs(t1 - t2) / 1000 / 60 / 60;
var int = Math.floor(ret);
var float = ret - int < 0.5 ? 0 : 0.5;
return int + float;
}
}
function compare(str, str1) {
var s = str + str1;
var a = s.split('');
var o = {};
a.forEach(function (item, index, a) {
if (o[item]) {
o[item]++;
} else {
o[item] = 1;
}
});
a = a.filter(function (item, index, a) {
return o[item] === 1 ? true : false;
});
a.sort();
var a2 = a.slice().reverse();
var s1 = a.join('');
var s2 = a2.join('');
return s1 + s2;
}
<label><input type="checkbox">記住我</label>
網易遊戲筆試
1. 768x1024分辨率的32位色彩的位圖的存儲空間:768*1024*32/8字節
2. 設有一個用數組Q[1..m]表示的環形隊列,約定f爲當前隊頭元素在數組中的位置,r爲隊尾元素的後一位置(按順時針方向),若隊列非空,則計算隊列中元素個數的公式應爲(A)
3. n個元素出棧多少種可能:f(n) = f(0)*f(n-1) + f(1)*f(n-2) + ... + f(n-1)*f(0),f(0)設爲1
4. Cookie是瀏覽器的概念,服務器不存儲Cookie
前者:在讀取屬性時調用,負責返回有效的值
後者:在寫入屬性時調用,並會把新值傳進去
Shopee筆試
用組合
var line = readline();
var x = + line.split(' ')[0];
var y = + line.split(' ')[1];
var n = 1;
for (var i = x + y, j = 0; j < x; i--, j++) {
n *= i;
}
var d = 1;
for (var i = x; i >= 1; i--) {
d *= i;
}
console.log(n / d);
惟品會筆試
新浪筆試
W3C,World Wide Web Consortium,萬維網聯盟,HTML、CSS、DOM標準都是由它制定的。
Block Formatting Context,塊級格式化上下文,包含建立它的元素的全部東西,它對浮動和清除浮動很重要。浮動和清除浮動只會應用在同一個BFC裏的元素上。浮動不會影響別的BFC裏的元素的佈局,清除浮動只能清除同一個BFC中在它前面的元素的浮動。外邊距塌陷也只會發生在同一個BFC中的塊級元素之間。
Progressive Web Apps,漸進式Web應用
騰訊筆試
微衆筆試
A. content
B. charset
C. http-equiv
D. scheme
const f = (b,...a)=>a+b;
console.log(f(2));
輸出'5'(錯, 輸出'2',由於[] + 2的結果是'2'([]會先調用toString()轉爲''),console.log(f(2, 1, 3))輸出1,32'')
解析:fill() 方法用一個固定值填充一個數組中從起始索引到終止索引內的所有元素。不包括終止索引。
let y = 0.3 - 0.2;
let z = 7;
let obj = {a: 10};
change(obj);
change(z);
function change(obj) {
if (obj instanceof Object) {
if (y === 0.1) {
obj.a = 8;
} else {
obj = {t: 'mumble'};
}
} else {
obj = 9;
}
}
var a = 2;
var obj = {
b: 3
};
function foo(str) {
'use strict';
eval(str);
}
function boz(data, param) {
with(data) {
c = param;
}
}
foo('var a = 4;');
if (obj.b < a) {
boz(obj, true);
} else {
boz(obj, false);
}
Shopee一面
let test = {
a: 1
};
Object.defineProperties(test, {
b: {
get: function() {
return 1;
}
}
});
let my = JSON.parse(JSON.stringify(test));
console.log(my.b);
解析:數據屬性和訪問器屬性的[[Enumerable]]要爲true,才能被這種方式複製
能夠,遍歷的是數組的下標(也是按順序的)
V8那麼快,確定是用C++啦
網易遊戲一面
AMD推崇依賴前置,即在定義模塊的時候就要聲明其依賴的模塊;
CMD推崇就近依賴,即只有在用到某個模塊的時候再去require
一次性更新大量的對DOM的操做,而不是每操做一次DOM就更新一次。
用vw或vh單位(vw,視口寬度的百分之一;vh,視口高度的百分之一)
沒有
CSS預處理器
MVVM是一種軟件架構模式,有助於將數據和視圖分離。M,model,數據;V,view,視圖,這二者經過VM,viewmodel關聯起來,使view的變化能同步到model,model的變化能同步到view
不知道,我就把代碼拉下來,而後開發,開發了一些了,就推上去。
用友二面
若是加載指的是下載JS文件,那隻能經過把<script>放<body>底部
會。
Teambiton一面
1) translate能夠用GPU加速
2) translate不會引發重排(會引發重繪)
3) translate不會引發offsetLeft、offsetTop的改變
重排重繪太頻繁
1) 前者不須要本身設置時間間隔(在下一次重繪以前執行代碼(每秒60次,和顯示器的刷新頻率對應)),後者須要
2) 後者不精確,由於它不能保證時間到了後必定會執行相應的代碼(一方面是因爲事件循環的問題,另外一面是因爲瀏覽器的計時器精度的問題)
新增二進制分幀層
運滿滿筆試
Function.prototype.bind = function (context) {
var that = this;
return function () {
return that.apply(context, arguments);
};
}
網易遊戲二面
text/html、text/css、text/ javascript、application/json
HTTPS
把上一個節點和下一個節點都存起來,讓當前節點指向上一個節點,把當前節點存進「上一個節點」,把下一個節點存進「當前節點」
var arr = [];
for (var i = 0; i < 10; i++) {
arr[i] = function () {
console.log(i);
};
}
(function () {
for (var i = 0; i < 10; i++) {
arr[i]();
}
})()
JS數組不是真正的數組,本質上是Object,只不過多了length屬性和一些方法,並對用非負整數下標訪問作了優化。它的長度不是固定的。它的每一項不必定連續,取決於使用它的方式以及用的JS引擎是什麼。若是是現代JS引擎,當一個數組的每一項的類型都相同,那這個數組就是連續的。
都很快嗎?那多是當數組不連續時,用了哈希算法
流利說一面
key和存儲地址有映射關係。
HTTP/1.1使用了持久鏈接(持久鏈接又有兩種工做方式:非流水線式和流水線式)。(這是最主要的區別,別的區別都是無傷大雅的,由於咱們的計算機網絡教材上提到的區別就只有這一個。HTTP/1.1都是上個世紀的東西了。)
爲相互通訊的應用進程提供邏輯通訊。
主機遞歸查詢(即替主機繼續查詢)本地域名服務器,本地域名服務器迭代查詢根域名服務器、頂級域名服務器和權限域名服務器。
TCP擁塞控制的算法有4種:慢開始、擁塞避免、快重傳和快恢復。
1) 擁塞窗口初始值爲1,在執行慢開始算法時,發送方每收到一個確認就把擁塞窗口加1,而後開始下一輪傳輸,所以擁塞窗口隨着傳輸輪次按指數規律增加。
2) 當擁塞窗口增加到慢開始門限時,就改成執行擁塞避免算法,擁塞窗口改成線性增加。
3) 當網絡出現超時,發送方就判斷爲網絡擁塞,因而調整慢開始門限爲原來的一半,同時設置擁塞窗口爲1,從新執行慢開始算法。
4) 根據快重傳算法(針對個別報文段的丟失),當發送方一連收到3個重複確認,當即進行重傳,並執行快恢復算法,調整擁塞窗口爲原來的一半,並讓慢開始門限等於擁塞窗口,因而開始執行擁塞避免算法
二進制分幀層並不直接提升性能,它改變了瀏覽器與服務器交換數據的方式,以二進制編碼幀的形式交換數據,這是HTTP/2全部其它性能提升的基礎。
堆:存放引用類型的值;垃圾收集就是檢查這裏
棧:存放基本類型的值;JS主線程的函數執行,都壓到這裏
當初我在MDN,一個前端開發者社區,學習前端,這是其中的一個做業。
不必定。HTTP/1.0默認都要,從HTTP/1.1開始默認就使用持久鏈接(長鏈接)了。
10. HTTP/1.0怎麼實現持久鏈接?
瀏覽器在請求頭加上值爲Connection: keep-alive,服務器收到請求後,在響應頭中也加上加上值爲Connection: keep-alive字段。
HTTP/1.1默認啓用持久鏈接,要關閉,用Connection: close(這也是HTTP/1.0的默認值)
11. TCP是怎麼實現可靠傳輸的?
1) 當出現差錯時重傳出現差錯的數據
2) 接收方來不及處理收到的數據時,發送方要下降發送數據的速度
12. 中止等待協議傳輸效率低,怎麼辦?
不使用中止等待協議,而採用流水線傳輸;發送方可連續發送多個分組,沒必要每發完一個分組就停頓下來等待對方的確認,這樣可以使信道上一直有數據不間斷地在傳送。
13. 使用流水線傳輸時,要使用什麼協議?
滑動窗口協議。
14. 發送窗口裏有什麼東西?
1) 已發送但未收到確認的字節數
2) 容許發送但當前還沒發送的字節數(可用窗口)
15. Cookie是怎樣工做的?
1) 當一個用戶瀏覽某個使用Cookie的網站時,該網站的服務器就爲這個用戶產生一個惟一的識別碼,Cookie,並以此做爲索引在數據庫中產生一個項目。接着在給用戶的HTTP響應的響應頭中添加一個Set-cookie的字段,值就是Cookie。
2) 當用戶收到這個響應時,瀏覽器就在它的Cookie文件中添加一行,其中包括Cookie和這個服務器的域名。當用戶繼續瀏覽這個網站時,每發送一個HTTP請求,瀏覽器就會從它的Cookie文件中取出這個網站的Cookie,並放到HTTP請求的請求頭中的Cookie字段。
3) 因而,這個網站就可以跟蹤這個用戶在這個網站的活動。
16. Cookie的缺點?
1) 能存放的數據的大小有限,只有4K
2) 瀏覽器每次發送HTTP請求都會攜帶Cookie,若是Cookie中保存的數據過多會帶來性能問題
3) Cookie在JS中的接口很差用
4) 用戶隱私可能會被泄露
17. 爲何HTTP/2能夠多路複用而HTTP/1.x不能夠?
由於HTTP/1.x是基於文本的,在一個TCP鏈接中,數據必須按順序發送,不然接收方就識別不了;而HTTP/2是基於二進制的,每一個二進制幀都有個序號,從而能夠不按順序發送。
18. HPACK原理?
瀏覽器和服務器分別有一個字典,它們字典是相同的,壓縮的原理就是把頭部中的鍵值對用字典中更短的字符表示
搜狐一面
function elementInViewport(el) {
var top = el.offsetTop;
var left = el.offsetLeft;
var width = el.offsetWidth;
var height = el.offsetHeight;
while(el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;
}
console.log(top + height)
return (
top < (window.pageYOffset + window.innerHeight) &&
left < (window.pageXOffset + window.innerWidth) &&
(top + height) > window.pageYOffset &&
(left + width) > window.pageXOffset
);
}
var img = document.querySelector('img');
document.addEventListener('mousewheel', function () {
if (elementInViewport(img)) {
img.src = 'test.jpg';
}
});
Node Package Manager,node包管理器。
若是要比較的兩個操做數的數據類型不一樣,相等操做符會在比較以前轉換操做數的數據類型;全等操做符不會。
金山WPS一面
link visited focus hover active first-child first-of-type nth-child() nth-of-type()
after before first-letter first-line
調用一個同步過程後,在返回結果以前,處於阻塞狀態,只有在返回結果後,調用者才能夠繼續作其它的事情
調用一個異步過程後,不會阻塞,調用者能夠繼續作其它事情,等返回結果後再通知調用者。
若是是我本身練手的項目,會用的,並且我會盡量用這些語義化的元素而不是div、span這些;但我在實習時作的項目,就沒用到了,由於個人同事都不用
OYO筆試
順豐科技面試準備
1) link標籤的href屬性
2) a標籤的href屬性
3) img標籤的src屬性
4) script標籤的src屬性
5) Ajax
6) 表單
順豐科技一面
JS具有與瀏覽器窗口及其內容等幾乎全部方面交互的能力
Momenta一面
1) SVG(全程是可縮放矢量圖形)是矢量圖,canvas是標量圖
2) SVG是基於XML的,canvas屬於HTML
返回Promise對象的話,就由這個Promise對象接管後面的鏈;
返回普通對象的話,會把這個普通對象做爲參數傳入下一個then
外層的Promise的狀態由內層的Promise的狀態決定,後面的then語句都變成針對內層的Promise
前者返回的對象是動態的,每當文檔結構發生變化時,這個對象都會獲得更新,意味着每次訪問這個對象,都會運行一次基於文檔的查詢,對性能的影響很大。
後者返回的對象是靜態的,返回的時候是什麼之後就是什麼,沒有前者的性能問題。
Web Workers
JavaScript的超集,添加了靜態類型。
做業幫筆試
屏幕寬度:screen.width
瀏覽器寬度:outerWidth
文檔可視高度:innerHeight
文檔高度:document.documentElement.offsetHeight
快手筆試
10.深度爲n的二叉樹最多有多少個節點(第一層深度爲1)?2n-1(等比數列求和)
11.void recursive(int n, int m, int o)
{
if (n <= 0)
{
printf("%d,%d\n", m, o);
}
else
{
recursive(n - 1, m + 1, o);
recursive(n - 1, m, o + 1);
}
}
以上函數的時間複雜度(C)
12.同時擲兩顆骰子,落下來後,點數之和爲偶數的有多少種(一、2和二、1算一種)?12
13.1024! 末尾有多少個0?204+40+8+1=253
富途筆試準備
function f(num) {
num = '' + num;
var dotIndex = num.indexOf('.');
var float = num.slice(dotIndex, dotIndex + 3);
var str = num.slice(0, dotIndex).split('').reverse().join('');
str = str.replace(/(\d{3})/g, '$1,');
var int = str.split('').reverse().join('');
return '$' + int + float;
}
function add(s1, s2) {
var a1 = s1.split('').reverse();
var a2 = s2.split('').reverse();
a1.forEach(function (item, index, arr) {arr[index] = + item});
a2.forEach(function (item, index, arr) {arr[index] = + item});
var a3 = [];
for (var i = 0; i < a1.length && i < a2.length; i++) {
a3[i] = a1[i] + a2[i];
}
a3 = a3.concat(a1.slice(i), a2.slice(i));
var carry = 0;
for (var i = 0; i < a3.length; i++) {
a3[i] += carry;
if (a3[i] > 9) {
a3[i] -= 10;
carry = 1;
} else {
carry = 0;
}
}
var res = a3.reverse().join('');
if (carry) {
return 1 + res;
} else {
return res;
}
}
富途筆試
排列:An取m,n(n-1)(n-2)……(n-m+1),即從n開始乘,乘m個
組合:Cn取m,對應的排列除以m的階乘
華爲筆試
同花順筆試
1) 規範的代碼能夠促進團隊合做
2) 規範的代碼能夠減小Bug處理
3) 規範的代碼能夠下降維護成本
4) 規範的代碼有助於代碼審查
5) 養成代碼規範的習慣,有助於程序員自身的成長
1) 異或
a = a ^ b;
b = a ^ b;
a = a ^ b;
缺陷:當要交換的兩個變量實際上是同一個變量的時候,結果就不對,永遠爲0
2) 加減
a = a + b;
b = a - b;
a = a - b;
缺陷:彷佛沒有
4) 乘除
a = a * b;
b = a / b;
a = a / b;
缺陷:a、b都不能爲0
美麗聯合(蘑菇街)筆試
function f(arr) {
var hash = {};
arr = arr.filter(function(item) {
if (hash[JSON.stringify(item)]) {
return false;
}
hash[JSON.stringify(item)] = true;
return true;
}
);
console.log(arr)
}
POST http://test.mi.cn/insert.html HTTP/1.1
Host: test.mi.com
Referer: http://test.mi.cn/index.php?data=58
Cookie: uid=1504174654; addressid=1&productid=123&num=1&price=120
看瀏覽器
touchstart:當手指觸摸屏幕時觸發;即便已經有一個手指放在了屏幕上也會觸發。
touchend:當手指從屏幕上移開時觸發。
10. span的nth-child(0) nth-child(-n+1) nth-last-child(3) first-child
<p>
<span>A</span>
<span>B</span>
<span>C</span>
</p>
解析::nth-child(an+b) 這個 CSS 僞類首先找到全部當前元素的兄弟元素,而後按照位置前後順序從1開始排序,選擇的結果爲第(an+b)個元素的集合(n=0,1,2,3...)。
富途一面
function isSub(subSeq, seq) {
var i = 0,
j = 0;
while (i < subSeq.length) {
if (subSeq[i] === seq[j]) {
i++;
j++;
} else {
j++;
if (j === seq.length) {
return false;
}
}
}
return true;
}
HTTP規範沒有指定生成ETag的方法
富途二面
function find(arr) {
var a = [arr[0]];
var max = arr[0];
for (var i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
a.push(max);
}
var b = [arr[arr.length - 1]];
var min = arr[arr.length - 1];
for (var i = arr.length - 2; i >= 0; i--) {
if (arr[i] < min) {
min = arr[i];
}
b.unshift(min);
}
var res = [];
for (var i = 0; i < a.length; i++) {
if (a[i] === b[i]) {
res.push(a[i]);
}
}
return res;
}
console.log(find([21,11,45,56,9,66,77,89,78,68,100,120,111]))
房間。避免用戶修改本身的權限。
有人點擊抽獎,前端就告訴後端有人開始抽獎啦,而後後端計算這我的的抽獎結果,並把結果返回給前端,前端展現結果。
後端。防止用戶篡改抽獎機率。
愛奇藝筆試
var str = 'hello'
var fn1 = function() {
console.log(str)
};
str = 'HELLO'
var fn2 = function () {
var str = 'world'
fn1();
str = 'WORLD'
};
fn2();
function out(x) {
var temp = 2;
function inside(y) {
console.log(x + y + (temp--))
}
inside(5);
}
out(3);
完美世界筆試
var b = 3;
console.log(b+++4*++b);
var line = readline();
var arr = line.split(' ');
var obj = {};
var frequency = 0;
arr.forEach(function (item, index, arr) {
if (arr.indexOf(item) !== index) {
if (obj[item]) {
obj[item]++;
if (obj[item] > frequency) {
frequency++;
}
} else {
obj[item] = 1;
if (!frequency) {
frequency = 1;
}
}
}
});
console.log(1 + frequency);
360一面
1) 事件
被拖放的元素上的:dragstart drag dragend
放置目標上的:dragenter dragover dragleave或drop
2) 自定義放置目標:阻止dragenter和dragover的默認行爲
3) e.dataTransfer能在拖放時實現數據交換,它有兩個主要的方法:setData ()和getData()。前者要在在被拖放的元素上的dragstart事件中調用,後者要在放置目標的drop事件中調用。前者接收兩個參數,第一個參數爲'text'或'URL',表示保存的數據類型,第二個參數爲保存的數據,後者接收一個參數,同前者的第一個參數同樣。
4) 默認狀況下,只有圖像、連接和文本是可拖動的,其中,文本還要在被選中的狀態下。設置HTML元素的draggable爲ture或false能夠改變默認的可否拖動。
<div>test</div>
@keyframes myfirst {
from {background: red;}
to {background: yellow;}
}
div {
animation: myfirst 5s;
}
用@keyframes規則建立動畫,用from-to或百分比指定動畫不一樣階段的樣式,而後把它綁定到一個選擇器,同時至少要指定動畫的時長
Cross-Orgin Resource Sharing,跨域資源共享,定義了在訪問跨域資源時,瀏覽器與服務器應該如何溝通。CORS的基本思想,就是使用自定義的HTTP頭部讓瀏覽器與服務器溝通,從而決定請求是否成功。
發送跨域請求時,瀏覽器會附加一個Origin頭部,其中包含請求頁面的源信息(協議、域名和端口),以便服務器根據這個頭部信息來決定是否給予響應。若是服務器認爲這個請求能夠接受,就在Access-Control-Allow-Origin(訪問控制容許來源)頭部中回發相同的源信息,若是是公共資源,能夠回發「*」。
對前端來講,CORS和同源的Ajax沒有差異,CORS由瀏覽器自動完成。
有贊筆試
斐波那契數列(記初始狀態爲1對,故1個月後爲1對,2個月後爲2對……)
用兩個指針均從頭部開始,一個先走一個後走,差太小則前指針++,差過大則後指針++。
7次
綠色表示一種可能的結果
Keep筆試
console.log('goto123keep456'.replace(/\d+/g, '*'))
function LCS(s1, s2) {
var rows = (' ' + s1).split('');
var cols = (' ' + s2).split('');
var dp = [];
for (var i = 0; i < rows.length; i++) {
dp[i] = [];
for (var j = 0; j < cols.length; j++) {
if (i === 0 || j === 0) {
dp[i][j] = 0;
} else {
if (rows[i] === cols[j]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
}
console.log(dp);
return dp[i - 1][j - 1];
}
console.log(LCS('abcdab', 'bdcaba'))
須要3根繩子:同時燒第一根繩子的兩頭和第二根繩子的一頭,第一根繩子燒完的時候(過了半小時),燒第二根繩子的另外一頭,第二根繩子燒完的時候(又過了15分鐘),燒第三根繩子。
獵豹筆試
解析:注意396也是相應進制的,別默認都是十進制了
2次
可看做01揹包問題的特殊狀況
function knapsack(weights, values, capacity) {
var arr2d = [];
for (var i = 0; i < weights.length; i++) {
arr2d[i] = [];
}
for (var i = 0; i < weights.length; i++) {
for (var j = 0; j <= capacity; j++) {
if (i === 0) {
arr2d[i][j] = j < weights[i] ? 0 : values[i];
} else {
if (j < weights[i]) {
arr2d[i][j] = arr2d[i - 1][j];
} else {
arr2d[i][j] = Math.max(arr2d[i - 1][j], arr2d[i - 1][j - weights[i]] + values[i]);
}
}
}
}
return arr2d[weights.length - 1][capacity];
}
var input = [1, 0, 1, 7, 2, 4];
var sum = 0;
for (var i = 0; i < input.length; i++) {
sum += input[i];
}
console.log(sum - 2 * knapsack(input, input, Math.floor(sum / 2)));
var line = readline();
var arr = line.split(' ');
if (arr.length === 1) {
console.log(arr[0]);
} else {
var hash = {};
for (var i = 0; i < arr.length; i++) {
if (hash[arr[i]]) {
if (++hash[arr[i]] >= (arr.length / 2)) {
console.log(arr[i]);
break;
}
} else {
hash[arr[i]] = 1;
}
}
}
一點資訊筆試
class能夠看做是一個語法糖,它的絕大部分功能,ES5均可以作到,它只是讓自定義引用類型的寫法更加清晰、更加像面向對象編程的語法。
class Test {
constructor(x) {
this.x = x;
}
toString() {
return '' + x;
}
}
神策筆試
6。馬爾可夫鏈,可作圖求解遞歸方程。
Shopee二面準備
rgba:a(alpha)是不透明度(即值爲0時徹底透明),改變顏色的透明度
Shopee二面
表示獨一無二的值。ES5 的對象的屬性名都是字符串,這容易形成屬性名的衝突。好比,我使用了一個他人提供的對象,但又想爲這個對象添加新的屬性,新屬性的名字就有可能與現有屬性產生衝突。而用Symbol就能夠防止這種狀況。
WeakSet 與 Set 相似,也是不重複的值的集合。可是,它與 Set 有兩個區別:
首先,WeakSet 的成員只能是對象,而不能是其餘類型的值;其次,WeakSet 中的對象都是弱引用,即垃圾收集機制不考慮 WeakSet 對該對象的引用,也就是說,若是別的地方都再也不引用該對象,那麼垃圾收集機制會自動回收該對象所佔用的內存,不考慮該對象是否存在於 WeakSet 之中。
WeakMap與Map相似,也是鍵值對的集合。可是,它與 Map有兩個區別:首先,WeakMap只接受對象(不包括null)做爲鍵名,不接受其餘類型的值做爲鍵名;其次,WeakMap的鍵名所指向的對象都是弱引用,即垃圾收集機制不考慮 WeakMap對該對象的引用。
function myInstanceof (leftValue, rightValue) {
while (leftValue) {
if (leftValue.__proto__ === rightValue.prototype) {
return true;
}
leftValue = leftValue.__proto__;
}
return false;
}
PS:
function Foo() {}
Object instanceof Object // true
Function instanceof Function // true
Foo instanceof Foo // false
ES6規定的。
去哪兒一面
美團筆試
overflow規定元素的內容溢出時怎麼辦。
visible(默認值):顯示溢出的內容
hidden:隱藏溢出的內容
scroll:不管是否溢出,都顯示滾動條
auto:溢出時顯示滾動條
解析:度爲2的節點數 = 葉子節點數 – 1
華爲面試準備
1) 模塊化、組件化
2) 先後端分離
3) 遵照代碼規範
騰訊一面
登陸彈框。當咱們點擊登陸按鈕時,頁面中可能會出現一個彈框,而這個彈框是惟一的,不管點擊多少次登陸按鈕,彈框只會被建立一次。
CPU(和內存)
有贊一面準備
1) text-align: center + line-height: (父元素的height)
2) 絕對定位的前三種方法
3) flex的兩種方法均可以
陌陌筆試
function f(s) {
var res = [];
if (s.length === 1) {
return [s];
} else {
var preRes = f(s.slice(1));
for (var i = 0; i < preRes.length; i++) {
for (var j = 0; j < preRes[i].length + 1; j++) {
var temp = preRes[i].slice(0, j) + s[0] + preRes[i].slice(j);
res.push(temp);
}
}
return res;
}
}
PS:有重複字符就對最後的結果去個重就行了
滴滴筆試
有贊一面
方法一(時間複雜度爲O(nlogn),若是數組已有序就能夠達到O(n)):
function find(arr1, arr2) {
arr1.sort((v1, v2) => v1 - v2);
arr2.sort((v1, v2) => v1 - v2);
var i = 0,
j = 0,
res = [];
while (i < arr1.length && j < arr2.length) {
if (arr1[i] < arr2[j]) {
i++;
} else if (arr1[i] > arr2[j]) {
j++;
} else {
res.push(arr1[i]);
i++;
j++;
}
}
return res;
}
方法二(哈希算法,不管數組是否有序,時間複雜度都爲O(n)):
function find(arr1, arr2) {
var hash = {};
for (var i = 0; i < arr1.length; i++) {
hash[arr1[i]] = true;
}
var res = [];
for (var i = 0; i < arr2.length; i++) {
if (hash[arr2[i]]) {
res.push(arr2[i]);
}
}
return res;
}
1) for-in:返回全部可以經過對象訪問的(既包括實例屬性,也存在於原型中的屬性)、可枚舉的屬性
2) Object.keys():返回對象上全部可枚舉的實例屬性
3) Object.getOwnPropertyNames():返回全部實例屬性,無論是否可枚舉(即Object.getOwnPropertyNames(Object.prototype)也會返回不可枚舉的constructor)
有,指向Function,由於Function是構造函數,構造函數也是函數,因此也是由Function建立的(同理,Object也是由Function建立的)。
OYO一面
數據結構分爲邏輯結構和物理結構(也叫存儲結構)
邏輯結構有:集合結構、線性結構、樹形結構、圖形結構
物理結構有:順序結構、鏈式結構
每一個節點最多隻有兩個分支的樹結構
用於建立已經設置好了一個或多個參數的函數。bind()方法也實現了函數柯里化。
同花順一面
有贊二面
function commonParentNode(oNode1, oNode2) {
for (;;oNode1 = oNode1.parentNode) {
if (oNode1.contains(oNode2)) {
return oNode1;
}
}
}
add、commit、push
application/x-www-form-urlencoded、multipart/form-data、text/plain、application/json
字節跳動一面
function erat(n) {
var arr = [];
for (var i = 2; i <= n; i++) {
arr.push(i);
}
var res = [];
function f(arr) {
var p = arr.shift();
res.push(p);
if (p >= Math.sqrt(n)) {
res = res.concat(arr);
return;
}
var temp = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % p) {
temp.push(arr[i]);
}
}
f(temp);
}
f(arr);
return res;
}
#left {
float: left;
width: 300px
}
字節跳動二面
function myReduce(arr, func, init) {
var res = init ? init : arr[0];
for (var i = init ? 0 : 1; i < arr.length; i++) {
res = func(res, arr[i], i, arr);
}
return res;
}
function myNew(fn) {
var ret = {};
ret.__proto__ = fn.prototype;
var temp = fn.apply(ret, Array.from(arguments).slice(1));
return Object.prototype.toString().apply(temp) === '[object Object]' ? temp : ret;
}
百度一面
1) 要經過變量來訪問屬性時
2) 屬性名包含會致使用點表示法就語法錯誤的字符時,好比空格
3) 屬性名使用的是關鍵字或保留字時
slice()、substr()、substring()
區別:
1) slice()和substring()的第二個參數指定的是子字符串最後一個字符後面的位置,substr()的第二個參數指定的是返回的字符個數
2) 當參數是負值時,slice()會把負值與字符串的長度相加,substr()會把負的第一個參數加上字符串的長度,而將負的第二個參數轉換爲0,substring()會把全部負值都轉換爲0
calc(100% - 30px)會被解析成calc(70%)。
解決辦法:calc(~"100% - 30px")
不會:valueOf toString join concat slice indexOf lastIndexOf every some filter map forEach reduce reduceRight
會:push pop unshift shift reverse sort splice
1) FormData類型
2) 超市設定timeout
3) overrideMimeType()方法,重寫XHR響應的MIME類型
1) 把函數做爲參數
2) 把函數做爲返回值
茄子快傳筆試
應用層、運輸層、網際層(對應網絡層)、網絡接口層(對應數據鏈路層、物理層)
貝殼筆試
對,好比靜態鏈表
由該問題分解出的子問題的解能夠合併爲該問題的解
var datas = ['1 2 3 4 5 6','128 39 20 109 100 92','1000 10 39 33 333 39','101 10 10 101 20 20'];
var T = + '4';
for (var i = 0; i < T; i++) {
var line = datas[i];
var arr = line.split(' ');
var X = + arr[0];
var A = + arr[1];
var C = + arr[2];
var Y = + arr[3];
var B = + arr[4];
var D = + arr[5];
X -= B;
var x = 0;
while (X > 0) {
X -= B;
x += D;
}
Y -= A;
var y = 0;
while (Y > 0) {
Y -= A;
y += C;
}
if (x < y) {
console.log('XIAOCHUN');
}
if (x > y) {
console.log('XIAOZHI');
}
if (x === y) {
console.log('TIE');
}
}
var line = '027555+692-0xD32C';
var arr = line.split(/[\+-]/);
var arr2 = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i][0] === '0' && arr[i][1] !== 'x') {
arr2.push(parseInt(arr[i], 8));
} else {
arr2.push(parseInt(arr[i]));
}
}
var res = arr2[0];
var arr3 = line.match(/[\+-]/g);
for (var i = 0; i < arr3.length; i++) {
if (arr3[i] === '+') {
res += arr2[i + 1];
} else {
res -= arr2[i + 1];
}
}
console.log(res);
360筆試
a();
function a() {
console.log(a);
}
解析:A之因此會輸出錯誤信息是由於解碼操做則是將已經通過編碼的 URL 片斷中的每個轉義序列替換爲相對應的字符。若是相應的字符不存在,就會拋出錯誤
let i = 0;
new Array(10).forEach(()=>{i++;})
console.log(i);
let i = 1 + {
valueOf() {return 9;}
};
解析:(?=pattern),正向確定預查(look ahead positive assert),在任何匹配pattern的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不須要獲取供之後使用。例如,「Windows(?=95|98|NT|2000)」能匹配「Windows2000」中的「Windows」,但不能匹配「Windows3.1」中的「Windows」。預查不消耗字符,也就是說,在一個匹配發生後,在最後一次匹配以後當即開始下一次匹配的搜索,而不是從包含預查的字符以後開始。
(?!pattern),正向否認預查(negative assert)。
[^xyz],排除型字符集合(negated character classes)。匹配未列出的任意字符。
流利說筆試
樸素解法:
function FindGreatestSumOfSubArray(array)
{
var ret = array[0];
for (var i = 0; i < array.length; i++) {
var sum = array[i];
var max = array[i];
for (var j = i + 1; j < array.length; j++) {
sum += array[j];
if (sum > max) {
max = sum;
}
}
if (max > ret) {
ret = max;
}
}
return ret;
}
動態規劃:
function FindGreatestSumOfSubArray(array)
{
var ret = array[0];
var pre = array[0];
for (var i = 1; i < array.length; i++) {
pre = Math.max(pre + array[i], array[i]);
ret = Math.max(ret, pre);
}
return ret;
}
陌陌一面
這個方法會建立一個函數的實例,它的this值會被綁定到傳入bind()的參數。
前者是事件處理器所在的元素的引用,後者是發生的事件所在的元素的引用。
設置justify-content爲space-evenly或space-around或space-between,三者的區別是:左右兩端保留空間不一樣
PS:若要沿垂直方向均分,則加上flex-direction: column
迅雷面試準備
function binarySearch(arr, target) {
var low = 0,
high = arr.length - 1;
while (low <= high) {
var mid = Math.floor((low + high) / 2);
if (arr[mid] > target) {
high = mid - 1;
} else if (arr[mid] < target) {
low = mid + 1;
} else {
return mid;
}
}
return -1;
}
追一面試準備
window
解決辦法:用一個包裝函數或對這個對象的方法調用bind()(對定時器調用call()和apply()不行,由於定時器必須在window上調用,因此即便用call()和apply(),第一個參數也只能傳入window纔不報錯)
1) 父元素設置font-size: 0,內聯元素設置正常的font-size值
2) margin設爲負的(通常可設爲-0.25rem)
3) 行內元素緊挨着寫
指定頁面中的一個位置,另外能夠用來作路由
不會
複雜請求在第一次發送時,比簡單請求多一次請求,以後的必定時間內,都不用發多一次。
Options
迅雷一面
瀏覽器和服務器仍是須要通訊一次
可能發生資源更新了而緩存沒有即便更新的狀況
給資源的名字加個版本號
迅雷二面
Content-Type的值默認是application/x-www-form-urlencoded(上傳文件時用multipart/form-data)(經過 <form> 元素的 enctype 屬性指定)
表單字段的名稱和值會進行URL編碼,使用和號(&)分隔
同花順二面
1) 看官方文檔
2) 總結成博客
3) 看用這個框架開發的開源項目,模仿它
4) 把遇到的問題和解決辦法總結成博客
PS:寫博客能夠方便我之後回顧
小米麪試準備
4種
px em rem % vw vh 不帶單位(如line-height)
1) 後臺建立一個對應的基本包裝類型的實例
2) 在實例上調用指定的方法
3) 銷燬這個實例
一個Promise
把一個元素裏的內容分紅多列
slice substr substring
indexOf lastIndexOf
trim
toLowerCase toUpperCase
match search replace split
追一二面
由於null被認爲是一個空的對象引用
1) 函數聲明會發生函數聲明提高
2) 函數聲明只能建立局部函數
定義了瀏覽器怎樣向服務器請求資源,以及服務器怎樣把資源返回給瀏覽器。
小米一面
value factory service provider constant
不會,但會觸發error事件,因此能夠經過onerror事件處理器來捕獲該事件
服務器端
1) 跳轉:錨點或window.scroll(0, 0)(和scrollto同樣)
2) 滾動:
function backToTop() {
scrollBy(0, -100);
if (document.documentElement.scrollTop + document.body.scrollTop !== 0) {
setTimeout(backToTop, 10);
}
}
PS:在不一樣的瀏覽器種,document.documentElement.scrollTop和document.body.scrollTop只有一個會生效,而另外一個恆爲0
有
undefined
用arguments.callee代替函數名
div {
height: 0;
padding-top: 56.25%;
}
PS:56.25%由100% / 16 * 9得來。若是div內有元素,那這些元素要設置position: absolute且div要設置position: relative,否則這些元素都將被padding擠出容器(形成內容溢出)。
小米二面
能夠在單個TCP鏈接上進行雙向通訊。
輸入一個正整數數組,把數組裏全部數字拼接起來排成一個數,打印能拼接出的全部數字中最小的一個。例如輸入數組{3,32,321},則打印出這三個數字能排成的最小數字爲321323。
function printMinNumber(arr) {
arr.sort((a, b) => {
var ab = '' + a + b,
ba = '' + b + a;
return ab - ba;
});
return arr.join('');
}
拼多多筆試
1) 設置了display: none的元素再也不佔據空間,設置了visibility: hidden的元素仍然佔據空間
2) display: none不可繼承,visibility: hidden可繼承
3) 設置了display: none的元素的子元素不管怎樣都不能顯示,設置了visibility: hidden的元素的子元素經過設置visibility:visible能夠恢復顯示
4) 屏幕閱讀器不會讀取設置了display: none的元素的內容,而會讀取設置了visibility:hidden的元素的內容
5) display: none會致使重排,visibility: hidden只會致使重繪
1) transition
2) animation
const promise = new Promise((resolve, reject) => {
console.log('a');
resolve();
console.log('b');
});
promise.then(() => {
console.log('c');
});
console.log('d');
var a = [0, 1, 2]
a[10] = 10;
console.log(a.filter(function (x) {return x === undefined;}));
PS:說明並無真的給a[3]到a[9]分配空間
滴滴面試準備
方法一:
var ul = document.querySelector('ul');
var lis = ul.querySelectorAll('li');
var frag = document.createDocumentFragment();
for (var i = lis.length; i > 0; i--) {
frag.appendChild(lis[i - 1]);
}
ul.appendChild(frag);
方法二:
var ul = document.querySelector('ul');
var lis = ul.querySelectorAll('li');
for (var i = 0; i < lis.length - 1; i++) {
ul.insertBefore(ul.lastElementChild, lis[0]);
}
PS:lastElementChild和lastChild不一樣,後者會返回文本節點和註釋節點(注意children只會返回元素節點)
init clone mv(能夠用來改文件名) add commit push pull
是一門編程語言。誕生之初是爲了實如今前端的輸入驗證,而如今則具有了和瀏覽器窗口及其內容等幾乎全部方面交互的能力,可以處理複雜的計算和交互,是Web的一個重要組成部分,前端三劍客之首。
爲了解決瀏覽器的兼容問題
方法一:
先排序,而後判斷判斷一個序列是否是另外一個序列的子序列
方法二(哈希):
function f(subSeq, seq) {
var hash = {};
for (var i = 0; i < seq.length; i++) {
hash[seq[i]] = true;
}
for (var i = 0; i < subSeq.length; i++) {
if (!hash[subSeq[i]]) {
return false;
}
}
return true;
}
<!DOCTYPE html>
若是在文檔開始處沒有發現文檔類型聲明,則默認開啓混雜模式。
'abc' == new String("abc")返回true
若是字符串在字母表中應該排在字符串參數以前,則返回-1;等於,返回0,以後,返回1
用戶代理檢測,navigator.userAgent
10.display: none對應於ng-show: false或ng-hide: true,visibility: hidden沒有對應(ng-if是真的會把元素從DOM中移除)
11.爲何img是內聯元素卻能夠設置寬高?
由於img同時也是替換元素
12.今天星期幾?
new Date().getDay()
拼多多(廣州)二面
滴滴一面
translate scale(縮放) rotate