面試題總結

1. js的數據類型有哪些,如何判斷?

js的數據類型包括:javascript

  • 1.nullcss

  • 2.undefinedvue

  • 3.booleanjava

  • 4.stringvuex

  • 5.number數組

  • 6.Symbol瀏覽器

判斷js的數據類型方法:緩存

1.typeof

typeof ''; // string 有效
typeof 1; // number 有效
typeof Symbol(); // symbol 有效
typeof true; //boolean 有效
typeof undefined; //undefined 有效
typeof null; //object 無效
typeof [] ; //object 無效
typeof new Function(); // function 有效
typeof new Date(); //object 無效
typeof new RegExp(); //object 無效
複製代碼

2.instanceof

instanceof 是用來判斷 A 是否爲 B 的實例,表達式爲:A instanceof B,若是 A 是 B 的實例,則返回 true,不然返回 false。安全

instanceof (A,B) = {
    var L = A.__proto__;
    var R = B.prototype;
    if(L === R) {
        // A的內部屬性 __proto__ 指向 B 的原型對象
        return true;
    }
    return false;
}
複製代碼

Tips:數組沒法用instanceof判斷,ES5 提供了 Array.isArray() 方法 。該方法用以確認某個對象自己是否爲 Array 類型。 從原型鏈能夠看出,[] 的 proto 直接指向Array.prototype,間接指向 Object.prototype,因此按照 instanceof 的判斷規則,[] 就是Object的實例。依次類推,相似的 new Date()、new Person() 也會造成一條對應的原型鏈 。所以,instanceof 只能用來判斷兩個對象是否屬於實例關係, 而不能判斷一個對象實例具體屬於哪一種類型。bash

3. constructor

當一個函數 F被定義時,JS引擎會爲F添加 prototype 原型,而後再在 prototype上添加一個 constructor 屬性,並讓其指向 F 的引用。

能夠看出,F 利用原型對象上的 constructor 引用了自身,當 F 做爲構造函數來建立對象時,原型上的 constructor 就被遺傳到了新建立的對象上, 從原型鏈角度講,構造函數 F 就是新對象的類型。這樣作的意義是,讓新對象在誕生之後,就具備可追溯的數據類型。

Tips:

  1. null 和 undefined 是無效的對象,所以是不會有 constructor 存在的,這兩種類型的數據須要經過其餘方式來判斷。

  2. 函數的 constructor 是不穩定的,這個主要體如今自定義對象上,當開發者重寫 prototype 後,原有的 constructor 引用會丟失,constructor 會默認爲 Object所以,爲了規範開發,在重寫對象原型時通常都須要從新給 constructor 賦值,以保證對象實例的類型不被篡改。

4. toString

toString() 是 Object 的原型方法,調用該方法,默認返回當前對象的 [[Class]] 。這是一個內部屬性,其格式爲 [object Xxx] ,其中 Xxx 就是對象的類型。

對於 Object 對象,直接調用 toString() 就能返回 [object Object] 。而對於其餘對象,則須要經過 call / apply 來調用才能返回正確的類型信息。

Object.prototype.toString.call('') ;   // [object String]
Object.prototype.toString.call(1) ;    // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(Symbol()); //[object Symbol]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object global] window 是全局對象 global 的引用
複製代碼

2.Arry有哪些方法

  • concat()連接兩個或多個數組;不改變原數組;返回被連接數組的一個副本

  • join()把數組元素放到一個字符串;不改變原數組;返回字符串

  • slice()從已有的數組中返回選定的元素;不改變原數組;返回一個新的數組

  • toString()把數組轉爲字符串;不改變原數組;返回一個新的數組

  • pop()刪除數組最後一個元素,若是數組爲空,則不改變數組,返回undefined;改變原有數組;返回被刪除的元素

  • push()向數組末尾添加一個或多個元素;改變原數組;返回新數組的長度

  • reverse()顛倒數組中元素的順序;改變原數組;返回該數組

  • shift()把數組的第一個元素刪除,若爲空數組,不進行操做,返回undefined;改變原數組;返回第一個元素的值

  • sort()對數組進行排序;改變數組;返回新數組

  • splice()從數組中添加/刪除項目;改變數組;返回新數組

  • unshift()向數組的開頭添加一個或多個個元素;改變原數組;返回新數組的長度。

3.簡單實現字符串trim方法,去掉首位空格,有哪些方法?

<script type="text/javascript">
function trim(str){ //刪除左右兩端的空格
   return str.replace(/(^\s*)|(\s*$)/g, "");
}
function ltrim(str){ //刪除左邊的空格
    return str.replace(/(^\s*)/g,"");
}
function rtrim(str){ //刪除右邊的空格
    return str.replace(/(\s*$)/g,"");
}
</script>
複製代碼

