記錄前端的面試平常(持續更新)

寫在前面的話

又到了跳槽的季節,如今也該總結一下本身在前端積累這麼多年的一點珍藏的貨色了,注意了我主要總結是儘可能用本身能表達的想法去說,全部可能沒別人總結的那麼客觀,還有儘可能用簡短的話簡單的思路去表達應該有的意思,方便記憶理解,還有這篇博文我會持續更新的javascript

什麼叫優雅降級和漸進加強(這個其實不少的,可是我是不可能去背的,全部儘可能用少的話,總結清楚)

.transition{
  -webkit-transition: all .5s;
     -moz-transition: all .5s;
       -o-transition: all .5s;
          transition: all .5s;  
}//漸進加強
.transition{ 
     transition: all .5s;
  -o-transition: all .5s;
  -moz-transition: all .5s;
-webkit-transition: all .5s;
}//優雅降級

優雅降級:一開始就構建完整的功能,而後再針對低版本瀏覽器進行兼容php

漸進加強:針對低版本瀏覽器進行構建頁面,保證最基本的功能,而後再針對高級瀏覽器進行效果.交互等改進和追加功能達到最好的用戶體驗css

jQuery的實現原理

(functon(window,undefined){})(window)html

jQuery利用JS函數做用域的特性,採用當即調用表達式包裹了自身,解決命名空間和變量污染問題前端

window.jQuery=window.$=jQueryvue

在閉包當中將jQuery和$()綁定到window上,從而jQuery和$暴露爲全局變量java

jQuery.fn的init方法返回的this就是jQuery對象node

核心是對DOM 操做進行的封裝,以免單獨實現不一樣瀏覽器的兼容代碼jquery

經過代理對象,給不一樣的對象監聽事件,進行管理webpack

jQuery 的屬性拷貝(extend)的實現原理是什麼,如何實現深拷貝?

淺拷貝(只複製一份原始對象的引用)

  • var newObject=$.extend({},oldObject)

深拷貝(對原始對象實行所引用的對象進行遞歸拷貝)

JSON對象parse方法能夠將JSON字符串反序列化成js對象,stringify方法能夠將js對象序列化成json字符串,這兩種方法產生一個便捷的深克隆

  • var newObject=$.extend(true,{},oldObject)

深淺拷貝的區別

深拷貝以後,改變其中一個值,不會影響另一個值,淺拷貝則會影響

淺拷貝只是拷貝了指向對象的指針

而深拷貝則是徹底拷貝整個值,建立了一個新的和原對象同樣的對象

清除浮動

第一種overflow:hidden

第二種

.clearfix:after{
  content:".",
  diplay:block;
  hieght:0;
  clear:both;
  visibility:hidden;
}

最快速的數組求最大值

var arr=[1,2,12,5,6];

Math.max(...arr);//es6

math.max.apply(null,arr)//es5 apply

//for循環
let max=arr[0];
for(let i=0;i<arr.length-1;i++){
  max=arr[i]<arr[i+1]?arr[i+1]:arr[i]
}

//數組sort()
arr.sort((num1,num2)=>{return num1-num2<0})//回憶a-b升序b-a降序,同理喔
arr[0]

//數組reduce
//這個仍是須要科普一下
//aray的reduce()把一個函數做用在整個Array的[x1,x2,x3,x4...]上,這個必須接受兩個
//參數,reduce()把結果繼續和序列的下一個元素作累計計算,怎麼感受有點像map
//感受沒有解釋清楚,下面給個地址
arr.reduce((num1,num2){return num1>num2?num1:num2})

reduce科普

數組去重

[... new Set([2,"23","2","5",12,5,6,12])]最快速的方式

  • 最簡單的方法
function arr1(){
    var n=[];
    for(var i=0;i<arr.length;i++){
      if(n.indexOf(arr[i])==-1){
          n.push(arr[i])
      }
    }
    return n;
  }

cookie是網站爲了標識用戶身份而存儲在用戶本地終端上的數據

cookie數據使用在同源的http請求中攜帶,會在瀏覽器和服務器來回傳遞

webStorage目的:克服cookie帶來的一些限制,當數據須要被嚴格控制在客戶端是,不須要持續的將數據發回服務器

webstorage提供兩種API:localstorage(本地存儲)和sessionStorage(會話存儲)

