2018前端面試題總結

CSS篇javascript

1. CSS 盒子模型,絕對定位和相對定位?css

  ① 盒模型html

 

  背景會應用於元素內容、內邊距、邊框三者組成的區域;前端

  margin值能夠設置爲負值,不少狀況下會須要使用margin負值;padding沒有負數;  vue

  瀏覽器的兼容性:IE5.X 和 6 在怪異模式中使用本身的非標準模型。這些瀏覽器的 width 屬性不是內容的寬度,而是內容、內邊距和邊框的寬度的總和。java

  目前最好的解決方案是迴避這個問題。也就是,不要給元素添加具備指定寬度的內邊距,而是嘗試將內邊距或外邊距添加到元素的父元素和子元素webpack

  ② 絕對定位和相對定位css3

  position:absolute | relative | fixed | static | inherit

  absolute:絕對定位;相對於除了static定位之外的第一個父元素進行定位;將元素從文檔流中拖出來,不佔用原來元素的空間,相對於其最接近的一個具備定位屬性的父級元素進行絕對定位

  relative:相對定位;生成相對定位的元素,相對於其正常位置進行定位。仍是會佔用該元素在文檔中初始的頁面空間。

  fixed:固定定位;生成絕對定位的元素,相對於瀏覽器窗口進行定位。

  static:默認值;

  inherit:繼承

  絕對定位會隱式改變元素的display類型,同元素設置float:left | right;時同樣,都會隱式將元素的display設置爲inline-block;git

  可是float在IE6下的雙邊距bug就是用display:inline; 來解決的。angularjs

2. 清除浮動,何時須要清除浮動,清除浮動都有哪些方法?

  浮動帶來的影響——父元素高度塌陷了,此時就須要來清楚浮動

清除浮動的方法:
    ① 爲父元素設置高度
        爲父元素定高,簡單粗暴,可是網頁製做中,不多出現高度height。由於盒子能被內容撐高!因此這種清除浮動的方法工做中用的不多
    ② 在父元素的最後設置clear:both
        缺點 在頁面中添加這麼多沒有意義的冗餘元素,太麻煩,並且不符合語義化。
    ③ 僞元素
        :after { 
            content:""; 
            display:table; 
            clear:both;
        }
    ④ 給父元素添加overflow:hidden
        能夠了解下 BFC 塊級格式化上下文
        添加overflow: hidden就能清除浮動的工做原理是:
        若是沒有明確設定容器高狀況下
        它要計算內容所有高度才能肯定在什麼位置hidden
        浮動的高度就要被計算進去
        順帶達成了清理浮動的目標
        同理
        overflow 非默認值
        position 非默認值
        float 非默認值
        等都是遵循這個佈局計算思路

3. 如何保持浮層水平垂直居中
 

// 下面列舉幾種經常使用的
<div class="parent">
    <div class="child">hello world-3</div>
</div>
① 思路:子元素絕對定位,距離頂部50%,左邊50%,而後使用css3         
    transform:translate(-50%,-50%)
    優勢:高大上,能夠在webkit內核的瀏覽器中使用
    缺點:不支持IE9如下 不支持transform屬性
    .parent {
        position: relative;
        height:300px;
        width: 300px;
        background: #FD0C70;
    }
    .parent .child {
        position: absolute;
        top: 50%;
        left: 50%;
        color: #fff;
        transform: translate(-50%, -50%);
    }
② 思路:使用css3 flex佈局
    優勢:簡單 快捷
    缺點:兼容性很差
    .parent {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 300px;
        height:300px;
        background: #FD0C70;
    }
    .parent .child {
        color:#fff;
    }
③ 這個方法使用絕對定位的 div,把它的 top 設置爲 50%,margin-top設置 
    爲負的 content 高度。這意味着對象必須在 CSS 中指定固定的高度。
    由於有固定高度,或許你想給 content 指定 overflow:auto,這樣若是 
    content 太多的話,就會出現滾動條,以避免content 溢出。
    優勢:適用於全部瀏覽器,不須要嵌套標籤
    缺點:沒有足夠空間時,content 會消失(相似div 在 body 內,當用戶縮小 
    瀏覽器窗口,滾動條不出現的狀況)
    .child {
        position: absolute;
        top: 50%;
        height: 240px;
        margin-top: -120px; /* 盒子自己高度的一半 */
    }
④ 這個方法使用了一個 position:absolute,有固定寬度和高度的 div。這個     
    div 被設置爲 top:0; bottom:0;。可是由於它有固定高度,其實並不能和 
    上下都間距爲 0,所以 margin:auto; 會使它居中。使用 margin:auto;使 
    塊級元素垂直居中是很簡單的。
    優勢:簡單粗暴,代碼簡單,其實設計者當初也根本沒想到也能這樣用,可是聰    
    明的你們硬是鑿出了一條簡單的路。
    缺點:IE(IE8 beta)中無效。無足夠空間時,content 被截斷,可是不會有    
    滾動條出現   
     .child {
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        margin: auto;
        height: 240px;
        width: 70%;
    }

 參考 http://www.javashuo.com/article/p-ccakqyrj-r.html