4. Vue實現雙向綁定的原理

當你把一個普通的 JavaScript 對象傳給 Vue 實例的 data 選項,Vue 將遍歷此對象全部的屬性,並使用 Object.defineProperty 把這些屬性所有轉爲 getter/setter。Object.defineProperty 是 ES5 中一個沒法 shim 的特性,這也就是爲何 Vue 不支持 IE8 以及更低版本瀏覽器。

每一個組件實例都有相應的 watcher 實例對象,它會在組件渲染的過程當中把屬性記錄爲依賴,以後當依賴項的 setter 被調用時,會通知 watcher 從新計算,從而導致它關聯的組件得以更新。

5.爲何vue實例中的data屬性要用函數返回

咱們都知道基本數據類型存放在棧中,引用數據類型存放在堆中。

當一個組件被定義,data 必須聲明爲返回一個初始數據對象的函數,由於組件可能被用來建立多個實例。若是 data 仍然是一個純粹的對象,則全部的實例將共享引用同一個數據對象!經過提供 data 函數,每次建立一個新實例後,咱們可以調用 data 函數,從而返回初始數據的一個全新副本數據對象。

6.狀態管理

vue中都包含了一個data()函數,用於要響應的組件。若是模板中使用的data()屬性值發生改變,組件視圖將會更新。

要想弄清楚狀態管理,不得不說組件之間的傳值。

1.組件經過props將數據傳遞給子組件:

props傳值咱們須要將一個值綁定在子組件的prop屬性上。

經過上面代碼能夠看到 ParentComponent組件把 numbers數組做爲同名的 props傳遞給 ChildComponent。而後 ChildComponent組件進行渲染。

2.子組件經過自定義事件進行傳值給父組件

經過上面代碼能夠看出來子組件經過自定義事件$emit('number-added', Number(number))"傳值給父組件,父組件經過@number-added="numbers.push($event)"監聽自定義事件接收子組件的傳值。

上面說了如何父子之間的傳值,可是兄弟組件的傳值怎麼辦?

Vue大體有三種方式能夠管理兄弟之間的通信:

  • 使用全局的EventBus

EventBus是一個實例,用於支持獨立組件之間發佈和訂閱自定義事件,換句話說EventBus是使用發佈訂閱模式進行數據的改變的。

  • 使用簡單的全局儲存

簡單的全局存儲很接近Flux的狀態管理,在store中定義一個初始化對象state和一個addNumbers方法,

在組件中 import { store } from '../store.js';引入 store而後在 data中直接獲取數據,同時能夠在methods中修改方法。

export default { 
    name: 'NumberDisplay', 
    data: () => ({ 
        storeState: store.state 
    }) ,
    methods: { 
        addNumber(numberInput) { 
            store.addNumber(Number(numberInput)) 
        } 
    }
}
複製代碼
  • 使用相似Flux庫的Vuex

Vuex是一個Store庫在這個庫中能夠實現各個組件數據的共享:

  • State方法:該方法中只是定義須要共享的數據;最簡單的用法就是直接在組件的computed計算屬性中調用this.$store.state.count;若是在組件中須要屢次調用可使用mapState來簡化代碼;
  • getter方法,在getter方法中能夠過濾一下State裏的數據從而獲取到符合預期的數據。同時在組件中也可使用mapGetters來批量獲取計算屬性。
  • mutation方法:在該方法中主要是修改State方法中的數據,默認第一個參數是State,在組件中使用commint方法調用this.$store.commit('hotel/setPickCity',data);(第一個參數爲Store所在的位置,第二個爲數據);若是同時要改變多個數據可使用mapMutations輔助函數來操做;爲了不在mutation中異步同步同時使用,因此統一mutation方法中都是同步事件;
  • action方法:在該方法中只要是異步獲取數據,而後使用commint調取mutation裏的方法實現改變state裏的方法。

Action 函數接受一個與 store 實例具備相同方法和屬性的 context 對象,所以你能夠調用 context.commit 提交一個 mutation,或者經過 context.state 和 context.getters 來獲取 state 和 getters。在組建中咱們使用this.$store.dispatch('xxx')來分發action,或者使用mapAction,進行多個方法的簡化;

總的來講vuex中數據改變的方法大體就是:定義一個state函數後,getter函數能夠過濾一些數據供其餘組件使用,同時mutation來改變state裏的數據,action經過調用mutation裏的方法改變state數據。