生命週期:

  • localStorage(本地存儲)

    - 永久的,關閉網頁也不會消失,除非主動刪除數據
  • sessionStorage(會話存儲)

    -  數據在當前瀏覽器窗口關閉後自動刪除
  • cookie     設置的cookie過時時間以前一直有效,即便瀏覽器關閉

locaStorage(本地存儲)和sessionStorage(會話存儲)不會自動把數據發給服務器,僅僅本地保存

存儲大小:

  • cookie -->4k
  • sessionStorage和localStorage -->5m或更大

javascript有幾種類型的值

:原始數據類型(undefined,null,Boolean,number,string)

:引用數據類型(對象,數組,函數)

區別:存儲位置不一樣

原始類型數據直接存儲在棧的簡單數據段

  • 佔據空間小,大小固定,屬於被平凡使用數據,因此放在棧中存儲

引用數據類型存儲在堆中的對象

  • 佔據空間大,大小不固定,若是存儲在棧中,將會影響程序運行的性能
  • 引用數據類型在棧中存儲了指針,該指針指向該實體的起始地址
  • 當解釋器尋找引用值時,會首先檢索在棧中的地址,取得地址後從堆中獲取實體

javascript如何實現繼承

原型prototype機制或apply和call方法去實現較簡單,建議使用構造函數與原型混合方式。
 
    function Parent(){
        this.name = 'wang';
    }

    function Child(){
        this.age = 28;
    }
    Child.prototype = new Parent();//繼承了Parent,經過原型

    var demo = new Child();
    alert(demo.age);
    alert(demo.name);//獲得被繼承的屬性

什麼是doctype

DTD就是告訴瀏覽器我是什麼文檔類型,用這個來判斷我用什麼來解析它渲染它

doctype就是通知瀏覽器哪一個DTD和文檔類型

<!doctypehtml>--->HTML5

HTML4.0有兩個模式:嚴格模式和寬鬆模式

內核的理解

分爲兩個部分:渲染引擎和js引擎

渲染引擎:負責取得網頁的內容(html,css)

js引擎:解析和執行javascript來實現網頁的動態效果,可是後來js引擎愈來愈獨立了(V8引擎)

有一個長度100的數組,算前10項的和

var a=[1,2,34,4,5,6,76,7,1,2,3,4,5,6,7]
      sun=null;
      sun=a.slice(0,10).reduce(function(pre,current){
        return pre+current;
      })
      console.log(sun);//reduce能夠看前面最大值

javascript優化

鬆耦合:當修改一個組件而不須要改其餘組件時,就作到鬆耦合

將js從css中抽出,不要使用css表達式

將css從js中抽出:經過js修改css樣式時,使用className或classList

將js從html抽離:從js外置文件

將HTML從js中抽離:不要使用innerHTML使用字符串模板

HTML.css.JS三者的關係應當時相互獨立分離的,若是產生交集,出現緊耦合代碼,就違反了代碼可維護性原則

全局變量

零全局變量(function(){})(window)

單全局變量(jQuery)和命名空間

模塊

事件處理

隔離應用邏輯(將應用邏輯和事件處理的代碼拆分開)

var MyApplication = {
  handleClick: function(event){
    this.showPopup(event);
  },
  showPopup: function(event){
    var popup = document.getElementById('popup');
    popup.style.left = event.clientX + 'px';
    popup.style.top = event.clientY + 'px';
    popup.className = 'reveal';
  }
};
addListener(element,'click',function(event){
  MyApplication.handleClick(event);
});

不要分發事件對象

讓事件處理程序使用event對象來處理事件,而後拿到全部須要的數據傳到應用邏輯

//改進的作法
var MyApplication = {
  handleClick: function(event){
    this.showPopup(event.clientX,event.clientY);
  },
  showPopup: function(x,y){
    var popup = document.getElementById('popup');
    popup.style.left = x + 'px';
    popup.style.top = y + 'px';
    popup.className = 'reveal';
  }
};
addListener(element,'click',function(event){
  MyApplication.handleClick(event);
});

記得在事件處理程序應當在進入應用邏輯以前針對event對象執行任何須要的操做,包括阻止時間冒泡,都應該包含在事件處理程序中