4. 樣式的層級關係,選擇器優先級,樣式衝突,以及抽離樣式模塊怎麼寫,說出思路,有無實踐經驗

  一、樣式的層級關係:一個是權重,另外一個就是共用樣式和私用樣式了,好比說兩個ul,它們的子元素除了背景色以外都同樣,那能夠直接用li {}來定義相同的公用樣式,用 .ul_1 li {} , .ul_2 li {} 來定義不相同的樣式。能夠根據元素之間的差異來選擇用哪一種方法。推薦用多層級的方式書寫css選擇器

  二、選擇器優先級:(!important>)id選擇器>class選擇器(屬性選擇器/僞類選擇器)>標籤選擇器(僞元素選擇器) 同類選擇符條件下層級越多的優先級越高。優先級就近原則,同權重狀況下樣式定義最近者爲準。載入樣式以最後載入的定位爲準。

  三、樣式衝突:   若是同個元素有兩個或以上衝突的CSS規則,瀏覽器有一些基本的規則來決定哪個很是特殊而勝出。
        選擇器同樣的狀況下後面的會覆蓋前面的屬性。
        使用嵌套選擇器時:
          一組嵌套選擇器的實際特性能夠計算出來。基本的,使用ID選擇器的值是100,使用class選擇器的值是10,每一個html選擇器的值是1。它們加起來就能夠計算出特性的值。
          p的特性是1(一個html選擇器)
          div p的特性是2(兩個html選擇器)
          .tree的特性是10(1個class選擇器)
          div p.tree的特性是1+1+10=12,(兩個html選擇器,一個class選擇器)
          #baobab的特性是100(1個ID選擇器)
          body #content .alternative p的特性是112(兩個html選擇器,一個ID選擇器,一個類選擇器)

            基本上,一個選擇器越多特性,樣式衝突的時候將顯示它的樣式。

  四、抽離樣式模塊
    由於瀏覽器的兼容問題,不一樣瀏覽器對有些標籤的默認值是不一樣的,若是沒對CSS初始化每每會出現瀏覽器之間的頁面顯示差別。固然,初始化樣式會對SEO有必定的影響,但魚和熊掌不可兼得,但力求影響最小的狀況下初始化。
        最簡單的初始化方法: * {padding: 0; margin: 0;} (強烈不建議)
        body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td { margin:0; padding:0; }
        body, button, input, select, textarea { font:12px/1.5tahoma, arial, \5b8b\4f53; }
        h1, h2, h3, h4, h5, h6{ font-size:100%; }
        address, cite, dfn, em, var { font-style:normal; }
        code, kbd, pre, samp { font-family:couriernew, courier, monospace; }
        small{ font-size:12px; }
        ul, ol { list-style:none; }
        a { text-decoration:none; }
        a:hover { text-decoration:underline; }
        sup { vertical-align:text-top; }
        sub{ vertical-align:text-bottom; }
        legend { color:#000; }
        fieldset, img { border:0; }
        button, input, select, textarea { font-size:100%; }
        table { border-collapse:collapse; border-spacing:0; }

6. css3動畫效果屬性,canvas、svg的區別,CSS3中新增僞類舉例
  動畫參考: https://blog.csdn.net/songchunmin_/article/details/54646090

   CSS3中新增僞類:https://blog.csdn.net/qq_41696819/article/details/81531494 

7. px和em和rem的區別,CSS中link 和@import的區別是?

px和em和rem的區別

PX特色
-1. IE沒法調整那些使用px做爲單位的字體大小;

-2. 國外的大部分網站可以調整的緣由在於其使用了em或rem做爲字體單位;

-3. Firefox可以調整px和em,rem,可是有大部分的國產瀏覽器使用IE內核。

px像素(Pixel)。相對長度單位。像素px是相對於顯示器屏幕分辨率而言的。(引自CSS2.0手冊)
em是相對長度單位。相對於當前對象內文本的字體尺寸。如當前對行內文本的字體尺寸未被人爲設置,則相對於瀏覽器的默認字體尺寸。(引自CSS2.0手冊)
任意瀏覽器的默認字體高都是16px。全部未經調整的瀏覽器都符合: 1em=16px。那麼12px=0.75em,10px=0.625em。爲了簡化font-size的換算,須要在css中的body選擇器中聲明Font-size=62.5%,這就使em值變爲 16px*62.5%=10px, 這樣12px=1.2em, 10px=1em, 也就是說只須要將你的原來的px數值除以10,而後換上em做爲單位就好了。

EM特色 -1. em的值並非固定的; -2. em會繼承父級元素的字體大小。 因此咱們在寫CSS的時候,須要注意兩點: -1. body選擇器中聲明Font-size=62.5%; -2. 將你的原來的px數值除以10,而後換上em做爲單位; -3. 從新計算那些被放大的字體的em數值。避免字體大小的重複聲明。 也就是避免1.2 * 1.2= 1.44的現象。好比說你在#content中聲明瞭字體大小爲1.2em,那麼在聲明p的字體大小時就只能是1em,而不是1.2em, 由於此em非彼em,它因繼承#content的字體高而變爲了1em=12px。
REM特色 rem是CSS3新增的一個相對單位(root em,根em),這個單位引發了普遍關注。這個單位與em有什麼區別呢?區別在於使用rem爲元素設定字體大小時,仍然是相對大小,但相對的只是HTML根元素。這個單位可謂集相對大小和絕對大小的優勢於一身,經過它既能夠作到只修改根元素就成比例地調整全部字體大小,又能夠避免字體大小逐層複合的連鎖反應。目前,除了IE8及更早版本外,全部瀏覽器均已支持rem。對於不支持它的瀏覽器,應對方法也很簡單,就是多寫一個絕對單位的聲明。這些瀏覽器會忽略用rem設定的字體大小。下面就是 一個例子: p {font-size:14px; font-size:.875rem;} 注意: 選擇使用什麼字體單位主要由你的項目來決定,若是你的用戶羣都使用最新版的瀏覽器,那推薦使用rem,若是要考慮兼容性,那就使用px,或者二者同時使用。

CSS中link 和@import的區別參考博客

 http://www.javashuo.com/article/p-bstehaet-h.html

8. 瞭解過flex嗎?

 參考文檔 Flex佈局教程

JavaScript篇

1. JavaScript 裏有哪些數據類型,解釋清楚原始數據類型和引用數據類型解釋清楚 null 和 undefined,。講一下 1 和 Number(1)的區別

  

  原始類型(基本類型):按值訪問,能夠操做保存在變量中實際的值。原始類型彙總中null和undefined比較特殊。

  引用類型:引用類型的值是保存在內存中的對象。

  undefeated和null:  

  Undefined類型
  Undefined只有一個值,即特殊的undefined,使用var聲明變量但未對其初始化時的值;
  使用已聲明但未初始化但變量,將獲得「undefined」;使用未聲明但變量,將會報錯;
  var message;  //聲明變量,但未初始化,默認值未undefined
  alert(message);  //彈出框將顯示message但值,即「undefined
  alert(age);   //將產生錯誤
  使用typeof操做符對已聲明但未初始化的變量和還沒有被聲明的變量所返回的值均未「undefined」
  var message;
  alert(typeof message);   //顯示undefeated
  alert(typeof age);  //顯示undefined
  即便未初始化的變量會自動賦予undefined值,但仍然推薦顯示但初始化變量,這樣在使用typeof操做符返回「undefined」值時,就能知道被檢測到的變量還未被聲明,而不是還沒有初始化;

  Null類型
  只有一個值,即特殊的null;
  邏輯角度看,null值表示一個空對象指針,因此 「typeof null「 返回的是「object」;
  若定義的變量準備在未來用於保存對象,則推薦將該變量初始化爲null,而不是其餘值;
  undefined值是派生自null值,因此「null == undefined「的值是true;
  不管在什麼狀況下都沒有必要吧一個變量顯式的設置爲undefined;只要意在保存對象的變量在尚未真正保存對象時都應該明確地設置爲null值;

  講一下 1 和 Number(1)的區別

  1是Number類型,是常量。
  Number(1)是對1執行Number類包裝,會對傳入的參數去兩側空格,去掉引號,若是是純數字,則返回純數字,不然返回NaN

  參考文檔:

   http://www.javashuo.com/article/p-dmwggppj-x.html

   http://www.javashuo.com/article/p-xncqcigm-bu.html

 

2.  講一下 prototype 是什麼東西,原型鏈的理解,何時用 prototype 

   prototype是函數對象上面預設的對象屬性

  1.JS中全部的東西都是對象,每一個對象都有prototype這個屬性,這個屬性是一個對象(object)

  2.JS中全部的東西都由Object衍生而來, 即全部東西原型鏈的終點指向Object.prototype。若是仍是再找不到,就返回null(Object.prototype.proto===null)

  3.JS中構造函數和實例(對象)之間有微妙的關係,構造函數經過定義prototype來約定其實例的規格, 再經過 new 來構造出實例, 他們的做用就是生產對象。而構造函數(方法)自己又是方法(Function)的實例, 所以也能夠查到它的__proto__(原型鏈)

  Object / function F(){} 這樣子的就是構造函數,一個是JS原生API提供的,一個是自定義的

  new Object() / new F() 這樣子的就是實例

  實例就"只能"查看__proto__來得知本身是基於什麼prototype被製造出來的,而"不能"再從新定義實例的prototype妄想創造出實例的實例了。

  原型

  是一個對象上面的原型,這個原型一般是它的構造器的prototype屬性

  原型鏈

function foo(){};
foo.prototype.z = 3;
var obj = new foo();

  經過new構造對象(實例)的特色是,obj的原型(prototype)指向了構造器的prototype屬性,也就是foo.prototype,而foo.prototype則指向了原始的Object.prototype,Object.prototype也有原型,爲null。這就是一整個原型鏈。

  何時用 prototype

  使用 prototype的好處是不會額外產生內存,全部實例化後的對象都會從原型上繼承這個方法。也就是須要一個子類擁有父類的某些特性(同種特性能夠覆蓋),又能夠添加本身的特性,而不會影響父類時候使用prototype。

  Prototype一般用來解決一個問題:對象的建立比較耗費資源。好比,對象建立的時候須要訪問數據庫、須要讀取外部文件、須要使用網絡,這些都是比較耗費時間和內存的。若是能夠用clone來解決,就方便多了。當須要建立不少 擁有相同屬性的對象時候須要clone。

3. 函數裏的this什麼含義,什麼狀況下用

 this是Javascript語言的一個關鍵字。它表明函數運行時,自動生成的一個內部對象,只能在函數內部使用。隨着函數使用場合的不一樣,this的值會發生變化。可是有一個總的原則,那就是this指的是,調用函數的那個對象 

  狀況一:純粹的函數調用
   這是函數的最一般用法,屬於全局性調用,所以this就表明全局對象Global。
      function test(){
        this.x = 1;
        alert(this.x);
      }
      test(); // 1
    爲了證實this就是全局對象,我對代碼作一些改變:
      var x = 1;
      function test(){
        alert(this.x);
      }
      test(); // 1
    運行結果仍是1。再變一下:
      var x = 1;
      function test(){
        this.x = 0;
      }
      test();
      alert(x); //0


    狀況二:做爲對象方法的調用
    函數還能夠做爲某個對象的方法調用,這時this就指這個上級對象。
      function test(){
        alert(this.x);
      }
      var o = {};
      o.x = 1;
      o.m = test;
      o.m(); // 1


    狀況三: 做爲構造函數調用
    所謂構造函數,就是經過這個函數生成一個新對象(object)。這時,this就指這個新對象。
      function test(){
        this.x = 1;
      }
      var o = new test();
      alert(o.x); // 1
    運行結果爲1。爲了代表這時this不是全局對象,對代碼作一些改變:
      var x = 2;
      function test(){
        this.x = 1;
      }
      var o = new test();
      alert(x); //2
    運行結果爲2,代表全局變量x的值沒變。


    狀況四: apply調用
    apply()是函數對象的一個方法,它的做用是改變函數的調用對象,它的第一個參數就表示改變後的調用這個函數的對象。所以,this指的就是這第一個參數。
      var x = 0;
      function test(){
        alert(this.x);
      }
      var o={};
      o.x = 1;
      o.m = test;
      o.m.apply(); //0
    apply()的參數爲空時,默認調用全局對象。所以,這時的運行結果爲0,證實this指的是全局對象。
    若是把最後一行代碼修改成
    o.m.apply(o); //1
    運行結果就變成了1,證實了這時this表明的是對象o。

4. apply和 call 什麼含義,什麼區別?何時用。

  call和apply都用於函數調用,和使用函數名直接調用不一樣,call和apply能夠指定一個額外的參數做爲函數體內的this對象。

  call採用不定長的參數列表,而apply使用一個參數數組。

  因爲call和apply能夠改變函數體內的this指向,所以一般被用來將一個對象原型上的方法應用到另外一個對象上。 

  參考文檔:

  https://www.cnblogs.com/nzbin/articles/9027036.html

5. 數組和對象有哪些原生方法,列舉一下,分別是什麼含義,好比鏈接兩個數組用哪一個方法,刪除數組的指定項和從新組裝數組(操做數據的重點)。

  數組

  pop 和 push
       Array .pop();    // 刪除數組最後一個元素,返回被刪除的元素
      Array .push(element1, ..., elementN);    // 在數組尾部插入1-N個元素,返回操做後數組的length
  經過這 pop 和 push ,就能把數組模擬成 堆棧(stack) 來進行操做。
  堆棧這種數據結構的特色,就是「後進先出」(LIFO, Last In First Out)。
  
  shift 和 unshift
       Array .shift();    //  刪除數組第一個元素,返回被刪除的元素
      Array .unshift(element1, ..., elementN) ;     // 在數組頭部插入1-N個元素,返回操做後數組的length
  利用 shift 和 unshift 則能夠實現 隊列(queue) 的操做。
  隊列的操做方式和堆棧相反,採用「先進先出」(FIFO, First-In-First-Out)。
  
  splice
      Array .splice(index , howMany[, element1[, ...[, elementN]]]);
       Array .splice(index);
  參數:
      index:規定從何處添加/刪除元素。
      owmany:規定應該刪除多少元素。
      elements:規定要添加到數組的新元素,從 index 所指的下標處開始插入。
  splice方法是對 pop、push、shift、unshift 的一個補充。
  返回值是被刪除的元素。
  
  reverse
      Array .reverse();    // 顛倒數組中元素的順序,並返回逆序後的數組
  
  sort
      Array .sort([compareFunction]);
  若是調用該方法時沒有使用參數,將按字母順序對數組中的元素進行排序。
  說得更精確點,是按照字符編碼的順序進行排序。
  若是想按照其餘標準進行排序,就須要提供比較函數,該函數要比較兩個值,而後返回一個用於說明這兩個值的相對順序的數字。比較函數應該具備兩個參數 a 和 b,其返回值以下:
  • 若 a 小於 b,在排序後的數組中 a 應該出如今 b 以前,則返回一個小於 0 的值。
  • 若 a 等於 b,則返回 0。
  • 若 a 大於 b,則返回一個大於 0 的值。
  concat

 

       Array.concat(value1, value2, ..., valueN);    // 連接2個或多個數組,並返回合併後的數組

 

  但有一個須要注意的地方,用下面的例子說明:
1 var arr = [1, 2, 3];
2 arr.concat(4, 5);                // return [1, 2, 3, 4, 5]
3 arr.concat([4, 5]);              // return [1, 2, 3, 4, 5]
4 arr.concat([4, 5], [6, 7]);      // return [1, 2, 3, 4, 5, 6, 7]
5 arr.concat(4, [5, [6, 7]]);      // return [1, 2, 3, 4, 5, [6, 7]]
  join
       string = Array.join(separator);   
  把數組中的全部元素放入一個字符串。其中,元素之間是經過指定的分隔符進行分隔的。
  默認的分隔符是逗號(,),返回值是合併後字符串。
1 [1, 2, 3].join();    // return "1,2,3"
  Array.join()方法,其實是String.splite()的逆向操做。
 

 

  slice

 

       Array.slice(begin[, end]);    // 數組中返回選定的元素
 

 

  toString 

 

       Array.toString();    // 這個就不說了,全部JavaScript都有toString這個方法

 

 

 

  indexOf 和 lastIndexOf    * [ECMAScript 5]

 

      Array.indexOf(searchElement[, fromIndex]);    // 從頭開始搜索

 

      Array.lastIndexOf(searchElement[, fromIndex]);    // 從尾開始搜索

 

  searchElement:須要搜索的值

 

  fromIndex:索引,指示搜索從哪裏開始
 
  forEach      * [ECMAScript 5]
       Array.forEach(callback[, thisArg]);    // 從頭至尾遍歷一次數組,併爲數組中的每一個元素,調用指定的函數
  參數:
      callback:遍歷數組時調用的函數
      thisArg:指定 callback 的做用域
  另外,callback會調用三個參數:
      value:數組元素
      index:數組索引
      array:數組自己
1 [1, 2].forEach(function(value, index, array) {
2      console.log(value, index, array); 
3 });
4 // return 
5 // 1 0 [1, 2]
6 // 2 1 [1, 2]
  Note:forEach是沒法經過break來中斷數組的遍歷。
  解決方法:利用try方法來拋出異常,終止遍歷。
複製代碼
1 try {
2     [1,2,3].forEach(function(val) {
3         console.log(val);
4         throw(e)
5     });
6 } catch(e) {
7     console.log(e);
8 }
複製代碼
 
  map      * [ECMAScript 5]
       Array.map(callback[, thisArg]);    // 遍歷數組元素,調用指定函數,並以數組返回全部結果
  參數:
      callback:遍歷數組時調用的函數
      thisObject :指定 callback 的做用域
  例子:
1 [1, 2, 3].map(function(num) {    // return [2, 3, 4]
2     return num + 1;
3 });
 
  filter       * [ECMAScript 5]
       Array.filter(callback[, thisObject]);    // 遍歷數組調用方法,知足條件(返回true)的元素,將被添加到返回值的數組中
  參數:
      callback:遍歷數組時調用的函數
      thisObject :指定 callback 的做用域
  例子:
1 [1, 2, 3].filter(function(num) {    // return [1]
2     return num < 2;
3 });

 

  every 和 some       * [ECMAScript 5]
       Array.every(callback[, thisObject]);    // 「與」
       Array.some(callback[, thisObject]);    // 「或」
  參數:
      callback:遍歷數組時調用的函數
      thisObject:指定 callback 的做用域
  every:當全部元素調用函數都返回true,結果才返回true,否則均返回false。
  some:當全部元素調用函數都返回false,結果才返回false,否則均返回true。
  一旦every和some的返回值肯定,就會馬上中止遍歷。
  例子:
1 [1, 2, 3]. every(function(num) {    // return false
2     return num > 1;
3 });
4 [1, 2, 3]. some(function(num) {    // return true
5     return num > 2;
6 });

 

  reduce 和 reduceRight      * [ECMAScript 5]
      Array.reduce(callback[, initialValue]);    // 使用指定的方法將數組元素進行組合,按索引從低到高(從左到右)
      Array.reduceRight(callback[, initialValue]);    // 使用指定的方法將數組元素進行組合,按索引從高到低(從右到左)
      參數:
      callback:遍歷數組時調用的函數
      initialValue:第一個次調用callback時傳入的previousValue
  另外,callback會調用四個參數:
       previousValue:到目前爲止的操做累積結果
      currentValue:數組元素
      index:數組索引
      array:數組自己
  例子:
1 [1, 2, 3]. reduce(function(x, y) {    // return 106
2     return x + y;
3 }, 100);

6. 怎樣避免全局變量污染?ES5嚴格模式的做用,ES6箭頭函數和ES5普通函數同樣嗎?

  怎樣避免全局變量污染?  

  方法一:只建立一個全局變量。

MYAPP.stooge = {
 "first-name": "Joe",
 "last-name": "Howard"
};

 

  方法二:使用閉包  

//建立函數,返回一個特權對象
var f3 = function() {
  var age = 18;
  return {
    name: "啊哈",
    age: age,
    gender: "男"
  }
}();
//獲取變量
f3.name = "啊哈";

對於閉包,還有一個方法,就是使用匿名自執行函數,其實這貨就是個如假包換的閉包,全部代碼寫在其中,在它內部聲明的變量所有都是局部變量,通常用來寫徹底獨立的腳本,好比jQuery,插件等。。。

(function() {
  //我在一個匿名自執行函數中
  //some code here...
})()

 

  方法三:0全局變量

  這個方法直接杜絕了全局變量,那就是不在全局聲明變量(包括隱式聲明全局變量);

 

  ES5嚴格模式的做用,ES6箭頭函數和ES5普通函數同樣嗎? 

  一、消除javascript語法的一些不合理、不嚴謹之處,減小一些怪異行爲;

      二、消除代碼運行的一些不安全性,促進代碼運行的安全;

      三、提升編譯器效率,增長運行速度;

      四、爲將來新版本的javascript作好鋪墊

      IE10\chrome\火狐等主流瀏覽器已經全面支持

  

  1)函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。

    (2)不能夠看成構造函數,也就是說,不可使用new命令,不然會拋出一個錯誤。

    (3)不可使用arguments對象,該對象在函數體內不存在。若是要用,能夠用 rest 參數代替。

  this對象的指向是可變的,可是在箭頭函數中,它是固定的。

