記一次面試

1、一面(筆試)

  1. jsonp跨域簡述原理

    jsonp實現跨域的原理是跨域的服務端把客戶端所須要的數據放進客戶端本地的一個js方法裏,進行調用,客戶端在本地的js對返回的數據進行處理。這樣就實現了不一樣域名下的兩個站點間的交流。因爲<script>標籤的src能夠跨域,利用這一點,就有了jsonp這種非正式傳輸協議。由於有多是多個不一樣站點都要訪問這個服務端,那麼各個站點要調用的方法多是各不相同的,若是把方法名寫死的話,就會很不和諧。因此解決的辦法是各個站點來訪問服務端時,在url中帶一個參數(callback)過來,服務端獲取到這個參數,就會在生成js代碼時,以這個callback參數做爲方法名,再把數據放到這個方法裏。這樣各個站點就能夠調用各自的方法了。javascript

    寫一個模擬jsonp原理的一個簡單的例子。參考連接:http://www.javashuo.com/article/p-zizqynjr-dh.htmlphp

    本地客戶端:css

    1 <script type="text/javascript"src="http://example.com/Index.aspxcallback=Hello"></script>

    本地回調函數:html

    1 function Hello(data){
    2      alert(data.result);
    3 }

    跨域服務端:前端

    protected void Page_Load(object sender, EventArgs e)
    {
         string callback=Request.QueryString["callback"];//獲取客戶端回調函數名,值爲"Hello"
         Response.Write(callback+"({result:1})");  //調用客戶端指定函數,並把數據傳進去
     }
  2. 正則表達式判斷郵箱地址

    參考連接:http://www.javashuo.com/article/p-ttosfovu-dw.htmljava

    舉例:zhangsan-001@gmail.com 
    分析郵件名稱部分:node

    • 26個大小寫英文字母表示爲a-zA-Z
    • 數字表示爲0-9
    • 下劃線表示爲_
    • 中劃線表示爲-
    • 因爲名稱是由若干個字母、數字、下劃線和中劃線組成,因此須要用到+表示屢次出現

     根據以上條件得出郵件名稱表達式:[a-zA-Z0-9_-]+
    分析域名部分:jquery

     通常域名的規律爲「[N級域名][三級域名.]二級域名.頂級域名」,好比「qq.com」、「www.qq.com」、「mp.weixin.qq.com」、「12-34.com.cn」,分析可得域名相似「**.**.**.**」組成。webpack

    • 「**」部分能夠表示爲[a-zA-Z0-9_-]+
    • 「.**」部分能夠表示爲\.[a-zA-Z0-9_-]+
    • 多個「.**」能夠表示爲(\.[a-zA-Z0-9_-]+)+

     綜上所述,域名部分能夠表示爲[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+web

    最終表達式: 
     因爲郵箱的基本格式爲「名稱@域名」,須要使用「^」匹配郵箱的開始部分,用「$」匹配郵箱結束部分以保證郵箱先後不能有其餘字符,因此最終郵箱的正則表達式爲: 
    ^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$

  3. 如下輸出結果是什麼?
    1. console.log(1+'1'+'2')      輸出112      //字符串和其餘的數據使用+號運算,會鏈接成一個新的字符串
    2. console.log(1+'1'+2)       輸出112
    3. console.log(1-'1'+'2')      輸出02        //減號只能做爲數值運算,沒有二義性(這點和加號不一樣),因此解釋器就將1-'1'自動轉成number進行運算。
    4. console.log(1-'1'+2)        輸出2        
    5.  condole.log('A'-'B')         輸出NAN   //not a number,非數值

四、從輸入url到獲得html的過程

參考連接:https://blog.csdn.net/sinat_41747081/article/details/87629707

1. 域名解析

  瀏覽器會把輸入的域名解析成對應的ip,解析分爲幾部分進行。

    • 查看瀏覽器內部緩存,若是查到域名對應的ip,就發送和接受參數和數據
    • 查看本機的host文件,瀏覽器會在本機的hosts文件查看是否有對應的ip服務器地址。
    • 查看本地路由器的DNS緩存,找到對應的ip
    • 查看網絡服務商中DNS服務器
    • 查詢根域名下是否存在。
      上述5步找到對應的ip地址後
    • 詢到目標IP地址後,則開始創建 TCP 三次握手 ,與目標服務器創建鏈接。
    • 經過規定的協議(http)向目標主機發送請求

2. 服務器接收到請求和返回數據

      服務器:安裝了系統和web-server的主機,能夠理解爲一臺電腦,安裝了系統和軟件來處理數據(硬件)

    • 服務器接收到了瀏覽器發送的請求後,根據某個協議,經過web-server把瀏覽器發送的數據進行打包(包含請求頭,ip地址,請求路徑和查詢參數等)

    • web-server把數據打包後,發送給網站代碼(好比django、flask、node.js等後端服務)

    • 後端服務軟件會根據路徑和查詢參數進行相應處理,返回給瀏覽器對應的數據包(包括http協議組成的代碼。裏面包含頁面的佈局、文字。數據也多是圖片、腳本程序,反應頭,反應數據,請求頭等)

3. 瀏覽器的接受數據和頁面渲染

 

    1. 將HTML解析成DOM樹的結構
    2. 將css解析出結構化的css,也就是cssom
    3. 將DOM樹和cssom合併在一塊兒造成render tree,即渲染樹
    4. 根據render tree進行渲染

五、閉包的優勢和缺點

參考連接:http://www.javashuo.com/article/p-fjxlbmdu-db.html

閉包定義:當一個函數的返回值是另一個函數,而返回的那個函數若是調用了其父函數內部的變量,且返回的這個函數在外部被執行,就產生了閉包。閉包是一個環境,具體指的就是外部函數--高階函數。

說白了就是一個環境,可以讀取其餘函數內部的變量。本質上,閉包是將函數內部和函數外部鏈接起來的橋樑。

用處:1.讀取函數內部的變量;

           2.這些變量的值始終保持在內存中,不會在外層函數調用後被自動清除。

優勢:1:變量長期駐紮在內存中;

           2:避免全局變量的污染;

           3:私有成員的存在 ;

特性:1:函數套函數;

           2:內部函數能夠直接使用外部函數的局部變量或參數;

           3:變量或參數不會被垃圾回收機制回收 GC;

缺點:

    常駐內存 會增大內存的使用量 使用不當會形成內存泄露,詳解:

(1)因爲閉包會使得函數中的變量都被保存在內存中,內存消耗很大,因此不能濫用閉包,不然會形成網頁的性能問題,在IE中可能致使內存泄露。解決方法是,在退出函數以前,將不使用的局部變量所有刪除。

(2)閉包會在父函數外部,改變父函數內部變量的值。因此,若是你把父函數看成對象(object)使用,把閉包看成它的公用方法(Public Method),把內部變量看成它的私有屬性(private value),這時必定要當心,不要隨便改變父函數內部變量的值。

 

六、建立一個對象的過程

①爲對象分配內存空間,將對象的實例變量初始化爲其變量類型的默認值

②若是實例變量在聲明時被顯式的初始化則將初始化值賦給實例變量

③調用構造方法

④返回對象的引用

 

七、下面代碼輸出什麼?

function fun(n){
    return n==1?1:n*fun(n-1);   //函數返回n的階乘,即n*(n-1)*(n-2)...2*1
};
console.log(fun(4));
//輸出24

八、怎麼判斷類型爲對象?

參考連接:http://www.javashuo.com/article/p-reneplyk-cv.html

    1. typeof
      1 console.log(typeof null); //object 2 console.log(typeof {}); //object 3 console.log(typeof []); //object
      typeof沒法區分對象和數組
    2. instanceof
      1 var a={}; 2 console.log(a instanceof Object) //true 3 console.log(a instanceof Array) //false 4 var b=[]; 5 console.log(b instanceof Array) //true 6 console.log(b instanceof Object) //true,數組屬於object中的一種

      instanceof須要判斷兩次才能區分對象和數組

    3. constructor
      1 var a={}; 2 console.log(a.constructor==Object) //true 3 var b=[]; 4 console.log(b.constructor==Array) //true 5 console.log(b.constructor==Object) //false

      constructor能夠區分對象和數組,注意constructor屬性是能夠被修改的,會致使檢測出的結果不正確。

    4. Object.prototype.toString.call()
      1 Object.prototype.toString.call({})   //"[object Object]" 2 Object.prototype.toString.call([]) //"[object Array]"

       推薦此方法

    5. jQuery中的$.type接口
      1 $.type([])           //array 2 $.isArray([]); //true 3 $.isPlainObject({}); //true

 

  九、怎麼判斷空對象?

 

參考連接:http://www.javashuo.com/article/p-odgvuaok-co.html

一、將json對象轉化爲json字符串,再判斷該字符串是否爲"{}"

var data = {}; var b = (JSON.stringify(data) == "{}"); alert(b);//true

 

  二、for in 循環判斷

1 var obj = {}; 2 var b = function() { 3 for(var key in obj) { 4 return false; 5 } 6 return true; 7 } 8 alert(b());//true

 

  三、jquery的isEmptyObject方法。此方法是jquery將2方法(for in)進行封裝,使用時須要依賴jquery

1 var data = {}; 2 var b = $.isEmptyObject(data); 3 alert(b);//true

 

  四、Object.getOwnPropertyNames()方法。此方法是使用Object對象的getOwnPropertyNames方法,獲取到對象中的屬性名,存到一個數組中,返回數組對象,咱們能夠經過判斷數組的length來判斷此對象是否爲空

1 var data = {}; 2 var arr = Object.getOwnPropertyNames(data); 3 alert(arr.length == 0);//true

 

  五、使用ES6的Object.keys()方法。與上一種方法相似,是ES6的新方法, 返回值也是對象中屬性名組成的數組

1 var data = {}; 2 var arr = Object.keys(data); 3 alert(arr.length == 0);//true

 

  10.v-if和v-show的相同點和不一樣點 

相同點:v-if與v-show均可以動態控制dom元素顯示隱藏

不一樣點:v-if顯示隱藏是將dom元素整個添加或刪除,而v-show隱藏則是爲該元素添加css--display:none,dom元素還在。

  11.介紹DOM樹

HTML DOM Node Tree

常見的DOM節點:元素節點、文本節點、屬性節點。

常見的DOM操做:獲取、建立、添加、刪除、設置屬性。

12.判斷一個字符串中出現最屢次數的字符

 

 1 function fun(str){  2 var obj={};  3 var max=0;  4 var key='';  5 for(var i=0;i<str.length;i++){  6 if(!obj[str.charAt(i)]){  7 obj[str.charAt(i)]=1;  8 }else{  9 obj[str.charAt(i)]++; 10  } 11  } 12 for(var i in obj){ 13 if(max<obj[i]){ 14 max=obj[i]; 15 key=i; 16  } 17  } 18 return 'str中最多的字符是'+key+',出現了'+max+'次'; 19 } 20 console.log(fun('dhdf793dcdjsd8'));//str中最多的字符是d,出現了5次

 stringObject.charAt(index):charAt() 方法可返回指定位置的字符,index表示字符串中某個位置的數字,即字符在字符串中的下標。

  13.輸出斐波那契數列

 1 var arr=[];
 2 function fun(n){
 3     if(n<3){
 4         arr[0]=1; 
 5         if(n==2){
 6             arr[1]=1;
 7         }
 8     }else{
 9         arr[0]=arr[1]=1;
10         for(var i=2;i<n;i++){
11             arr[i]=arr[i-1]+arr[i-2];
12         }
13     }
14     console.log(arr);
15 }
16 fun(7);//[1,1,2,3,5,8,13]

 

2、二面(面談)

 

  1. 列舉常見的HTTP狀態碼:
    (略)參考連接:https://baike.baidu.com/item/HTTP狀態碼/5053660?fr=aladdin
  2. 網頁優化加載
    1. 優化圖像 
    2. 去掉沒必要要的插件
    3. 減小DNS查詢(DNS lookups)
    4. 最小化重定向
    5. 使用內容分發網絡(Content Delivery Network CDN)
    6. 把CSS文件放在頁面頂部,而JS文件放在底部
    7. 利用瀏覽器緩存
    8. 使用 CSS Sprites 整合圖像
    9. 壓縮CSS和JavaScript
    10. 啓用GZIP壓縮
    11.前端實現懶加載(lazyload)
  3. Ajax是什麼?如何建立一個Ajax

    ajax全稱是asynchronous javasript and xml,主要用來實現客戶端服務器的異步通訊效果,實現頁面的局部刷新,使用ajax原生方式發送請求主要經過XMLHttpRequest(標準瀏覽器)、ActiveXObject(IE瀏覽器)對象實現異步通訊效果。

     1 <script type="text/javascript">
     2     window.onload = function(){
     3         //第一步:建立xhr對象
     4         //xhr是一個對象;裏面能夠放不少東西,數據;
     5         var xhr = null;
     6         if(window.XMLHttpRequest){//標準瀏覽器
     7             xhr = new XMLHttpRequest();//建立一個對象
     8         }else{//早期的IE瀏覽器
     9             xhr = new ActiveXObject('Microsoft.XMLHTTP');//參數是規定的;
    10         }
    11         console.log("狀態q"+xhr.readyState);//0
    12         //第二步:準備發送請求-配置發送請求的一些行爲
    13         //open即打開連接,第一個參數是以什麼方式;第二個是往哪兒發送請求,第三個能夠不寫,默認true,表示異步,false表示同步;;
    14         xhr.open('get','03form.php',true);
    15         console.log("狀態w"+xhr.readyState);//1
    16 
    17         //第三步:執行發送的動做
    18         //send也能夠寫在前面,推薦寫在後面;寫null是兼容問題;
    19         xhr.send(null);
    20         console.log("狀態e"+xhr.readyState);//1
    21 
    22         //第四步:指定一些回調函數,也屬於事件函數;不觸發不執行,觸發條件是xhr.readyState;z這個值有0-4,共5個狀態,是由瀏覽器控制的;
    23         xhr.onreadystatechange = function(){
    24             if(xhr.readyState == 4){//4指服務器返回的數據可使用;
    25                 if(xhr.status == 200){ //判斷已經成功的獲取了數據;200表示hTTP請求成功;404表示找不到頁面;503表示服務器端有語法錯誤;
    26                     var data = xhr.responseText;//json,文本,主角;
    27                     // var data1 = xhr.responseXML;
    28                 }
    29             }
    30             // console.log("狀態t"+xhr.readyState);//2表示已經發送完成;
    31 
    32             // console.log(1234);
    33         }
    34 
    35         // console.log(456);
    36         console.log("狀態r"+xhr.readyState);//1
    37 
    38 
    39     }
    40     </script>
  4. 談談你對webpack的瞭解

    參考連接:https://blog.csdn.net/NingZheYuan/article/details/80729174

    (1)概念

    • webpack是一個現代javascript應用程序的靜態模塊打包器,
    • webpack處理應用程序時他會遞歸的構建一個依賴關係圖,其中包含應用程序的每一個模塊,而後將這些模塊打包成一個或者多個build文件

    (2)入口enter

      告訴webpack 使用那個模塊 來做爲構建內部依賴圖的開始。進圖入口文件後,webpack會找到那些模塊和庫是入口起點(直接或者間接)的依賴。舉例:

    1 module.exports = {
    2   entry: './path/to/my/entry/file.js'    // 咱們的入口文件
    3 };

    (2)出口output

      告訴webpack從哪裏產出builds以及如何命名這些文件 默認值是 ./dist。這樣整個應用程序結構都會編譯到你指定的文件夾中。舉例:

    1 const path = require('path');
    2 
    3 module.exports = {
    4   entry: './path/to/my/entry/file.js',            // 入口文件
    5   output: {
    6     path: path.resolve(__dirname, 'dist'),        // 打包後的文件夾的名字及路徑
    7     filename: 'my-first-webpack.bundle.js'        // 打包後的js名稱
    8   }
    9 };

    (3)loader

    loder 讓webpack可以處理那些 非javascript 的文件(webpack自身只理解javascript)。loader能夠將全部類型文件轉換爲 webpack 可以處理的有效模塊,而後就能夠利用 webpack打包模塊 來對他們進行處理。
    本質上 webpack loader 是將 全部類型的文件 轉化爲 應用程序依賴圖(最終的bundle) 能夠直接進行引用。
    webpack loader 兩個參數:
    1. test 用於標識出應該被對應的 loader 進行轉換的 某個 或者某個文件
    2. use 標識轉換時應該使用那個loader
     1 const path = require('path');
     2 
     3 module.exports = {
     4   entry: './path/to/my/entry/file.js',            // 入口文件
     5   output: {
     6     path: path.resolve(__dirname, 'dist'),        // 打包後的文件夾的名字及路徑
     7     filename: 'my-first-webpack.bundle.js'        // 打包後的js名稱
     8   },
     9   module: {
    10     rules: [
    11       { test: /\.txt$/, use: 'raw-loader' }
    12     ]
    13   }
    14 };

    raw-loader webpack 的原始模將文件加載爲字符串

    (4)插件pligins

loader能夠用來轉換某些類型的模塊,而插件則能夠執行範圍更廣的任務.
插件的範圍包括:
1. 打包優化
2. 壓縮
3. 從新定義環境中的變量
使用一個插件 只須要 require 它。 而後給它添加到 plugins 數組中。 多數插件能夠經過 options 來定義。
注意:若是你在一個配置文件中屢次的使用同一個插件時,這時候須要經過new 操做符來重建一個新的實例。
 1 const webpack = require('webpack');
 2 const HtmlWebpackPlugin = require('html-webpack-plugin'); // html 須要npm 安裝一下
 3 const config = {
 4   module: {
 5     rules: [
 6       { test: /\.txt$/, use: 'raw-loader' }
 7     ]
 8   },
 9   plugins: [
10     new webpack.optimize.UglifyJsPlugin(),                // 壓縮js
11     new HtmlWebpackPlugin({template: './src/index.html'}) // 指定模板
12   ]
13 };

(5)模式

經過 developmentproduction 之中的一個 來設置 mode 參數, 來啓動 webpack 內置的優化

1 module.exports = {
2   mode: 'production'
3 };

 

5.原型模式建立對象過程

參考連接:https://blog.csdn.net/u010176097/article/details/80484890

(1)JS中prototype,__proto__,constructor的關係

 1 function Person(){
 2     Person.prototype.name='hj';
 3     Person.prototype.age=22;
 4     Person.prototype.say=function(){
 5         console.log('姓名:'+this.name+',年齡:'+this.age)
 6     }
 7 }
 8 var person1=new Person();
 9 var person2=new Person();
10 console.log(person1.__proto__==Person.prototype);//true
11 console.log(Person.prototype.constructor==Person);//true

JS中,當咱們建立一個函數的時候,就根據一組特定的規則給這個函數建立一個prototype屬性,這個屬性指向這個函數的原型對象。在默認狀況下,每一個原型對象都會自動得到一個constructor 屬性,這個屬性指向這個函數。    上面的代碼中,新建了一個Person對象,而後在Person的原型對象上(Person.prototype)添加了屬性和方法,Person的原型對象有個constructor屬性,指向Person。經過new Person()建立了兩個實例對象person1和person2,person1的__proto__指向的就是Person的原型對象。下圖代表了上述關係。

(2)在原型對象中查找值

 1 function Person(){
 2     Person.prototype.name='hj';
 3     Person.prototype.age=22;
 4     Person.prototype.say=function(){
 5         console.log('姓名:'+this.name+',年齡:'+this.age)
 6     }
 7 }
 8 var person1=new Person();
 9 var person2=new Person();
10 person1.say();//姓名:hj,年齡:22
11 person1.name="aaa";
12 person1.say();//姓名:aaa,年齡:22

在上面的代碼中,person1中也有個name屬性,在調用say方法時,會先在實例對象中查找name,若是有,返回name,若是沒有,則繼續在原型對象中查找,依次向上,直到找到或者沒找到返回null。雖然能夠經過對象實例     訪問原型對象中的值,可是卻不能經過實例對象重寫原型中的值。若是在實例對象中已經找到了name屬性,則自動屏蔽掉原型對象中的值。不過,經過delete操做符能夠刪除實例屬性屬性。                                                          (3) 檢測屬性是在實例中仍是原型對象中

使用hasOwnProperty()能夠檢測出實例對象是否具備某個屬性,若是是原型屬性統一返回false.

 1 function Person(){  2 Person.prototype.name='hj';  3 Person.prototype.age=22;  4 Person.prototype.say=function(){  5 console.log('姓名:'+this.name+',年齡:'+this.age)  6  }  7 }  8 var person1=new Person();  9 var person2=new Person(); 10 console.log(person1.hasOwnProperty("name"));//true 11 delete person1.name;//delete刪除person1的name屬性 12 console.log(person1.hasOwnProperty("name"));//false

 

6.display:none和visiblity:hidden的區別

相同:二者都能隱藏元素。

不一樣:

(1)display:none 不佔頁面空間,visiblity:hidden 佔據原先頁面空間。這裏必須說明的是,元素不佔頁面空間後,取該元素或其內部元素的寬高值永遠是0。若是想隱藏又想取到寬高值,那就得用visiblity:hidden。

(2)display:none 的子元素也必定沒法顯示,visiblity:hidden 的子元素能夠設置顯示。display:none元素及其子元素都將隱藏,而visiblity:hidden元素的子元素卻能夠設置visibility: visible 顯示出來。在這一點上,若是頁面是比較     複雜或者是不受控制的,就要慎重使用visiblity:hidden,由於保不齊哪一個元素被設置成可見,影響顯示效果。

(3)display:none 引發頁面重繪和迴流, visiblity:hidden 只引發頁面重繪。

visiblity:hidden 看起來性能比display:none好些,在二者都能使用狀況下,可先考慮visiblity:hidden。 

相關文章
相關標籤/搜索