//改進的作法
var MyApplication = {
  handleClick: function(event){
    event.preventDefault();
    event.stopPropagation();
    this.showPopup(event.clientX,event.clientY);
  },
  showPopup: function(x,y){
    var popup = document.getElementById('popup');
    popup.style.left = x + 'px';
    popup.style.top = y + 'px';
    popup.className = 'reveal';
  }
};
addListener(element,'click',function(event){
  MyApplication.handleClick(event);
});

感受這個須要日積月累,感受前面是有無數的坑等着你踩先完成功能而後再考慮優化的問題

線程和進程的區別

node進程啓動事後默認會建立一個線程,線程用於執行咱們的代碼

一個進程能夠有多個線程,全部進程與線程是包含與被包含的關係

進程(程序):一個靜態概念,一個class文件,一個exe文件

線程:是一個程序裏面不一樣的執行路徑

二叉樹遍歷

先序遍歷:順序根左右

中序遍歷:順序左根右

後序遍歷:順序左右根

層序遍歷:順序從上到下從左到右分層遍歷

前序遍歷:先訪問根節點,而後前序遍歷左子樹,再前序遍歷右子樹(中左右)

中序遍歷:從根節點開始(注意不是先訪問根節點),中序遍歷根節點的左子樹,而後是訪問根節點,左後遍歷根節點的右子樹(左中右)

這裏仍是要多羅嗦一些東西,由於我有時仍是有點不太懂(這樣是否是稍微清晰了一點)

中序遍歷:BDCAEHGKF

後序遍歷:從左到右先葉子後節點的方式遍歷訪問根節點(左右中)//怎麼有點像css遍歷從上到下從右到左

層序遍歷:從樹的第一層,也就是根節點開始訪問,從上到下逐層遍歷,在同一層中,按從左到右的順序結構訪問

瀏覽器的渲染原理

當瀏覽器獲取html文件時,會"自上而下"加載,並在加載過程解析渲染

解析:

瀏覽器會將HTML解析成一個DOM樹,DOM樹的構建過程是一個深度遍歷過程:當前節點的全部子節點都構建好後纔會去構建當前節點的下一個兄弟節點

將CSS解析成CSS Rule Tree

根據DOM樹和CSSOM樹來構造Rendering Treen,注意:Rendering Tree渲染樹並不等同於DOM樹,由於一些想header或display:none的東西就不必放在渲染樹中

有了Render Tree,瀏覽器已經能知道網頁中有哪些節點.各個節點的CSS定義以及他們的從屬關係,下一步操做稱之爲Layout就是計算出每一個節點在屏幕中的位置

而後就進行繪製,遍歷render樹,並使用UI後端層繪製每個節點

終於說到重點了,影響瀏覽器渲染主要有:reflow(迴流)和repaint(重繪)

迴流Reflow(渲染機制類)

  • DOM結構中的各個元素都有本身的盒子模型,這些須要瀏覽器根據各類樣式計算並根據計算結果將元素放在該出現的位置,這個過程稱reflow

觸發Reflow

  • 移動DOM

  • 修改CSS

  • 修改網頁默認字體

  • 增長刪除修改DOM節點

重繪Repaint

  • 頁面呈現的內容放在頁面上

觸發Reqaint

  • DOM改動

  • CSS改動

儘可能避免reflow(迴流)

reflow想一想怎麼可能避免呢?那隻能將reflow對性能的影響減到最小

好比須要改變元素的樣式,不要經過父級元素影響子元素,最好直接加載子元素

設置style屬性改變樣式的話,沒設置一次都會致使一次reflow,最好就是設置class的方式

避免沒必要要的複雜的css選擇器,尤爲是後代選擇器(這裏確定會有人反駁了,我用的是less,就看看解析的時候,後代有多長,看着多怕,哥們要不你用sess或者sass,有個屬性能夠直接跳出選擇器@at-rootless有沒有我也不知道)

還有就是不要用tables佈局

ES6

從數組中移出falsey值

使用Array.filter()刪選出falsey值(false,null,0,"",undefined和NaN)

const compact=arr=>arr.filter(Boolean);
console.log(compact([0, 1, false, "", 3, "s","e"*23,"a", NaN]));

計算數組中值的出現次數

使用Array.reduce()在每次遇到數組中的特定值時遞增計數器