7. JS 模塊包裝格式都用過哪些,CommonJS、AMD、CMD。定義一個JS 模塊代碼,最精簡的格式是怎樣。

  https://www.jianshu.com/p/bd4585b737d7

8. JS 怎麼實現一個類。怎麼實例化這個類。

  嚴格的說,JavaScript 是基於對象的編程語言,而不是面向對象的編程語言。
  在面向對象的編程語言中(如Java、C++、C#、PHP等),聲明一個類使用 class 關鍵字。
  例如:public class Person{}
  可是在JavaScript中,沒有聲明類的關鍵字,也沒有辦法對類的訪問權限進行控制。

  JavaScript使用函數來定義類。

  語法:
  function className(){
      // 具體操做
  } 

  說明:this關鍵字是指當前的對象

  建立對象(類的實例化)

  建立對象的過程也是類實例化的過程。
  在JavaScript中,建立對象(即類的實例化)使用 new 關鍵字。
  語法:
  new className();

面向對象編程的基本概念

  面向對象編程(Object Oriented Programming,OOP,面向對象程序設計) 的主要思想是把構成問題的各個事務分解成各個對象,創建對象的目的不是爲了完成一個步驟,而是爲了描敘一個事物在整個解決問題的步驟中的行爲。
  面向過程就是分析出解決問題所須要的步驟,而後用函數逐步實現,再依次調用就能夠了。

  面向對象與面向過程是兩種不一樣的編程思想,沒有哪種方式絕對完美,須要根據程具體項目來定。好比,開發一個小的軟件或網頁,工程量小,短期內就可完成,徹底能夠採用面向過程的開發方式,使用面向對象,反而會增長代碼量,減緩運行效率。 

  面向過程的編程語言(如C語言)不能建立類和對象,不能用面向對象的方式來開發程序;面向對象的編程語言(如Java、C++、PHP)保留了面向過程的關鍵字和語句,能夠採用面向過程的方式來開發程序。

  類的繼承

  一個類能夠繼承另外一個類的特徵,如同兒子繼承父親的DNA、性格和財產等,與現實生活中的繼承相似。

9. 理解閉包嗎?請講一講閉包在實際開發中的做用;閉包建議頻繁使用嗎?

  閉包:就是一個獲取並訪問某個做用域,可在外訪問或者自身內部訪問。

  最大的兩個做用

  1. 讀取函數內部變量

  2. 讓變量值始終保持在內存裏

function f1(){
    var n=999;
    nAdd=function(){n+=1}
    function f2(){
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999
  nAdd();
  result(); // 1000   

result實際上就是閉包f2函數。它一共運行了兩次,第一次的值是999,第二次的值是1000。這證實了,函數f1中的局部變量n一直保存在內存中,並無在f1調用後被自動清除。
爲何會這樣呢?緣由就在於f1是f2的父函數,而f2被賦給了一個全局變量,這致使f2始終在內存中,而f2的存在依賴於f1,所以f1也始終在內存中,不會在調用結束後,被垃圾回收機制(garbage collection)回收。
這段代碼中另外一個值得注意的地方,就是"nAdd=function(){n+=1}"這一行,首先在nAdd前面沒有使用var關鍵字,所以nAdd是一個全局變量,而不是局部變量。其次,nAdd的值是一個匿名函數(anonymous function),而這個匿名函數自己也是一個閉包,因此nAdd至關因而一個setter,能夠在函數外部對函數內部的局部變量進行操做

    • 管理私有變量和私有方法,將對變量(狀態)的變化封裝在安全的環境中

    • 將代碼封裝成一個閉包形式,等待時機成熟的時候再使用,好比實現柯里化和反柯里化

    • 須要注意的:

      • 因爲閉包內的部分資源沒法自動釋放,容易形成內存泄露 解決方法是,在退出函數以前,將不使用的局部變量所有刪除。

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

    建議不要深度的使用閉包,那樣的代碼很是難以維護以及理解。

10.說一下了解的js 設計模式,解釋一下單例、工廠、觀察者。

  須要瞭解的幾個設計模式:

  https://www.jianshu.com/p/c09cc339c85c

  // 1) 單例: 任意對象都是單例,無須特別處理

    var obj = {name: 'michaelqin', age: 30};

    // 2) 工廠: 就是一樣形式參數返回不一樣的實例
    function Person() { this.name = 'Person1'; }
    function Animal() { this.name = 'Animal1'; }

    function Factory() {}
    Factory.prototype.getInstance = function(className) {
        return eval('new ' + className + '()');
    }

    var factory = new Factory();
    var obj1 = factory.getInstance('Person');
    var obj2 = factory.getInstance('Animal');
    console.log(obj1.name); // Person1
    console.log(obj2.name); // Animal1

    //3) 代理: 就是新建個類調用老類的接口,包一下
    function Person() { }
    Person.prototype.sayName = function() { console.log('michaelqin'); }
    Person.prototype.sayAge = function() { console.log(30); }

    function PersonProxy() {
        this.person = new Person();
        var that = this;
        this.callMethod = function(functionName) {
            console.log('before proxy:', functionName);
            that.person[functionName](); // 代理
            console.log('after proxy:', functionName);
        }
    }

    var pp = new PersonProxy();
    pp.callMethod('sayName'); // 代理調用Person的方法sayName()
    pp.callMethod('sayAge'); // 代理調用Person的方法sayAge()

    //4) 觀察者: 就是事件模式,好比按鈕的onclick這樣的應用.
    function Publisher() {
        this.listeners = [];
    }
    Publisher.prototype = {
        'addListener': function(listener) {
            this.listeners.push(listener);
        },

        'removeListener': function(listener) {
            delete this.listeners[listener];
        },

        'notify': function(obj) {
            for(var i = 0; i < this.listeners.length; i++) {
                var listener = this.listeners[i];
                if (typeof listener !== 'undefined') {
                    listener.process(obj);
                }
            }
        }
    }; // 發佈者

    function Subscriber() {

    }
    Subscriber.prototype = {
        'process': function(obj) {
            console.log(obj);
        }
    }; // 訂閱者

    var publisher = new Publisher();
    publisher.addListener(new Subscriber());
    publisher.addListener(new Subscriber());
    publisher.notify({name: 'michaelqin', ageo: 30}); // 發佈一個對象到全部訂閱者
    publisher.notify('2 subscribers will both perform process'); // 發佈一個字符串到全部訂閱者

 

11.ajax 跨域有哪些方法,jsonp 的原理是什麼,若是頁面編碼和被請求的資源編碼不一致如何處理?

  跨域:

  瀏覽器對於javascript的同源策略的限制,例如a.cn下面的js不能調用b.cn中的js,對象或數據(由於a.cn和b.cn是不一樣域),因此跨域就出現了.

  上面提到的,同域的概念又是什麼呢??? 簡單的解釋就是相同域名,端口相同,協議相同

  同源策略:

  請求的url地址,必須與瀏覽器上的url地址處於同域上,也就是域名,端口,協議相同.

  跨域及幾種跨域方式:http://www.javashuo.com/article/p-ktjtcgkp-s.html   

 

  jsonp原理:http://www.javashuo.com/article/p-bbnotdik-ep.html

  若是頁面編碼和被請求的資源編碼不一致如何處理?

  描述:

  js編碼和頁面編碼不一致,致使提示變量未定義的解決方法 (2011-06-30 10:27:02)轉載▼
  標籤: js跨域 變量未定義 js編碼 it 分類: JS
  今天在測試項目的時候,因爲是和其餘站合做的,引用合做方的js文件,
  有個js函數調用,調用時會使用包含合做方js裏的變量,
  但是居然不兼容ie六、ie七、360等主流瀏覽器。那必須得解決是吧。
  本來覺得是跨域問題,若是是跨域問題,也應該提示沒權限,但是沒提示。

 

  提示的是某某變量未定義,我就百度了。 沒找到我想要的答案,
  靈機一動想到是否是編碼問題 。因而在js後加了 charset="utf-8" 這個 。

 

  發現還真好了。 。 繞了好些圈子 。 此次記下了。避免下次再遇到相似的情況。

 

  好比:http://www.yyy.com/a.html 中嵌入了一個http://www.xxx.com/test.js

 

  a.html 的編碼是gbk或gb2312的。 而引入的js編碼爲utf-8的 ,那就須要在引入的時候

 

  <script src="http://www.xxx.com/test.js" charset="utf-8"></script>
  同理,若是你的頁面是utf-8的,引入的js是gbk的,那麼就須要加上charset="gbk".
  ----------------------百度上搜到一個答案,不知道是否正確?---------------

  參考文檔:http://www.codes51.com/itwd/1198587.html

 開源工具

 1. 是否瞭解開源的架構工具 bower、npm、yeoman、gulp、webpack,有無用過,有無寫過,一個 npm 的包裏的 package.json 具有的必要的字段都有哪些(名稱、版本號,依賴)

  npm是什麼:http://www.javashuo.com/article/p-strgiqqz-gg.html

  gulp是工具鏈,能夠配合各類插件作js壓縮,css壓縮,less編譯等工做

  webpack是文件打包工具,能夠把項目的各類js文、css文件等打包合併成一個或多個文件

  bower是包管理器,用來管理你項目裏的那些外部依賴的。

 2. Git經常使用命令

  https://www.cnblogs.com/allanli/p/git_commands.html

計算機網絡基礎

1. 說一下HTTP 協議頭字段說上來幾個,是否儘量詳細的掌握HTTP協議。一次完整的HTTP事務是怎樣的一個過程?

    HTTP協議詳細總結:https://www.cnblogs.com/zrtqsk/p/3746891.htm

    

2.cookies 是幹嗎的,服務器和瀏覽器之間的 cookies 是怎麼傳的,httponly 的 cookies 和可讀寫的 cookie 有什麼區別,有無長度限制?請描述一下cookies,sessionStorage和localStorage的區別?  

  cookies 是幹嗎的?  

  網頁是沒有記憶的.一個用戶瀏覽同一個網站的不一樣的網頁將會被網站視爲徹底新的訪問者.當咱們瀏覽同一個網站的不一樣網頁時,會話cookie使得咱們正在訪問的網站能不用重複要求咱們提供已經給過的信息.

  cookie容許咱們在訪問多網頁的網站時無需重複驗證身份(如登陸).

  最多見的例子是電商網站的購物車, 當你訪問一個類目頁面,選擇一些商品,cookie會記住你的選擇,所以當你下單時購物車會有相應的商品.

  若是沒有cookie,當你下單時,新的頁面將不能記住你以前的選擇,購物車也將是空的.

  固然你能夠調整你的瀏覽器的cookie設置.

  持久型cookie是幹嗎的?

  當你將來訪問網站時持久cookie幫助網站記得你的信息.

  這可使得咱們更快,更方便的訪問網站,好比,咱們能夠不用再次登陸.

  除了登陸外,持久cookie使得其餘的一些網站特性成爲可能,如:語言選擇,主題選擇,菜單設定等.

  服務器和瀏覽器之間的 cookies 是怎麼傳的? 

      

  請描述一下cookies,sessionStorage和localStorage的區別?

1.存儲大小
  • cookie數據大小不能超過4k。
  • sessionStorage和localStorage 雖然也有存儲大小的限制,但比cookie大得多,能夠達到5M或更大。
2.有效時間
  • localStorage 存儲持久數據,瀏覽器關閉後數據不丟失除非主動刪除數據;
  • sessionStorage 數據在當前瀏覽器窗口關閉後自動刪除。
  • cookie 設置的cookie過時時間以前一直有效,即便窗口或瀏覽器關閉
3. 數據與服務器之間的交互方式
  • cookie的數據會自動的傳遞到服務器,服務器端也能夠寫cookie到客戶端
  • sessionStorage和localStorage不會自動把數據發給服務器,僅在本地保存。

 

 

整個過程大體以下:
1. 輸入URL,瀏覽器根據域名尋找IP地址
2. 瀏覽器發送一個HTTP請求給服務器,若是服務器返回以301之類的重定向,瀏覽器根據相應頭中的location再次發送請求
3. 服務器接受請求,處理請求生成html代碼,返回給瀏覽器,這時的html頁面代碼多是通過壓縮的
4. 瀏覽器接收服務器響應結果,若是有壓縮則首先進行解壓處理
5. 瀏覽器開始顯示HTML 
6. 瀏覽器發送請求,以獲取嵌入在HTML中的對象。在瀏覽器顯示HTML時,它會注意到須要獲取其餘地址內容的標籤。這時,瀏覽器會發送一個獲取請求來從新得到這些文件——包括CSS/JS/圖片等資源,這些資源的地址都要經歷一個和HTML讀取相似的過程。因此瀏覽器會在DNS中查找這些域名,發送請求,重定向等等…

那麼,一個頁面,到底是如何從咱們輸入一個網址到最後完整的呈如今咱們面前的呢?還須要瞭解一下瀏覽器是如何渲染的:

 

瀏覽器渲染引擎在獲取到內容後的基本流程:
1. 解析HTML
2. 構建DOM樹
3. DOM樹與CSS樣式進行附着構造呈現樹
4. 佈局
5. 繪製
上述這個過程是逐步完成的,爲了更好的用戶體驗,渲染引擎將會盡量早的將內容呈現到屏幕上,並不會等到全部的html都解析完成以後再去構建和佈局render樹。它是解析完一部份內容就顯示一部份內容,同時,可能還在經過網絡下載其他內容。

4.是否瞭解Web注入攻擊,說下原理,最多見的兩種攻擊(XSS 和 CSRF)瞭解到什麼程度。

  瞭解:http://www.javashuo.com/article/p-ewgzrrbk-cg.html

5.是否瞭解公鑰加密和私鑰加密。如何確保表單提交裏的密碼字段不被泄露。驗證碼是幹嗎的,是爲了解決什麼安全問題。

  公鑰和私鑰區別:http://www.javashuo.com/article/p-taqeofzx-cs.html

  驗證碼是幹嗎的,是爲了解決什麼安全問題:

  防止惡意註冊和暴力破解,所謂惡意註冊和暴力破解都是用軟件進行的。 人工註冊再快,也須要一項一項輸入資料,速度很慢,對服務器基本沒有影響。若是沒有驗證碼可使用軟件註冊的話,能夠同時運行成千上萬個線程,一次能註冊成千上萬個用戶,讓服務器的數據庫很快變得臃腫不堪,運行效率降低。 若是一個無聊的人或競爭對手對某網站懷有敵意,那麼這種方法很容易就能讓對方癱瘓。

6.編碼常識:文件編碼、URL 編碼、Unicode編碼 什麼含義。一個gbk編碼的頁面如何正確引 

  url編碼

      url編碼是一種瀏覽器用來打包表單輸入的格式,URL編碼遵循下列規則: 每對name/value由&;符分開;每對來自表單的name/value由=符分開。若是用戶沒有輸入值給這個name,那麼這個name仍是出現,只是無值。任何特殊的字符(就是那些不是簡單的七位ASCII,如漢字)將以百分符%用十六進制編碼,固然也包括象 =,&;,和 % 這些特殊的字符。其實url編碼就是一個字符ascii碼的十六進制。不過稍微有些變更,須要在前面加上「%」。好比「\」,它的ascii碼是92,92的十六進制是5c,因此「\」的url編碼就是%5c。那麼漢字的url編碼呢?很簡單,看例子:「胡」的ascii碼是-17670,十六進制是BAFA,url編碼是「%BA%FA」。

      escape(),encodeURI() 和 encodeURIComponent() 編碼函數是JavaScript編程中很是經常使用的幾個函數。

   Unicode編碼 : http://www.javashuo.com/article/p-khzalavw-bc.html

   文件編碼: http://www.javashuo.com/article/p-bkbstjrl-cg.html

前端框架

1.對 MVC、MVVM的理解?

MVC是一種架構模式,M表示Model,V表示視圖View,C表示控制器Controller:

  • Model負責存儲、定義、操做數據、從網絡中獲取數據(Struts中Service和Form);
  • View用來展現給用戶,而且和用戶進行交互;
  • Controller是Model和View的協調者,Controller把Model中的數據拿過來給View使用。Controller能夠直接與Model和View進行通訊,而View不能與Controller直接通訊。,當有數據更新時,Model也要與Controller進行通訊,這個時候就要用Notification和KVO,這個方式就像發廣播同樣,Model發信號,Controller設置接收監聽信號,當有數據更新是就發信號給Controller,Model和View不能直接通訊,這樣違背MVC設計原則。View與Controller通訊須要利用代理協議的方式,Controller能夠直接根據Model決定View的展現。View若是接受響應事件則經過delegate,target-action,block等方式告訴Controller的狀態變化。Controller進行業務的處理,而後再控制View的展現。 那這樣Model和View就是相互獨立的。View只負責頁面的展現,Model只是數據的存儲,那麼也就達到了解耦和重用的目的。

實例解析   UML圖:你們熟悉MVC的調用流程邏輯

2.vue、angularjs等相對於 jQuery在開發上有什麼優勢?

  • Vue比jQuery減小了DOM操做
  • Vue使用雙向綁定來處理表單問題,在使用多表單的頁面能夠更方便快捷的處理表單問題
  • 衆所周知jQuery的選擇器是十分損耗瀏覽器資源的,而Vue 2.0使用虛擬DOM則避開了這一缺點
  • 組件化的開發模式可使經常使用的模塊獨立起來,能夠複用

3.先後分離的思想了解嗎? 

 

  先後端先定義接口,好比約定只用json數據進行互相通訊。

  可是前臺的頁面跳轉,可能就是用前臺框架路由的概念去跳轉,跳轉後去 ajax請求後臺 得到新頁面須要的json數據。

  單寫前臺時 應該有模擬靜態數據的工具,支持只用前臺用靜態數據 去開發一套頁面。而後後臺開發好以後,把和後臺對接的接口數據 數據

  • 最大的好處就是前端JS能夠作很大部分的數據處理工做,對服務器的壓力減少到
  • 後臺錯誤不會直接反映到前臺,錯誤接秒較爲友好
  • 因爲後臺是很難去探知前臺頁面的分佈狀況,而這又是JS的強項,而JS又是沒法獨立和服務器進行通信的。因此單單用後臺去控制總體頁面,又或者只靠JS完成效果,都會難度加大,先後臺各盡其職能夠最大程度的減小開發難度。

  可參考:http://www.javashuo.com/article/p-gxkullaq-by.html

4.你上一個項目都用到了那些方法優化js的性能?

5.Vue的生命週期?

6.說一下你對vue和vuex的使用方法,vue的組件複用機制?

相關文章
相關標籤/搜索