2019年前端面試題-02

  1. px、em和rem的區別javascript

    • px表示像素 (計算機屏幕上的一個點:1px = 1/96in),是絕對單位,不會由於其餘元素的尺寸變化而變化;
    • em表示相對於父元素的字體大小。em是相對單位 ,沒有一個固定的度量值,而是由其餘元素尺寸來決定的相對值。
    • rem:相對單位,可理解爲」root em」, 相對根節點html的字體大小來計算,CSS3新加屬性,chrome/firefox/IE9+支持。php

      任意瀏覽器的默認字體高都是16px。因此未經調整的瀏覽器都符合: 1em=16px。那麼12px=0.75em, 10px=0.625em。
      爲了簡化計算,在css中的body選擇器中聲明Font-size=62.5%,這就使em值變爲16px*62.5%=10px, 這樣12px=1.2em, 10px=1em, 也就是說只須要將你的原來的px數值除以10,而後換上em做爲單位就好了。
  2. 優雅降級和漸進加強css

    • 漸進加強(Progressive Enhancement):一開始就針對低版本瀏覽器進行構建頁面,完成基本的功能,而後再針對高級瀏覽器進行效果、交互、追加功能達到更好的體驗。
    • 優雅降級(Graceful Degradation):一開始就構建站點的完整功能,而後針對瀏覽器測試和修復。好比一開始使用 CSS3 的特性構建了一個應用,而後逐步針對各大瀏覽器進行 hack 使其能夠在低版本瀏覽器上正常瀏覽。
  3. eval()的做用html

    eval() 函數可計算某個字符串,並執行其中的的 JavaScript 代碼。
    語法:前端

    eval(string)
  4. JS哪些操做會形成內存泄露vue

    JS的回收機制:
    找出再也不使用的變量,而後釋放掉其佔用的內存,可是這個過程不是實時的,由於其開銷比較大,因此垃圾回收系統(GC)會按照固定的時間間隔,週期性的執行。
    垃圾收集器必須跟蹤到底哪一個變量沒用,對於再也不有用的變量打上標記,以備未來收回其內存。用於標記的無用變量的策略可能因實現而有所區別,一般狀況下有兩種實現方式:「標記清除」和「引用計數」。引用計數不太經常使用,標記清除較爲經常使用。
    一、標記清除
      這是javascript中最經常使用的垃圾回收方式。當變量進入執行環境是,就標記這個變量爲「進入環境」。從邏輯上講,永遠不能釋放進入環境的變量所佔用的內存,由於只要執行流進入相應的環境,就可能會用到他們。當變量離開環境時,則將其標記爲「離開環境」。
      垃圾收集器在運行的時候會給存儲在內存中的全部變量都加上標記。而後,它會去掉環境中的變量以及被環境中的變量引用的標記。而在此以後再被加上標記的變量將被視爲準備刪除的變量,緣由是環境中的變量已經沒法訪問到這些變量了。最後。垃圾收集器完成內存清除工做,銷燬那些帶標記的值,並回收他們所佔用的內存空間。
    *關於這一塊,建議讀讀 ,關於做用域鏈的一些知識詳解,讀完差很少就知道了,哪些變量會被作標記。java

    function test(){
      var a=10;//被標記,進入環境
      var b=20;//被標記,進入環境
    }
    test();//執行完畢以後a、b又被標記離開環境,被回收

    二、引用計數
      另外一種不太常見的垃圾回收策略是引用計數。引用計數的含義是跟蹤記錄每一個值被引用的次數。當聲明瞭一個變量並將一個引用類型賦值給該變量時,則這個值的引用次數就是1。相反,若是包含對這個值引用的變量又取得了另一個值,則這個值的引用次數就減1。當這個引用次數變成0時,則說明沒有辦法再訪問這個值了,於是就能夠將其所佔的內存空間給收回來。這樣,垃圾收集器下次再運行時,它就會釋放那些引用次數爲0的值所佔的內存。web

    function test(){
      var a={};//a的引用次數爲0
      var b=a;//a的引用次數加1,爲1
      var c=a;//a的引用次數加1,爲2
      var b={};//a的引用次數減1,爲1
    }

    哪些操做會形成內存泄露:
    1.意外的全局變量引發的內存泄露,一個未聲明變量的引用會在全局對象中建立一個新的變量。在瀏覽器的環境下,全局對象就是 window,也就是說:面試

    function foo(arg) {
        bar = "aaaaa";
    }
    
    // 實際上等價於
    function foo(arg) {
        window.bar = "aaaaa";
    }
    
    // 相似的
    function foo() {
        this.variable = "qqqqq";
    }
    //this 指向全局對象(window)
    foo();

    2.閉包引發的內存泄露算法

    function fn1(){
        var n=1;
        function fn2(){//在加一個fn2當他的子集
            alert(n);
        }
    return fn2(); 
    //return出來後 他就給 window了因此一直存在內存中。由於一直在內存中,在IE裏容易形成內存泄漏
    }
    fn1();

    3.dom清空或刪除時,事件未清除致使的內存泄漏

    var elements={
        button: document.getElementById("button"),
        image: document.getElementById("image"),
        text: document.getElementById("text")
    };
    function doStuff(){
        image.src="http://some.url/image";
        button.click():
        console.log(text.innerHTML)
    }
    function removeButton(){
      document.body.removeChild(document.getElementById('button'))
    }

    4.循環引用

    function leakMemory() {
        var el = document.getElementById('el');
        var o = { 'el': el };
        el.o = o;
    }

    5.定時器setTimeout和setInterval:當不須要setInterval或者setTimeout時,定時器沒有被clear,定時器的回調函數以及內部依賴的變量都不能被回收,形成內存泄漏。好比:vue使用了定時器,須要在beforeDestroy 中作對應銷燬處理。js也是同樣的。

    clearTimeout(***)
    clearInterval(***)

    6.若是在mounted/created 鉤子中使用了$on,須要在beforeDestroy 中作對應解綁($off)處理

    beforeDestroy() {
      this.bus.$off('****');
    }

    7.死循環

    while(1){
        a++;
    }

    8.給DOM對象添加的屬性是一個對象的引用

    var testObject = {};
    document.getElementById('idname').property = testObject;  //若是DOM不被消除,則testObject會一直存在,形成內存泄漏
  5. bootstrap響應式實現的原理

    百分比佈局+媒體查詢

  6. CSS樣式覆蓋規則

    • 規則一:因爲繼承而發生樣式衝突時,最近祖先獲勝。
    • 規則二:繼承的樣式和直接指定的樣式衝突時,直接指定的樣式獲勝
    • 規則三:直接指定的樣式發生衝突時,樣式權值高者獲勝。

      樣式的權值取決於樣式的選擇器,權值定義以下表:
      ```
      CSS選擇器                    權值
      標籤選擇器                    1
      類選擇器                    10
      ID選擇器                    100
      內聯樣式                    1000
      僞元素(:first-child)        1
      僞類(:link)                10
      ```
      能夠看到,內聯樣式的權值>>ID選擇器>>類選擇器>>標籤選擇器,除此之外,後代選擇器的權值爲每項權值之和,好比」#nav .current a」的權值爲100 + 10 + 1 = 111。
    • 規則四:樣式權值相同時,後者獲勝。

    • 規則五:!important的樣式屬性不被覆蓋。
  7. position的值, relative和absolute分別是相對於誰進行定位的

    1. absolute:生成絕對定位的元素, 相對於最近一級的定位不是 static 的父元素來進行定位(相對於最近的已經定位,即position爲absolute或者relative的元素的祖先元素)。
    2. fixed(老IE不支持)生成絕對定位的元素,一般相對於瀏覽器窗口或 frame 進行定位。
    3. relative生成相對定位的元素,相對於其在普通流中的位置進行定位(相對於本元素原始位置進行定位)。
    4. static默認值。沒有定位,元素出如今正常的流中
    5. sticky生成粘性定位的元素,容器的位置根據正常文檔流計算得出
  8. 解釋下CSSsprites,以及你要如何在頁面或網站中使用它

    CSS Sprites其實就是把網頁中一些背景圖片整合到一張圖片文件中,再利用CSS的「background-image」,「background-repeat」,「background-position」的組合進行背景定位,background-position能夠用數字能精確的定位出背景圖片的位置

  9. 怎樣添加、移除、移動、複製、建立和查找節點?

    1)建立新節點
    
    createDocumentFragment() //建立一個DOM片斷
    createElement() //建立一個具體的元素
    createTextNode() //建立一個文本節點
    
    2)添加、移除、替換、插入
    appendChild() //添加
    removeChild() //移除
    replaceChild() //替換
    insertBefore() //插入
    
    3)查找
    getElementsByTagName() //經過標籤名稱
    getElementsByName() //經過元素的Name屬性的值
    getElementById() //經過元素Id,惟一性
  10. 瀏覽器的內核分別是什麼?

    • IE: trident內核
    • Firefox:gecko內核
    • Safari:webkit內核
    • Opera:之前是presto內核,Opera現已改用Google Chrome的Blink內核
    • Chrome:Blink(基於webkit,Google與Opera Software共同開發)
  11. 請解釋JSONP的工做原理,以及它爲何不是真正的AJAX。

    JSONP (JSON with Padding)是一個簡單高效的跨域方式,HTML中的script標籤能夠加載並執行其餘域的javascript,因而咱們能夠經過script標記來動態加載其餘域的資源。例如我要從域A的頁面pageA加載域B的數據,那麼在域B的頁面pageB中我以JavaScript的形式聲明pageA須要的數據,而後在 pageA中用script標籤把pageB加載進來,那麼pageB中的腳本就會得以執行。JSONP在此基礎上加入了回調函數,pageB加載完以後會執行pageA中定義的函數,所須要的數據會以參數的形式傳遞給該函數。JSONP易於實現,可是也會存在一些安全隱患,若是第三方的腳本隨意地執行,那麼它就能夠篡改頁面內容,截獲敏感數據。可是在受信任的雙方傳遞數據,JSONP是很是合適的選擇。

  12. 請解釋一下JavaScript的同源策略。

    在客戶端編程語言中,如javascript和 ActionScript,同源策略是一個很重要的安全理念,它在保證數據的安全性方面有着重要的意義。同源策略規定跨域之間的腳本是隔離的,一個域的腳本不能訪問和操做另一個域的絕大部分屬性和方法。那麼什麼叫相同域,什麼叫不一樣的域呢?當兩個域具備相同的協議, 相同的端口,相同的host,那麼咱們就能夠認爲它們是相同的域。同源策略還應該對一些特殊狀況作處理,好比限制file協議下腳本的訪問權限。本地的HTML文件在瀏覽器中是經過file協議打開的,若是腳本能經過file協議訪問到硬盤上其它任意文件,就會出現安全隱患,目前IE8還有這樣的隱患。

  13. 瀏覽器是如何渲染頁面的?

    1. 解析HTML文件,建立DOM樹。自上而下,遇到任何樣式(link、style)與腳本(script)都會阻塞(外部樣式不阻塞後續外部腳本的加載)。
    2. 解析CSS。優先級:瀏覽器默認設置<用戶設置<外部樣式<內聯樣式<HTML中的style樣式;
    3. 將CSS與DOM合併,構建渲染樹(Render Tree)
    4. 佈局和繪製,重繪(repaint)和重排(reflow)
  14. 對<meta></meta>標籤有什麼理解

    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
        <meta name="author" content="w3school.com.cn">
        <meta name="revised" content="David Yang,8/1/07">
        <meta name="generator" content="Dreamweaver 8.0en">
    </head>
    <body>
        <p>本文檔的 meta 屬性標識了創做者和編輯軟件。</p>
    </body>
    </html>
  15. 請寫出你對閉包的理解,並列出簡單的理解

    使用閉包主要是爲了設計私有的方法和變量。
    閉包的優勢是能夠避免全局變量的污染,缺點是閉包會常駐內存,會增大內存使用量,使用不當很容易形成內存泄露。
    閉包有三個特性:
    1.函數嵌套函數
    2.函數內部能夠引用外部的參數和變量
    3.參數和變量不會被垃圾回收機制回收

  16. JavaScript中如何檢測一個變量是一個String類型?請寫出函數實現

    typeof(obj) === "string"
    typeof obj === "string"
    obj.constructor === String
  17. 判斷一個字符串中出現次數最多的字符,統計這個次數
  18. $(document).ready()方法和window.onload有什麼區別?

    1. window.onload方法是在網頁中全部的元素(包括元素的全部關聯文件)徹底加載到瀏覽器後才執行的。
    2. $(document).ready()方法能夠在DOM載入就緒時就對其進行操縱,並調用執行綁定的函數。
  19. js遍歷

    1. for循環
    2. forEach循環:forEach() 方法用於調用數組的每一個元素,並將元素傳遞給回調函數。沒有返回值

      array.forEach(function(currentValue[, index, arr), thisValue])
    3. map()函數:map() 方法返回一個新數組,數組中的元素爲原始數組元素調用函數處理後的值。

      array.map(unction(currentValue,index,arr), thisValue)
    4. filter函數:方法建立一個新的數組,新數組中的元素是經過檢查指定數組中符合條件的全部元素。

      array.filter(function(currentValue[,index,arr), thisValue])
    5. some函數:some() 方法用於檢測數組中的元素是否知足指定條件(函數提供),some() 方法會依次執行數組的每一個元素:

      array.some(function(currentValue[,index,arr),thisValue])
    6. 對象in方法

      let obj ={a:'2',b:3,c:true};
      for (var i in obj) {
          console.log(obj[i],i)
      }
      console.log(obj);
    7. Object.keys(obj)和 Object.values(obj)函數

      const obj = {
          id:1,
          name:'zhangsan',
          age:18
      }
      console.log(Object.keys(obj))
      console.log(Object.values(obj))
  20. js數組處理函數總結

    1. array.push():push() 向數組的末尾添加一個或更多元素,並返回新的長度。
    2. array.pop():刪除並返回數組的最後一個元素
    3. array.unshift(): 向數組的開頭添加一個或更多元素,並返回新的長度.
    4. array.shift() :刪除並返回數組的第一個元素
    5. array.reverse() :方法將數組中元素的位置顛倒,並返回該數組。該方法會改變原數組
    6. array.sort() :方法用 原地算法 對數組的元素進行排序,並返回數組。排序算法如今是 穩定的 。默認排序順序是根據字符串Unicode碼點。因爲它取決於具體實現,所以沒法保證排序的時間和空間複雜性。原數組上原地排序,原數組改變
    7. array.concat(array2) :方法用於合併兩個或多個數組。此方法不會更改現有數組,而是返回一個新數組
    8. array.join():creates and returns a new string by concatenating all of the elements in an array (or an array-like object ), separated by commas or a specified separator string. If the array has only one item, then that item will be returned without using the separator.

      var arr = new Array(3)
      arr[0] = "George"
      arr[1] = "John"
      arr[2] = "Thomas"
      arr.join()
      //     output: George,John,Thomas
    9. string.slice(start,end) :方法提取一個字符串的一部分,返回一個從原字符串中提取出來的新字符串。

      // 語法:
      str.slice(beginSlice[, endSlice])
      
      beginSlice:
      必需。規定從何處開始選取。若是是負數,那麼它規定從數組尾部開始算起的位置。也就是說,-1 指最後一個元素,-2 指倒數第二個元素,以此類推。
      
      endSlice:
      可選。規定從何處結束選取。該參數是數組片段結束處的數組下標。若是沒有指定該參數,那麼切分的數組包含從 start 到數組結束的全部元素。若是這個參數是負數,那麼它規定的是從數組尾部開始算起的元素。
      
      //實例: 
      var arr = new Array(3)
      arr[0] = "George"
      arr[1] = "John"
      arr[2] = "Thomas"
      arr.slice(1) // output: John,Thomas
    10. array.splice() :方法經過刪除或替換現有元素或者原地添加新的元素來修改數組,並以數組形式返回被修改的內容。此方法會改變原數組。

      // 語法:
      array.splice(startIndex,howmany[,item1,.....])
      
      // 示例1: 添加元素
      var fruits = ["Banana", "Orange", "Apple", "Mango"];
      fruits.splice(2,1,"Lemon","Kiwi");    // output: Banana,Orange,Lemon,Kiwi,Mango
      
      // 示例2: 刪除元素
      var fruits = ["Banana", "Orange", "Apple", "Mango"];
      fruits.splice(2,2);    // output: Banana,Orange
    11. array.indexOf():返回數組對象的原始值
    12. array.reduce(reducer):方法對數組中的每一個元素執行一個由您提供的reducer函數(升序執行),將其結果彙總爲單個返回值

      reducer函數接收4個參數:
      1    Accumulator (acc) (累計器)
      2    Current Value (cur) (當前值)
      3    Current Index (idx) (當前索引)
      4    Source Array (src) (源數組)
    13. array.map():對數組的每一項應用回調函數,返回新數組
    14. array.some():數組中只需有一項知足給定條件則返回true。
    15. array.filter():方法建立一個新數組, 其包含經過所提供函數實現的測試的全部元素。
    16. array.every():數組的每一項都知足給定條件則返回true。
    17. forEach:數組遍歷,與for循環同樣,沒有返回

歡迎閱讀:
2019年前端面試題-01
2019年前端筆試題
2019年前端面試題-03


我是Cloudy,年輕的前端攻城獅一枚,愛專研,愛技術,愛分享。
我的筆記,整理不易,感謝閱讀、點贊和收藏。
文章有任何問題歡迎你們指出,也歡迎你們一塊兒交流前端各類問題!
相關文章
相關標籤/搜索