const coumt=(arr,value)=>arr.reduce((a,v)=>v===value?a+1:a+0,0);
console.log(coumt([12, 1, 1, 2, 3, 4, 32, 2, 1, 1, 1, 1, 1], 1));

若是不理解逗號後面的值,能夠再MDN查詢 reduce

深度拼合數組

const deepFlatten = arr => [].concat(...arr.map(v => Array.isArray(v) ? deepFlatten(v) : v));
console.log(deepFlatten([1, [2], [[3], 4], "a"]));

注意SEO

合理的title,description,keywords:搜索對着三項的權重逐個減少,

語義化的HTML代碼

重要內容HTML代碼放在最前

重要內容不要用js輸出

少用iframe

非修飾性圖片必須加alt

提升網站速度

離線存儲

在線的狀況,會請求html的manifest屬性,它會請求manifest文件的內容,根據內容進行離線存儲,讓加載頁面時,會對新的manifest文件內容進行比較,進行存儲

離線的狀況,直接使用離線存儲的資源

缺點:

更新的資源,須要二次刷新纔會被頁面採用

不支持增量更新,只有manifest發生變化,全部資源所有從新下載一次

缺少足夠容錯機制,當清單中任意資源文件出現加載異常,都會致使整個manifest策略運行異常

在javascript中一切都是對象嗎?

基本類型: Boolean Null Undefined string number Symbol(E6)

對象類型: Object

  • 數據封裝類對象:Object, Array ,Boolean, Number ,String
  • 其餘對象:Function, Arguments ,Math, Date, RegExp,Error
  • 任何非基本類型的都是對象類型

區別

基本類型

  • 不可變,沒法添加刪除屬性;按值比較,按值傳遞

對象類型

  • 可變,支持添加刪除屬性,按引用比較,按引用傳遞

檢測對象類型?或者檢測一個數據是數組類型

Object.prototype.toString.call([])

typeof只在基本類型的檢查上面纔好使,在引用類型(Function除外) 裏面他返回的都是object

Ajax

感受我會寫好多東西呀,能夠當作複習哦,面試的時候說個一二十分鐘不是問題

$.ajax({//jQuery
  url:"http://www.baidu.com",//請求的url地址
  dataType:"json",//返回的數據格式
  data:{} //參數
  type:"GET"
  success:function(data){
    //請求成功的請求
  }
})
// 1.建立
            var ajax = new XMLHttpRequest();
            // 2設置
            ajax.open('get', 'Ajax_get.php');
            // 3.發送
            ajax.send(null);
            // 4.狀態事件
            ajax.onreadystatechange = function() {
                        if (ajax.readyState == 4 && ajax.status == 200) {
                                    // 5.使用返回的數據 修改頁面的內容
                                    // responseText 返回的就是一個 字符串
                                    // 咱們 在ajax 中 若是 是經過 ajax.responseText 獲取到的 通通都是字符串
                                    console.log(ajax.responseText);
                        }
            }
var ajax = new XMLHttpRequest();

        // 使用post請求
        ajax.open('post','ajax_post.php');

        // 若是 使用post發送數據 必須 設置 以下內容
        // 修改了 發送給 服務器的 請求報文的 內容
        // 若是須要像 HTML 表單那樣 POST 數據,請使用 setRequestHeader() 來添加 HTTP 頭。而後在 send() 方法中規定您但願發送的數據:
        ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        // 發送
        // post請求 發送的數據 寫在 send方法中 
        // 格式 name=jack&age=18 字符串的格式
        ajax.send('name=jack&age=998');

        // 註冊事件
        ajax.onreadystatechange = function () {
            if (ajax.readyState==4&&ajax.status==200) {
                console.log(ajax.responseText);
            }
        }
function getXhr() {
        var xhr = null;
        if (window.XHLHttpRequest) {
            xhr = new XMLHttpRequest();
        } else {
            xhr = new ActiveXObect("Microsoft.XMLHttp");
        }
        return xhr;
    }

這個爲何我會單獨寫出來建立的對象兼容由於這裏涉及到:
js高階編程技巧之"惰性思想":可以執行一次就搞定的絕對不會執行屢次

Ajax:asyncjavascript and xml 異步的js和XML