7.computed、methods和watch的使用和區別

  • computed計算屬性,簡單的說computed就是能夠處理任何複雜邏輯的方法相似於過濾器。在這個方法中能夠按照咱們的要求處理數據。computedgetset方法可使用。

計算屬性是基於它們的依賴進行緩存的。只在相關依賴發生改變時它們纔會從新求值。

因此若是依賴不變,那麼就不會調用computed相對來講性能比較好。

  • methods方法,這個屬性簡單的來講就是function,能夠定義方法進行屬性的修改或者返回。與computed相比之下,每當觸發從新渲染時,調用方法將總會再次執行函數。
  • watch偵聽屬性,當有數據須要根據其餘數據的變更而變更的時候就須要用watch進行偵聽回調,使用的場景大多用以異步請求。

8.URL從渲染到頁面展示發生了什麼?

簡單的說瀏覽器打開URL時發生了:

  • 第一步:DNS解析把域名解析成了IP地址,
  • 第二步:進行TCP協議傳輸,TCP三次握手
  • 第三步:發生HTTP請求,
  • 第四步:服務器除了請求並返回HTTP報文
  • 第五步:瀏覽器解析渲染頁面
  • 第六步:斷開鏈接:TCP四次回收 在這個過程當中要明白URL是什麼? URL:統一資源定位符,用於定位互聯網上的資源,俗稱網址; 通常遵循如下語法規則:
scheme://host.domain:port/path/filename
https://www.baidu.com/123
複製代碼
  • scheme:協議類型。常見的協議有httphttpsftpfilehttphttps的差異在於https是加密的,http1.0和1.1的差異是1.1支持多個請求對應一個TCP連接,http默認的端口是80https默認的是443

  • host:定義域主機。默認www還有其餘二級域名;

  • domain:域名;

  • port:端口號;

  • path:路徑;

  • filename:文件名稱;

http請求分爲三部分,TCP三次握手、http請求響應、關閉TCP鏈接。

  • TCP三次握手用於同步客戶端和服務端序列號和確認號,並交換TCP窗口大小信息。爲了不失效的連接忽然傳入服務端而進行三次握手。

  • 三次握手後開始發送請求報文;請求報文包括:請求行、請求頭、請求體。

    請求行包括:請求方法、URL、協議版本, 經常使用的http請求方法包括get、post、put、delet、head、options。 get是用於獲取數據; post用於提交數據; put用於傳輸文件,報文主題包含文件內容,保存到對應的URL位置; head獲取報文首部,與get相似,只不過返回報文主體,通常驗證URL是否有效; delete用於刪除文件,與put相反,刪除對應的URL位置文件; option查詢相應的URL支持的HTTP方法; getpost的差異: get是獲取數據傳輸的數據比較小post是提交數據,傳輸的數據比較大; get把參數加到URL而且能夠做爲書籤收藏,因此不安全,post相對來講比較安全;他們的最大的區別在於post不是冪等性而get是。 請求頭:請求頭包括請求的附加信息,由key/value組成,中間由冒號隔開,通常包含host,user-agent等; 請求體:name=tom&password=1234&realName=tomson包含多個請求參數,注意並非全部請求都有請求數據。

  • 響應報文包括:響應行、響應頭。響應體。

響應行包括:協議版本、狀態、狀態碼描述 狀態碼描述規則:

  • 1xx:已接收,正在處理
  • 2xx:成功
  • 3xx:重定向,304成功 可是數據爲改變
  • 4xx:客戶端請求錯誤
  • 5xx:服務器端錯誤

響應頭和請求頭相似,由key/value組成,包含返回的數據格式等。

響應主體包含回車符、換行符和響應返回數據,並非全部響應報文都有響應數據。

爲了保證http請求的簡單因此http請求是無狀態的一種協議,這個無狀態是指無登陸狀態,http不會記錄是那我的發出的請求,這樣的好處是使傳輸更加簡單。

爲了解決一些須要登陸的請求就引入了cookiesession的概念;

cookie是一小段文本信息,http請求時會帶上它而後服務器檢查cookie傳輸不一樣的數據。

session是在服務器端記錄用戶狀態的一個機制,Session至關於程序在服務器上創建的一份客戶檔案,客戶來訪的時候只須要查詢客戶檔案表就能夠了。

瀏覽器拿到響應的HTML文本後會根據瀏覽器的渲染機制進行渲染:

  • 根據HTML解析出DOM樹
  • 根據css解析生成css規則樹(css會阻塞dom的渲染和js的加載)
  • 結合DOM樹和CSS規則樹生成渲染樹
  • 根據渲染樹計算每個節點信息
  • 根據計算好的信息繪製頁面

斷開鏈接發起TCP四次揮手。

相關文章
相關標籤/搜索