1 typescript
1.1 什么是 TypeScript
TypeScript 是微軟開發(fā)一款開源的編程語言,它是 JavaScript 的一個超集,本質(zhì)上是為 JavaScript 增加了靜態(tài)類型聲明。任何的 JavaScript 代碼都可以在其中使用,不會有任何問題。TypeScript 最終也會被編譯成 JavaScript,使其在瀏覽器、Node 中等環(huán)境中使用。
算法
2.1 冒泡排序
bubblesort (arr){
let len = arr.length;
//外層循環(huán),控制趟數(shù),每一次找到一個最大值
for(let i = 0; i < len - 1; i++){
// 內(nèi)層循環(huán),控制比較的次數(shù),并且判斷兩個數(shù)的大小
for(let j = 0;j < len - 1 - i; j++){
if(arr[j] > arr [j+1]){
let temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}
2.2 快速排序
- 實現(xiàn)1
基本思路:
- 在將要排序的數(shù)據(jù)中選取一個數(shù)作為基準(zhǔn)數(shù),將這些數(shù)據(jù)中比所選取的基準(zhǔn)數(shù)小的數(shù)放在所選取基準(zhǔn)數(shù)的左邊為左數(shù)組,將比所選取基準(zhǔn)數(shù)大的數(shù)組放在右邊為右數(shù)組。
- 通過遞歸的方式重復(fù)循環(huán)1中的過程達到排序的目的。
// 快速排序
quickSort(arr){
if(arr.length < 2) return arr;
let leftArr = [],rightArr = [] ,enArr = [],beginData = arr[0];
arr.forEach(item=>{
if(item > beginData){
rightArr.push(item);
}
if(item < beginData){
leftArr.push(item)
}
if(item == beginData){
enArr.push(item)
}
})
return this.quickSort(leftArr).concat(enArr,this.quickSort(rightArr));
}
- 實現(xiàn)2
quickSort2 (arr,begin,end){
//遞歸出口
if(begin >= end) return;
let l = begin,// // 左指針
r=end, //右指針
beginData = arr[begin]; //基準(zhǔn)數(shù),這里取數(shù)組第一個數(shù)
//左右指針相遇的時候退出掃描循環(huán)
while(l<r) {
//右指針從右向左掃描,碰到第一個小于基準(zhǔn)數(shù)的時候停住
while (l < r && arr[r] >= beginData)
r--;
//左指針從左向右掃描,碰到第一個大于基準(zhǔn)數(shù)的時候停住
while (l < r && arr[l] <= beginData)
l++;
// let temp = arr[r];
// arr[r] = arr[l];
// arr[l] = temp;
//交換左右指針?biāo)N恢玫臄?shù)
[arr[l], arr[r]] = [arr[r], arr[l]];
}
//最后交換基準(zhǔn)數(shù)與指針相遇位置的數(shù)
[arr[begin], arr[l]] = [arr[l], arr[begin]];
//遞歸處理左右數(shù)組
this.quickSort2(arr, begin, l - 1);
this.quickSort2(arr, l + 1, end);
return arr;
}
2.3 插入排序
算法理解:
插入排序就是把一組數(shù)字分成兩部分,一部分是排好順序的,另一部分是沒有排好順序的,然后,就是從沒有排好順序的那組數(shù)字中獲取數(shù)字,把它插入到已經(jīng)排好的順序的那部分?jǐn)?shù)字中,當(dāng)然,在插入到已經(jīng)排好順序的那部分?jǐn)?shù)字時,你還必須讓這個插入進來的數(shù)字與已經(jīng)排好順序的數(shù)字進行比較,為的是保證已經(jīng)排好的順序的那部分?jǐn)?shù)字不被打亂,插入排序的關(guān)鍵也就是這里,如果能夠理解這里,我想對于接下來我寫的代碼應(yīng)該不難理解了。
//外層循環(huán)取數(shù),內(nèi)層循環(huán)在有序中比較
insertSort (arr){
let len = arr.length;
for (let i = 1; i < len; i++) {
for(var j=i-1;j>=0;j--){//注意,j--,就是從有序部分的后面元素開始和無序部分的元素作比較
if(arr[j] > arr[j+1]){//第一次循環(huán)的第一個j+1也就是外層循環(huán)i,
//互換元素,對前面數(shù)組進行排序
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}
2.4 選擇排序
首先從原始數(shù)組中找到最小的元素,并把該元素放在數(shù)組的最前面,然后再從剩下的元素中尋找最小的元素,放在之前最小元素的后面,直到排序完畢。
// 選擇排序
selectSort (arr){
let temp,minindex;
let len = arr.length;
for(let i = 0; i< len; i++){
minindex = i;
for(let j = i+1;j<len;j++){
if(arr[j]<arr[minindex]){
minindex = j;
}
}
temp = arr[i];
arr[i] = arr[minindex];
arr[minindex] = temp;
}
return arr;
}
2.5 深拷貝實現(xiàn)
// 判斷是否為對象
function isObject(obj){
return typeof obj === 'object' && obj != null
}
function CloneDeep(source){
// 判斷復(fù)制的目標(biāo)書數(shù)組還是對象
if(!isObject(source)) return source;
var targetObj = source.constructor === Array ? [] : {};
for(let keys in source){
//判斷對象是否包含特定的自身(非繼承)屬性。
if(source.hasOwnProperty(keys)){
//判斷是否是對象或者數(shù)組
if(source[keys] && isObject(source[keys])){
targetObj = source.constructor === Array ? [] : {};
targetObj[keys] = CloneDeep(source[keys]);// 遞歸調(diào)用
}else{
targetObj[keys] = source[keys];
}
}
}
return targetObj;
}
3 HTTP協(xié)議相關(guān)
3.1 HTTP是什么
http(超文本傳輸協(xié)議),基于TCP/IP,在計算機世界里專門在兩點之間傳輸文字、圖片、音頻和視頻等超文本數(shù)據(jù)的約定和規(guī)范
3.2 輸入網(wǎng)址,按下回車究竟發(fā)生了什么
1、 瀏覽器先判斷輸入地址欄的是不是數(shù)字形式的IP地址,如果不是,肯定就是域名了,于是就發(fā)起域名解析動作,訪問一系列的域名解析服務(wù)器,把域名翻譯成TCP/IP協(xié)議里的IP地址(域名解析比較復(fù)雜,如果每一個域名都要大費周折的網(wǎng)上查一下,那我們上網(wǎng)肯定慢的受不了,所以,域名解析過程中會有多級緩存,瀏覽器會先看自己的緩存有沒有,再看操作系統(tǒng)的緩存,還沒有就檢查本機的域名解析文件hosts[c:\windows\system32\drivers\etc\hosts]),通過解析獲得IP地址和端口號
2、 瀏覽器使用TCP的三次握手和服務(wù)器建立連接
3、 瀏覽器向服務(wù)器發(fā)送拼接好的報文
4、 服務(wù)器收到報文后處理請求,同樣拼接號報文再發(fā)送給瀏覽器
5、 瀏覽器解析報文,渲染輸出頁面
3.2 什么是CORS
CORS(跨域資源共享 Cross-origin resource sharing)允許瀏覽器向跨域服務(wù)器發(fā)出XMLHttpRequest請求,從而克服跨域問題,它需要瀏覽器和服務(wù)器的同時支持。
- 瀏覽器端會自動向請求頭添加origin字段,表明當(dāng)前請求來源。
- 服務(wù)器端需要設(shè)置響應(yīng)頭的Access-Control-Allow-Methods,Access-Control-Allow--
Headers,Access-Control-Allow-Origin等字段,指定允許的方法,頭部,源等信息。 - 請求分為簡單請求和非簡單請求,非簡單請求會先進行一次OPTION方法進行預(yù)檢,看是否允許當(dāng)前跨域請求
3.3 作用域鏈
當(dāng)查找變量的時候,會先從當(dāng)前上下文的變量對象中查找,如果沒有找到,就會從父級(詞法層面上的父級)執(zhí)行上下文的變量對象中查找,一直找到全局上下文的變量對象,也就是全局對象。這樣由多個執(zhí)行上下文的變量對象構(gòu)成的鏈表就叫做作用域鏈
3.4 什么是閉包
閉包指能夠訪問自由變量(自由變量指的是在函數(shù)中使用,但既不是函數(shù)參數(shù)也不是函數(shù)局部變量的變量)的函數(shù)
3.5 get請求和post請求的詳細區(qū)別
- GET把參數(shù)包含在URL中,POST通過request body傳遞參數(shù)。
- GET請求在URL中傳送的參數(shù)是有長度限制的,而POST么有
- 對參數(shù)的數(shù)據(jù)類型,GET只接受ASCII字符,而POST沒有限制。
- GET比POST更不安全,因為參數(shù)直接暴露在URL上,所以不能用來傳遞敏感信息。
3.5 new操作符調(diào)用構(gòu)造函數(shù)
- 創(chuàng)建一個新的對象
- 將構(gòu)造函數(shù)的this指向這個新對象
- 為這個對象添加屬性,方法等
- 返回新對象
3.6 改變函數(shù)內(nèi)部this指針的指向函數(shù)(bind,apply,call的區(qū)別)
- 通過apply和call改變函數(shù)的this指向,他們兩個函數(shù)的第一個參數(shù)都是一樣的表示要改變指向的那個對象,第二個參數(shù),apply是數(shù)組,而call則是arg1,arg2...這種形式。
- 通過bind改變this作用域會返回一個新的函數(shù),這個函數(shù)不會馬上執(zhí)行
3.7 js的各種位置,比如clientHeight,scrollHeight,offsetHeight ,以及scrollTop, offsetTop,clientTop的區(qū)別
- clientHeight:表示的是可視區(qū)域的高度,不包含border和滾動條
- offsetHeight:表示可視區(qū)域的高度,包含了border和滾動條
- scrollHeight:表示了所有區(qū)域的高度,包含了因為滾動被隱藏的部分。
- clientTop:表示邊框border的厚度,在未指定的情況下一般為0
- scrollTop:滾動后被隱藏的高度,獲取對象相對于由offsetParent屬性指定的父坐標(biāo)(css定位的元素或body元素)距離頂端的高度。
3.8 Promise
//定義三種狀態(tài)
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
function MyPromise(fn) {
let self = this;// 緩存當(dāng)前promise實例
self.value = null; //成功時的值
self.error = null; //失敗時的原因
self.status = PENDING; // 當(dāng)前狀態(tài)
self.onFulfilled = null; //成功的回調(diào)函數(shù)
self.onRejected = null; 失敗的回調(diào)函數(shù)
function resolve(value) {
//如果狀態(tài)是pending才去修改狀態(tài)為fulfilled并執(zhí)行成功邏輯
if (self.status === PENDING) {
setTimeout(function() {
self.status = FULFILLED;
self.value = value;
self.onFulfilled(self.value);
})
}
}
function reject(error) {
//如果狀態(tài)是pending才去修改狀態(tài)為rejected并執(zhí)行失敗邏輯
if (self.status === PENDING) {
setTimeout(function() {
self.status = REJECTED;
self.error = error;
self.onRejected(self.error);
})
}
}
fn(resolve, reject);
}
MyPromise.prototype.then = function(onFulfilled, onRejected) {
if (this.status === PENDING) {
this.onFulfilled = onFulfilled;
this.onRejected = onRejected;
} else if (this.status === FULFILLED) {
//如果狀態(tài)是fulfilled,直接執(zhí)行成功回調(diào),并將成功值傳入
onFulfilled(this.value)
} else {
//如果狀態(tài)是rejected,直接執(zhí)行失敗回調(diào),并將失敗原因傳入
onRejected(this.error)
}
return this;
}
module.exports = MyPromise
3.9 Cookie、sessionStorage、localStorage的區(qū)別
- 共同點:都是保存在瀏覽器端,并且是同源的
- Cookie:cookie數(shù)據(jù)始終在同源的http請求中攜帶(即使不需要),即cookie在瀏覽器和服務(wù)器間來回傳遞。而sessionStorage和localStorage不會自動把數(shù)據(jù)發(fā)給服務(wù)器,僅在本地保存
- sessionStorage:僅在當(dāng)前瀏覽器窗口關(guān)閉前有效,自然也就不可能持久保持,localStorage:始終有效,窗口或瀏覽器關(guān)閉也一直保存,因此用作持久數(shù)據(jù);cookie只在設(shè)置的cookie過期時間之前一直有效,即使窗口或瀏覽器關(guān)閉
補充說明一下cookie的作用:
- 保存用戶登錄狀態(tài)。例如將用戶id存儲于一個cookie內(nèi),這樣當(dāng)用戶下次訪問該頁面時就不需要重新登錄了,現(xiàn)在很多論壇和社區(qū)都提供這樣的功能
- 跟蹤用戶行為。例如一個天氣預(yù)報網(wǎng)站,能夠根據(jù)用戶選擇的地區(qū)顯示當(dāng)?shù)氐奶鞖馇闆r。如果每次都需要選擇所在地是煩瑣的,當(dāng)利用了 cookie后就會顯得很人性化了,系統(tǒng)能夠記住上一次訪問的地區(qū),當(dāng)下次再打開該頁面時,它就會自動顯示上次用戶所在地區(qū)的天氣情況
- 定制頁面。如果網(wǎng)站提供了換膚或更換布局的功能,那么可以使用cookie來記錄用戶的選項,例如:背景色、分辨率等。當(dāng)用戶下次訪問時,仍然可以保存上一次訪問的界面風(fēng)格。