客戶端js中的方法,用來向服務器端發送請求(還能夠傳遞給服務器端數據,而後把服務器端返回的內容獲取

xml:可擴展的標記語言(在xml文件使用的標籤都是本身擴展的)

利用本身擴展的有規則的標記來存儲相關的數據(xml後臺用處很大)

xhr.readyState:請求狀態碼

  • 0 (未初始化)當前的請求尚未發送

  • 1 (載入)url地址已經打開(發送前的參數配置已經完成)

  • 2(載入完成) 響應頭信息已經接收

  • 3(交互) 主要返回的內容正在服務器端進行準備處理

  • 4(完成) 響應主體的內容已經成功返回到客戶端

xhr.status:HTTP網絡狀態碼,描述了服務器響應內容的狀態

  • 200 表示響應主體的內容已經成功返回了

  • 301->永久重定向/永久轉移

302->臨時重定向/臨時轉移 服務器的負載均衡
304 本次獲取的內容是讀取緩存中的數據
400 客戶端傳遞給服務器端的參數出現錯誤
401 無權限訪問
404 客戶端訪問的地址不存在
500 未知的服務器錯誤

501->服務器已經超負荷 一臺服務器能承受10000人,那麼第10001我的訪問,若是沒有作服務器的負載均衡,那麼這我的的狀態碼就是503

GET和POST的區別

get是從服務器獲取數據----"取";post是向服務器提交數據---"發"

大小問題

  • GET請求傳遞給服務器的內容存在大小限制,而POST理論上沒有限制

  • 緣由:GET經過URL傳參給服務器,HTTP協議沒有對URL長度進行限制,可是每一個瀏覽器對於URL的長度存在限制,谷歌8k,火狐7kb,IE2kb,若是URL的長度超過限制,瀏覽器會把超出的部分截取

緩存的問題

  • GET請求會出現緩存(這個緩存不必定是304),POST是沒有緩存的

  • 在項目中咱們的GET請求通常不會讓其出現緩存"清除緩存":在URL的末尾追加一個隨機數

  • xhr.open("get","/getList?num=12&="+Math.random()")

  • if (ajax["type"].toLowerCase() === "get") {
       //->GET請求還須要在URL的末尾追加隨機數
       var suffix = ajax["url"].indexOf("?") > -1 ? "&" : "?";
       ajax["url"] += suffix + "_=" + Math.random();
     }

安全問題

  • 通常來講GET不安全,可是POST相對安全些
var xhr=new XMLHttpRequest();
xhr.open("get", "./vue.html");
xhr.send(null);
xhr.onreadystatechange=function () {
   console.log(xhr.readyState);//沒有任何輸出
   //輸出的2,3,4由於在存儲的時候就已經把0,1已經執行了,也就是說在前面就已經把0,1都已經執行了
   }

垃圾回收機制

js的垃圾回收機制是爲了以防止內存泄露,內存泄露的含義就是當已經不須要某塊內存是這塊內存還存在着,垃圾回收機制就是間歇的不按期的尋找不在使用的變量,並釋放掉它們所指向的內存

變量的生命週期

  • 當一個變量的生命週期結束以後它所指向的內存就應該被釋放,JS有兩種變量,全局變量和在函數產生的局部變量,當局部變量的生命週期在函數執行事後就結束了,此時即可被它引用的內存釋放(當即回收),但全局變量生命週期會持續到瀏覽器關閉頁面

回收方式:標記清除.引用技術(不經常使用)

標記清除

  • 大部分瀏覽器以此方式進行垃圾回收,當變量進入執行環境(函數中聲明變量)的時候,垃圾回收器將其標記爲"進入環境",當變量離開環境的時候(函數執行結束)將其標記爲"離開環境",在離開環境以後還有的變量則是須要被刪除的變量
  • 垃圾收集器給內存中的全部變量都加上標記,而後去掉環境的變量以及被環境中的變量引用的變量的標記,在此以後再被標記的變量極爲須要回收的變量極爲須要回收的變量,由於環境中的變量沒法訪問到這些變量

引用技術

引用技術的含義就是跟蹤記錄每一個值被引用的次數

跨域問題

什麼是跨域

只要協議,域名,端口有任何一個不一樣,就是跨域

爲何不能跨域

瀏覽器的同源策略,用來保護用戶的安全

跨域的解決方案

JSONP

瀏覽器能夠引用不一樣域下的JS文件,利用這個特性,實現跨域

get請求

callback參數

document.domain

頁面地址是http://a.baidu.com,嵌入的iframe是http://b.baidu.com/

分別始終hi頁面和iframe的document.domain爲:baidu.com就能夠解決

CORS方案

CORS定義一種跨域訪問的機制,可讓AJAX實現跨域訪問,CORS容許一個域

向另外一個域提交跨域的ajax請求

header("Access-Control-Allow-Origin","*")

post請求

反向代理

正向代理代理的對象是客戶端,

反向代理代理的對象是服務器

使用HTML5引進的window.postMessage方法來跨域

我的認爲window.name的方法既不復雜也能兼容全部的瀏覽器

HTTP和HTTPS有何差別

HTTP:相對HTTPS來講,速度較快且開銷較小,默認是80端口

HTTPS相對安全但開銷較大(數據以加密的形式傳遞),默認端口443

HTTP是明文跑到TCP上,而HTTPS跑在SSL/TLS應用層之下,TCP上

HTTPS

  • 非對稱加密,生成公鑰和私鑰
  • 更嚴謹的採用CA,給密鑰簽名

變態題

var count = 0;

console.log(typeof count === "number"); // true , 這個不用解釋了

console.log(!!typeof count === "number"); // false

// 這裏涉及到就是優先級和布爾值的問題
// typeof count 就是字符串"number"
// !!是轉爲布爾值(三目運算符的變種),非空字符串布爾值爲 true
// 最後才=== 比較 , true === "number" , return false
(function(){
    var a=b=3;
    //var a,a=b;   b=3跑到全局去了
})()
null instanceof Object       //false  兩個都不熟悉一個數據類型
var val = 'smtg';
console.log('Value is ' + (val === 'smtg') ? 'Something' : 'Nothing'); //+的優先級大於等於號

javascript中不容易分清的slice 和splice

slice()

根據索引值和索引值截取字符串(若截取數組,不改變原數組)

slice(1,2) //從第0項開始,包左不包右

slice(-3) //從後往前截取到倒數第三個

slice(5,2)/返回空字符

splice() 截取數組,不能截取字符串

splice(1,2) //改變原數組 ,從0項開始刪除1,2項

splice(1,2,"aaa","bbb") //替換1,2的值

splice(1,0,"aaa","bbb") //在鍵值對爲1的前面插入兩個值 ,第二個參數爲0就是不替換參數,1就是替換一個參數

jS的閉包

函數聲明的時候,會生成一個獨立的做用域

同一做用域的對象能夠互相獨立訪問

做用域呈現包含狀態,造成做用域鏈,子做用域的對象能夠訪問父做用域的對象,反之不能;

另外子做用域會使用最近的父做用域的對象

閉包是函數

做爲內部函數保存着對外部函數中變量的引用

頁面加載

加載一個資源的過程

  • 瀏覽器根據DNS服務器獲得域名的IP地址
  • 向這個IP的機器發送http請求
  • 服務器收到,處理並返回http請求
  • 瀏覽器獲得返回內容

瀏覽器渲染頁面的過程

  • 根據HTML結構生成DOM Tree
  • 根據css生成CSSOM
  • 根據DOM和CSSOM整合造成RenderTree
  • 根據RenderTree開始渲染和展現
  • 遇到script標籤時,會執行並阻塞渲染

前端網頁有那三層構成,分別是什麼?做用是什麼

  • 結構層HTML,決定網頁的結構
  • 表示層CSS,決定網頁的樣式
  • 行爲層JS,決定網頁的行爲

什麼樣的前端代碼是好的

高複用低耦合,這樣文件小,好維護,並且好擴展

請解釋什麼是事件委託

是把本來須要綁定的事件委託給父親,讓父元素擔當事件監聽的職務

簡單的說就是某個時間原本該本身乾的,可是本身不幹,交給別人來幹,就交

<ul id="ul1">
    <li>111</li>
    <li>222</li>
    <li>333</li>
    <li>444</li>
</ul>
實現功能是點擊li,彈出123:

複製代碼
window.onload = function(){
    var oUl = document.getElementById("ul1");
    var aLi = oUl.getElementsByTagName('li');
    for(var i=0;i<aLi.length;i++){
        aLi[i].onclick = function(){
            alert(123);
        }
    }
}

優勢能夠提升性能

經過HTTP請求響應過程瞭解HTTP協議

DNS域名解析

發起TCP的3次握手

簡歷TCP鏈接後發起http請求

服務器端響應http請求,瀏覽器獲得html代碼

瀏覽器解析html代碼,並請求html代碼中的資源

瀏覽器對頁面進行渲染呈現給用戶


發起TCP的3次握手

在客戶端和服務器之間創建正常的TCP網絡鏈接是

客戶端發送SYN給服務器

服務端返回SYN+ACK給客戶端

客戶端確認,返回ACK給服務端

超易錯的CSS優先級關係

.classB{
        background-color: red;
    }
    .classA{
        background-color: rebeccapurple;
    }
</style>
<!--與樣式定義的先後有關--與標籤的class順序無關-->
<p class="classA classB">1111111</p>

H5與APP混合開發遇到的問題

頁面滾動條問題

web頁面在pc瀏覽時有滾動條,可是在移動端瀏覽器打開時,沒有滾動條

解決方法

給body一個大容器 設置overflow:auto/scroll

其餘的兼容性就不說了,看着腦殼疼,解決方案等遇到了再解決吧

說說你對vue聲明週期的理解

分爲8個階段,建立前/後,載入前/後,更新前/後,銷燬前/後

  • 建立前/後:在beforeCreate階段,vue實例的掛載元素,el和數據對象data都是undefined,還沒初始化,在created階段,用於發生數據請求,也能夠初始化一些數據
  • 載入先後:在beforeMount階段,vue實例的$el和data都初始化了,但仍是掛載以前爲虛擬的dom節點上,data.message尚未替換,在mounted階段,vue實例掛載完成,data.message成功渲染
  • 更新先後:當data變化時,出觸發beforeUpdata和updated方法
  • 銷燬先後:在執行destroy方法後,對data 的改變不會在觸發周期函數,說明vue實例已經接觸了事件監聽以及dom的綁定,可是dom結構依然存在

父組件如何將數據傳到子組件

  • 父組件能夠經過props傳遞數據到子組件中
  • props是單向綁定的
  • 每次父組件更新是,子組件的全部props都會更新爲最新值

子組件如何將數據傳到父組件

  • 子組件可經過vm.$emit將數據傳遞到父組件
  • vm.$emit是觸發當前實例上的事件,附加參數都會傳給監聽器回調

面向對象編程的三個基本特性

封裝.繼承,多態

封裝

  • 也就是把客觀事物封裝成抽象的類
  • 而且類能夠把本身的數據和方法只讓可信的類或者對象操做
  • 對不可信的進行信息隱藏

繼承

  • 它可使用現有類的全部功能,並在無需編寫原來的類的狀況下對這個類的狀況下對這些功能進行擴展
  • 要實現繼承,能夠經過"繼承"和"組合"來實現

多態

  • 後端的,js沒有這個概念

總結

  • 封裝能夠隱藏實現細節,使得代碼模塊化,繼承能夠擴展已存在的代碼模塊(類)
  • 目的是爲了--代碼重用

javascript實現繼承的方式

  • 原型鏈繼承(父類的實例做爲子類的原型)

    • 缺點
    • 來自原型對象的引用屬性是全部實例共享的
    • 建立子類實例時,沒法向父類構造函數傳參
  • 構造繼承(複製父類的實例屬性給子類)

    • call/apply/bind
    • 缺點:沒法實現函數複用,每一個子類都有父類實例函數的副本,影響性能
  • 實例繼承

    • 爲父類實例添加新特性,做爲子類實例返回
  • 拷貝繼承

    • cat.prototype[p]=animal[p]
    • 缺點:效率較低,內存佔用高
  • 組合繼承

    • 經過調用父類構造,繼承父類的屬性並保留傳參的有點,而後經過將父類實例做爲子類原型,實現函數複用
  • 寄生組合繼承

    • 經過寄生方式,砍掉父類的實例屬性(new),這樣,在調用兩次父類的構造的時候,就不會初始化兩次實例方法/屬性

promise

解決回調問題

最大的好處就是在異步執行的流程中,把執行代碼和處理結果的代碼清晰的分離

promise有三種狀態:等待(pending ). 已完成(fulfilled /f斐o/). 已拒絕(rejected /v jk/)

一個promise的狀態之可能從"等待"轉到"完成"或者"拒絕",不能逆向轉移

promise本質就是一個函數,他能夠接受一個函數做爲參數,而且會返回promise對象

promise.then(function(value) {
    // 若是調用了resolve方法,執行此函數
    }, function(value) {
    // 若是調用了reject方法,執行此函數
    });
    promise.then(function(result) {
        //成功時的處理
    }).catch(function(error) {
        //錯誤時的處理
})
resolve   /v 肉/

webpack的loader是幹什麼的

loader是用來編譯和處理資源的

loader用於對模塊的源代碼進行轉換,loader可使你在import或"加載"模塊是預處理文件,所以,loader相似於其餘構建工具中"任務(task)",並提供了處理前端構建步驟的強大方法

當咱們遇到大問題時,首相想到的老是去搜搜看有沒有現成的解決方案,但現實卻不免是沒有解決問題,在這種狀況下,咱們也能夠嘗試去寫一些插件,組件,或者一個通用化的解決方案,來解決自身的問題,同時對本身掌握一些知識也會有幫助,並且嘗試事後可能發現,他也沒這麼難

Vue組件的data屬性爲何是函數

每一個組件都是Vue的實例,每一個組件都應該有本身做用域

函數擁有本身的做用域,能夠避免組件共享data屬性

Vue的路由怎麼實現的

路由:直接找到與地址匹配的組件,並將其渲染出來,改變瀏覽器地址,但不請求服務器

實現方式:地址中添加#來欺騙瀏覽器,地址的改變是進行頁面內導航

Vue router與location.href的區別

vue router是hash值改變,頁面內跳轉

location.href是頁面跳轉,頁面刷新

Webpack與Gulp的區別

Gulp是一種可以優化前端代碼的開發流程的工具

webpack是一種模塊化的解決方案

plugins(插件)

plugins並非直接操做單個文件,他直接對整個構建過程起做用

好比他會將入口引用css文件,都打包獨立的css文件,而不是內嵌在js打包文件中

call 和apply的區別是什麼

obj.call(thisObj,arg1,arg2)

obj.apply(thisObj,[arg1,arg2])

二者做用一致,都是把obj(this)綁定到thisObj,這時候thisObj具有了obj的屬性和方法

區別是call接受的是連續參數,apply接受的是數組參數

typeof和instanceof

typeof用於判斷基本類型,是一元運算符.返回結果是字符串

undefined .boolean .null.string.number.symbol.function.object

instanceof用於判斷對象的類型,是二元運算符.返回結果是布爾值

注意:基本類型與一些特殊類型沒法獲得真的結果

三角形的實現原理

#aaa{
        width: 0;
        height: 0;
        border:20px solid transparent;
        border-bottom-color:red;
    }

AMD與CMD

AMD:異步模塊定義,全部模塊異步加載,模塊加載不影響後續運行,全部依賴模塊的語言必須寫在回調函數中,提早執行依賴前置主要應用於require.js 一個當多個用

CMD:同步加載 延遲執行 依賴就近,主要應用sea.js推薦每個模塊職責單一

判斷一個參數是不是一個數組

instanceof方法主要檢測 變量的constructor是否與Array相等,也就是檢測變量的原型鏈是否指向Array構造函數的prototype原型上

arr instanceof Array
arr.constructor ===Array
Array.isArray()
Object.prototype.toString.call(arr)

什麼是原型鏈

javascript是面向對象的,每一個實例對象都有一個__proto__屬性,該屬性指向它原來對象,這個實例對象的構造函數有一個原型屬性prototype,與實例的__proto__屬性指向同一個對象,當一個對象在查找一個屬性的時,自身沒有就會根據__proto__向它的原型進行查找,若是都沒有,則想他的原型的原型繼續查找,直到查到Object.prototype.__proto__爲null,這樣也就造成原型鏈

平常變態題點我

讓本身對原生js又多了一點點小小的認識

false==0

true==1

this是如何工做的

this永遠指向函數運行時所在的對象,而不是函數被建立是所在的對象,匿名函數或者不處於任何對象中的函數指向window

若是call .apply.bind ,指定的this是誰,就是誰

普通的函數調用,函數被誰調用,this就是誰

相關文章
相關標籤/搜索