前端常見面試題

1、HTML相關:

1. Html5 新增了哪些標籤?

佈局標籤:   header,  section,  footer,  article,  aside

表單標籤:   datalist, input:type=’week|date|time|datetime|number|search|url|tel|color|email|range’

多媒體標籤:  audio,  video
其餘標籤:   progress(進度條), meter

 

2. 行內元素和塊級元素的具體區別是什麼?

1、行內元素和塊級元素的區別css

  行內元素不會佔據整行,在一條直線上排列,都是同一行,水平方向排列;塊級元素會佔據一行,垂直方向排列。html

  塊級元素能夠包含行內元素和塊級元素;行內元素不能包含塊級元素。前端

  行內元素與塊級元素屬性的不一樣,主要是盒模型屬性上,行內元素設置width無效,height無效(能夠設置line-height),margin上下無效,padding上下無效。vue

 
 

2、行內元素和塊級元素的相互轉換html5

  行內元素轉化爲塊元素: display:block;node

  塊元素轉化爲行內元素: display:inline;jquery

 

3. 列舉幾個塊級標籤和行內標籤?

塊級標籤:div,  p,  h1~h6,  section,  header,f  ooter
行內標籤:span,  em(i),  strong(b),  u,  em(i),  a

 

4. 行內元素的padding 和margin 可設置嗎?

1 行內元素設置水平方向的padding 和margin 是能夠生效,可是設置垂直方向的padding 和margin 雖然看起來對標籤起做用,但實際並無對周圍元素產生任何影響,
因此行內元素設置垂直方向的padding和margin 是無效的.

 

5. 簡述readyonly 與disabled 的區別

readyonly 是設置表單元素爲只讀狀態;
disabled 是設置表單元素爲禁用狀態.

 

6. 哪些標籤都存在僞元素?

大部分容器標籤(大部分雙標籤)都有僞元素, iframe 沒有僞元素;
大部分單標籤都沒有僞元素, 可是img 有僞元素

 

7. 僞元素可使用js 來操做嗎?

js不能夠操做僞元素

 

8. Html5 的網頁爲何只須要寫<!DOCTYOE HTML>?

html5不基於SGML,所以不須要對DTD進行引用,可是須要doctype來規範瀏覽器的行爲(讓瀏覽器按照他們應該的方式來運行)
而HTML4.01基於SGML,因此須要對DTD進行引用,才能告知瀏覽器文檔所使用的文檔類型。

SGML(Standard Generalized Markup Language),即標準通用標記語言;DTD (Document Type Definition)規定了標記語言的規則,這樣瀏覽器才能正確地呈現內容。css3

 

2、CSS相關

9. px em rem 這三種長度單位的區別?

px是一個絕對單位;em和rem是一個相對單位, em參考的是當前元素的字體(font-size)大小, rem參考的是html元素的字體(font-size)大小.

 

10.CSS3 新增僞類有那些?

p:first-of-type 選擇屬於其父元素的首個<p>元素。
p:last
-of-type 選擇屬於其父元素的最後一個<p>元素。
p:nth
-child(2)選擇屬於其父元素的第二個子元素。
p:nth
-type-of(2)選擇屬於其父元素的第二個子元素p。
:enabled、:disabled 控制表單控件的禁用狀態。
:checked,單選框或複選框被選中。

 

11.談談css 選擇器優先級順序以及斷定標準?

優先級從低到高:
  通配符選擇器 < 標籤選擇器 < 類選擇器(屬性選擇器) < ID選擇器;
  行內樣式<使用!important 修飾的屬性優先級最高;
  若是兩個選擇器(屬性徹底相同)同時命中一個元素, 而且權重同樣,則書寫順序會影響優先級, 後一個選擇器的屬性會覆蓋前一個選擇器中相同的屬性.

 

12.position 幾個屬性的做用?

position 的常見四個屬性值: relative,absolute,fixed,static。通常都要配合"left"、"top"、"right"以及"bottom" 屬性使用。
  
1:static:默認位置,(static 元素會忽略任何top、bottom、left 或right 聲明)通常不經常使用。
 
 
2:relative:位置被設置爲relative 的元素,偏移的top,right,bottom,left 的值都以它原來的位置爲基準偏移。注意relative 移動後的元素在原來的位置仍佔據空間。
 
 
3:absolute:位置設置爲absolute 的元素,可定位於相對於包含它的元素的指定座標。意思就是若是它的父容器設置了position 屬性,而且position 的屬性值爲absolute 或者relative,
那麼就會依據父容器進行偏移。若是其父容器沒有設置position 屬性,那麼偏移是以body爲依據。注意設置absolute 屬性的元素在標準流中不佔位置。
4:fixed:位置被設置爲fixed 的元素,可定位於相對於瀏覽器窗口的指定座標。不論窗口滾動與否,元素都會留在那個位置。它始終是以body 爲依據的。注意設置fixed 屬性的元素在標準流中不佔位置。

 

13.position的relative、absolute與fixed區別?

relative 相對定位,以本身當前處於文檔流的位置爲基準設置偏移量,因此自身在文檔流會保持佔有固定的物理空間,而且物理空間的位置只受文檔流的影響,而不受自身設置偏移量(top/left這些)影響,
注意自身設置了margin這類非定位屬性也同樣改變其在文檔流的物理位置。

 

absolute 絕對定位,是相對於設置了position爲relative或者absolute最近的父級元素定位(body、html標籤也須要定位屬性才能做爲定位父級),若是沒有就是基於視窗定位,不佔文檔流的物理空間。

 

fixed 固定定位,是相對於瀏覽器視窗的,不佔文檔流的物理空間。

 

 

14.在一個頁面中給多個元素設置相同的id, 會致使什麼問題?

會致使經過js獲取dom元素的時候, 只能獲取到第一個元素, 後面的元素都沒法正常獲取.

 

15.用僞類實現一個上三角?

/*
爲除了上邊框之外的全部邊框設置相同的寬度
設置左右兩邊border設爲透明色
設置下border爲想要的顏色
設置該盒子的寬度爲0
*/
.triangle_border_up {
    border-left: 20px solid transparent;
    border-right: 20px solid transparent;
    border-bottom: 20px solid red;
    width: 0;
}

 

16.怎麼讓一個不定寬高的div,垂直水平居中?

方案一:transform
.parent {
    background: #DDD;
    width: 400px;
    height: 400px;
}

.son {
    position: relative;
    background: pink;
    width: 200px;
    height: 200px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

 

  方案二:flex 彈性佈局程序員

.parent {
    display: flex;
    justify-content: center;
    align-items: center;
    background: #DDD;
    width: 400px;
    height: 400px;
}

.son {
    background: pink;
    width: 200px;
    height: 200px;
}

 

  方案三:絕對定位es6

.parent {
    position: relative;
    background: #DDD;
    width: 400px;
    height: 400px;
}

.son {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background: pink;
    width: 200px;
    height: 200px;
    margin: auto;
}

 

 

17.清除浮動有哪些經常使用的方式?

額外標籤法: 在浮動元素的最後添加一個塊級標籤, 給其設置一個clear:both 的屬性(缺點:會在頁面上產生不少空白標籤);
給浮動元素的父元素設置高度:(缺點:不太靈活);
給浮動元素的父元素設置overflow:hidden;
使用僞元素法:(推薦使用):
/*給須要清除浮動的元素添加clear類*/
.clear:after{ content:
''; display:block; overflow:hidden; visibility:hidden; clear:both; }
 

 

18.讓兩個塊級元素在一行顯示有哪些作法?

設置顯示模式:display:inline|inline-block;

flex佈局: 給父元素設置display:flex;

使用浮動

 

19.如何設置一個元素在垂直方向居中?

首先不考慮代碼的靈活性, 可使用margin 外邊距或者padding 內邊距來實現元素在垂直方向居中顯示.具體能夠給父元素設置一個垂直方向的padding 內邊距; 

也能夠給須要垂直居中的子元素設置垂直方向的外邊距.其次若是這個須要垂直居中的元素是一個單行文本,則可使用行高等於標籤高度的方式來實現.

也可使用css3 中的flex 佈局, 使用align-items:center 設置元素在側軸(垂直方向)居中對齊.

也可使用絕對定位的方式, 設置元素在相對定位的父元素中垂直對齊.

 

20.說說圖片懶加載的原理?實際開發中用過哪些圖片懶加載的插件?

img 標籤在加載圖片的時候, 是經過請求src屬性所指向的文件來加載圖片的, 那若是img 標籤自己沒有src屬性的話, 那麼img標籤在渲染的時候,就不會加載圖片.
因此圖片懶加載的原理就是將img 標籤的src屬性暫時先改爲一個自定義的屬性, 這樣頁面在加載時就會不去自動加載圖片, 
當img標籤所在區域進入屏幕可視區域後, 從存放圖片路徑的自定義屬性中獲取圖片地址,並動態的設置給對應img標籤的src屬性, 
這樣瀏覽器就會自動請求對應的圖片資源, 也就實現了所謂的圖片懶加載.
圖片懶加載的插件有不少,大部分是基於jquery的, 好比jquery.lazyload. 固然vue中也有實現了圖片懶加載的插件, 好比vue-lazyload, vue的組件庫中也有圖片懶加載的組件.

 

21.css3 新增了那些新特性?

媒體查詢(@media);

transfrom系列:  translate 平移, scale 縮放,rotate 旋轉

動畫(animate);

過渡效果(transition);

flex彈性(伸縮)佈局;

盒模型計算方式:box-sizing:border-box;

線性漸變(linear-gradient),徑向漸變;

僞元素, 文字陰影(text-shadow), 邊框陰影(box-shadow), 圓角(border-radius)

 

22.display:none 和visibility:hidden 的區別?

 
 
display:none會讓元素從渲染樹中消失,渲染的時候不佔據任何空間;
visibility: hidden不會讓元素從渲染樹中消失,渲染的時候仍然佔據空間,只是內容不可見。
display: none會引起重排,而visiibility: hidden只會引起重繪。

 

display: none是非繼承屬性,子孫節點消失是因爲元素從渲染樹中消失形成,經過修改子孫節點的屬性沒法顯示;
visibility: hidden是繼承屬性,子孫節點消失是因爲繼承了hidden,經過設置visibility: visible,可讓子孫節點顯示。

 

3,讀屏器不會讀取display:none的元素內容,而會讀取visibility:hidden的元素內容。

 

 

23.Less 是什麼?

Less 是一門 CSS 預處理語言,它擴展了 CSS 語言,增長了變量、Mixin、函數等特性,使 CSS 更易維護和擴展。Less 能夠運行在 Node 或瀏覽器端。
 
 
在less中能夠定義一些變量和表達式以及使用嵌套語法; 
less 中使用@定義變量(@baseColor:pink); 
後期能夠經過一些編譯工具(less)將less 編譯成瀏覽器能直接識別的 css 樣式. 
因此less 只是在開發階段使用的一種中間語言, 使用 less 的目的是提升開發效率以及提升代碼的可維護性.

 

24.Scss 是什麼?(sass)

Sass 是一款強化 CSS 的輔助工具,它在 CSS 語法的基礎上增長了變量 (variables)、嵌套 (nested rules)、混合 (mixins)、導入 (inline imports) 等高級功能,
這些拓展令 CSS 更增強大與優雅。使用 Sass 以及 Sass 的樣式庫(如 Compass)有助於更好地組織管理樣式文件,以及更高效地開發項目。
CSS, Sass, SCSS 三者之間的關係請參考:https://www.cnblogs.com/wphl-27/p/9765647.html
 
 

scss 是一種css 預處理語言, 在less中能夠定義一些變量和表達式以及使用嵌套語法; scss 中使用$定義變量($baseColor:pink); 後期能夠經過一些編譯工具(node
-sass)將less 編譯成瀏覽器能直接識別的css 樣式. 因此scss 只是在開發階段使用的一種中間語言, 使用scss 的目的是提升開發效率以及提升代碼的可維護性.

 

25.Stylus 是什麼?(.styl)

Stylus 是一個高效、動態以及豐富的 CSS 預處理器。它同時支持縮進的和通俗的兩種風格的 CSS 語法風格。

在stylus 中能夠定義一些變量和表達式以及使用嵌套語法(stylus 中是使用縮進的語法表示嵌套關係);
後期能夠經過一些編譯工具(stylus)將stylus 編譯成瀏覽器能直接識別的css 樣式.
因此stylus 只是在開發階段使用的一種中間語言,使用stylus 的目的是提升開發效率以及提升代碼的可維護性.

 

3、JavaScript基礎相關:

26.js 中有哪些數據類型

7 種原始類型:
  Boolean
  Null
  Undefined
  Number
  BigInt(現提案階段)
  String
  Symbol(ES6新增)
和 Object

 

27.typeof(typeof()) 和instanceof 的區別?

typeof:     能夠判斷變量的數據類型,返回值是字符串;
instanceof:   a instanceof b 用於判斷b是否是在a的原型鏈上, 也能夠實現判斷數據類型, 返回值爲布爾值.

 

28.怎麼判斷兩個對象相等?

先判斷倆者是否是對象;
再判斷倆個對象的全部key 值是否相等相同;
最後判斷倆個對象的相應的key 對應的值是否相同

 

29.js 中函數有哪些定義方式

函數聲明:function fn(){}
函數表達式:var fn=function(){}
構造函數:var fn=new Function(‘參數1’,’參數2’,’函數體’)

 

30.js 中函數有哪些調用形式?

普通函數,對象的方法,事件處理函數,構造函數,回調函數

 

31."==" 和"===" 的區別?

==只會對值進行比較,===不只會對值進行比較,還會對數據類型進行比較.

 

32.js 中的經常使用內置對象有哪些?並列舉該對象的經常使用方法?

1.Math(數學相關)
  Math.abs(x);           返回指定數值的絕對值
  Math.radom();          返回0到1之間的僞隨機數
  Math.ceil(x);          向上取整
  Math.sqrt(x);          返回指定數值的平方根
  Math.pow(x,y);          返回x的y次冪
  Math.max(a,b,c,...);      返回給定的一組數字中的最大值。若是給定的參數中至少有一個參數沒法被轉換成數字,則會返回NaN

 

2.Date(日期相關)
  Date.now();             返回自 1970-1-1 00:00:00  UTC(世界標準時間)至今所通過的毫秒數
  Date.prototype.getTime();    返回從1970-1-1 00:00:00 UTC(協調世界時)到該日期通過的毫秒數,對於1970-1-1 00:00:00 UTC以前的時間返回負值
  Date.prototype.getFullYear()  根據本地時間返回指定日期對象的年份(四位數年份時返回四位數字)
  Date.prototype.getMonth();   根據本地時間返回指定日期對象的月份(0-11)
  Date.prototype.getDate();    根據本地時間返回指定日期對象的月份中的第幾天(1-31)
  Date.prototype.getHours();   根據本地時間返回指定日期對象的小時(0-23)
  Date.prototype.getMinutes();  根據本地時間返回指定日期對象的分鐘(0-59)
  Date.prototype.getSeconds();  根據本地時間返回指定日期對象的秒數(0-59)

 

3.Array(數組相關)
  Array.from();           從類數組對象或者可迭代對象中建立一個新的數組實例
  Array.isArray();         用來判斷某個變量是不是一個數組對象
  Array.of();            根據一組參數來建立新的數組實例,支持任意的參數數量和類型
  Array.prototype.push();     在數組的末尾增長一個或多個元素,並返回數組的新長度
  Array.prototype.reverse();   顛倒數組中元素的排列順序,即原先的第一個變爲最後一個,原先的最後一個變爲第一個
  Array.prototype.pop();      刪除數組的最後一個元素,並返回這個元素
  Array.prototype.splice();    該方法經過刪除或替換現有元素或者原地添加新的元素來修改數組,並以數組形式返回被修改的內容。此方法會改變原數組

 

4.Object(對象相關)
  Object.prototype.toString()  返回對象的字符串表示
  Object.is();           比較兩個值是否相同。全部 NaN 值都相等(這與==和===不一樣)
  Object.keys();          返回一個包含全部給定對象自身可枚舉屬性名稱的數組
  Object.values();         返回給定對象自身可枚舉值的數組
  Object.seal();          防止其餘代碼刪除對象的屬性

 

 

33.列舉和數組操做相關的方法

push: 將元素添加到數組的末尾, 返回值是數組長度
pop: 將數組最後一個元素彈出, 返回值是被彈出的元素
unshift: 在數組的開頭插入一個元素,返回值是數組的長度
shift: 將數組第一個元素彈出,返回值是被彈出的元素
splice(index,len): 刪除數組中指定元素
concat: 鏈接數組
reverse: 翻轉數組

 

34.列舉和字符串操相關的方法

substr(start,len)/substring(start,end): 截取字符串
slice:從數組字符串中截取一段
indexOf/lastIndexOf:查找某一個字符是否存在於另一個字符串中, 存在則返回索引, 不存在則返回-1;indexOf 是從前向後順序查找;lastIndexOf是從後向前查找
replace:替換字符串特定的字符
toUpperCase:將字符串轉成大寫
toLowerCase:將字符串轉成小寫
charAt:獲取字符串中指定索引的字符

 

35.document.write 和innerHTML 的區別?

document.write 是指定整個頁面區域的內容, innerHTML 是指定某一個元素的內容.

 

36.分別闡述split(),slice(),splice(),join()?

split 可使用一個字符串切割另一個字符串, 返回值是數組;
slice 能夠從數組中截取一部分(字符串對象也有slice 方法);
splice(index,len)能夠刪除指定的數組元素;
join 能夠將數組元素使用特定的鏈接符拼接成字符串;

 

37.JavaScript的強制類型轉換?

轉化成字符串:toString() 、String() 、+拼接
轉換成數字:Number() 、parseInt()、parseFloat();
轉換成布爾類型:Boolean()

 

38.如何判斷一個變量foo 是數組?

foo instanceof Array;
foo.constructor == Array;
Array.isArray(foo)
Object.prototype.toString.call(foo)=="[object Array]"

 

3、JavaScript基礎相關:

39.什麼是原型對象?

每個構造函數都有一個prototype的屬性,這個屬性的值是一個對象,這個對象就叫作構造函數的原型對象; 
通常建議將構造函數的成員屬性綁定在原型對象prototype上,由於原型對象prototype身上的屬性默承認以經過實例對象訪問到;
這樣作能夠保證在每次經過new關鍵字建立實例對象的時候,這些方法不會被重複在內存中建立.

 

40.什麼是原型鏈?

每一個構造函數都有一個prototype 屬性, 即原型對象, 經過實例對象的___proto___屬性也可訪問原型對象;
而原型對象本質也是一個對象, 是對象就有本身的原型對象, 最終造成的鏈狀的結構稱爲原型鏈.

 

41.什麼是構造函數?

構造函數本質也是一個函數, 只不過這個函數在定義的時候首字母通常須要大寫; 構造函數調用的時候,必須經過一個new關鍵字來調用; 
咱們通常不直接使用構造函數, 而是使用構造函數建立出來的實例對象. 構造函數是js 面向對象的一個重要組成部分.

 

42.js 中實現繼承的方式?

ES6 以前官方並無提供一種實現繼承的語法, 因此大部分繼承方式都是程序員經過代碼在模擬,常見的繼承方式有如下幾種:
  1.原型繼承;
  2.借用構造函數繼承;
  3.組合繼承;
  4.
ES6 以後使用extends 關鍵字實現繼承(class Student extendsPerson{})

 

43.什麼是閉包, 有什麼做用, 使用的時候須要注意什麼?

閉包是一個跟函數相關的概念,表現形式是一個父函數內部,嵌套了一個子函數, 子函數直接或間接的被返回給外部做用域, 而且子函數中會使用到父函數局部做用域中的變量.當咱們在外部調用這個子函數的時候, 就會發生閉包現象.
閉包的定義:閉包是指有權訪問另外一個函數做用域中的變量的函數。
閉包的做用:閉包能夠延展一個函數的做用域
注意事項:不能濫用閉包, 會致使內存泄漏

 

44.什麼是內存泄漏, 哪些操做會引發內存泄漏?

內存泄漏是指本應該被垃圾回收機制回收的內存空間因爲某種特殊緣由沒有被及時回收,濫用全局變量和濫用閉包都會致使內存泄漏.

 

45.什麼是預解析?

JS 代碼在執行以前,解析引擎會對代碼進行一個預先的檢查, 主要會對變量和函數的聲明進行提高, 將變量和函數的聲明提到代碼的最前面,變量只提高聲明,不提高賦值.

 

46.說說你對this 關鍵字的理解

this的定義:this表示當前執行代碼的環境對象
this在不一樣的場景下指向不太同樣, 主要分爲如下幾種狀況:   普通函數中指向全局對象window;   對象的成員方法中指向該方法的宿主對象;   構造函數中指向new出來的實例對象;   事件處理函數中指向事件源;   回調函數中指向全局對象window

 

47.call/apply/bind 的區別

這三個方法都是Function這個特殊對象的方法,經過這三個方法均可以改變函數內部this的指向.
不一樣點:   call 和apply 會調用一次函數, 而bind 不會調用函數, 只會在內存中建立一個函數的副本(修改過this指向的函數).   call 從第二個參數開始須要一個參數列表,   apply 的第二個參數要求是一個數組

 

48.new 操做符具體幹了什麼呢?

第一步:  建立一個空對象;
第二步:  將this 指向空對象;
第三步:  動態給剛建立的對象添加成員屬性;
第四步:  隱式返回this

 

49. 下面代碼的執行結果是什麼?

var helloWord=(function(){
  console.log('hello one');
  setTimeout(function(){
  console.log('hello two');
},100);
setTimeout(function(){
  console.log('hello three');
},0);
console.log('hello four');
}());

依次輸出: hello one,hello four,hello three,hello two

 

 

50. 下面代碼執行結果是什麼?

var a={
  id:10
}
b=a;
b.id=1;
b.name='test';
console.log(a);
輸出{id: 1, name: "test"}
 
分析過程:對象是一種引用數據類型, 簡單的b=a 只是把a 在內存中的地址賦值給了b, 因此修改b 會影響a.
 

 

51. 下面代碼執行結果是什麼?

var length=10;
function fn(){
  console.log(this.length);
}
var obj={
  length:5,
  method:function(fn){
    fn();
    arguments[0]();
  }
}
obj.method(fn,1);
執行結果:在控制檯輸出10,2

 

分析過程:
  fn(); 此時this 指向window, 因此this.length=10;
  arguments[0]()中的this 永遠指向arguments,而arguments自己有一個length 屬性,就是參數的個數.

 

 

52. 下面代碼執行完畢, 瀏覽器依次彈出什麼?

(function test(){
  var a=b=5;
  alert(typeof a);
  alert(typeof b);
})()
alert(typeof a);
alert(typeof b);
執行結果:依次彈出: number; number,undefined,number

 

分析過程:自調用函數會開闢一個局部做用域, var a=b=5 這句代碼var只會修飾a,因此a是一個局部變量, b是全局變量

 

 

53. 下面代碼輸出結果是什麼?

[1,2,3].map(function(item,index){
  // console.log(item,index);
  //parseInt(數值,進制)
  parseInt(1,0);
  parseInt(2,1);
  parseInt(3,2);
});
[1,2,3].map(parseInt);
輸出結果:[1,NaN,NaN];
 

 

54. 下面代碼執行結果是什麼?

console.log(square(5));
var square=function(n){
  return n*n;
}
執行結果:報錯(Uncaught TypeError: square is not a function)
分析過程:函數表達式方式聲明的函數只提高聲明, 不提高賦值, 因此不能再聲明以前調用.
 

 

55. 下面代碼執行結果是什麼?

console.log(2.0=='2'==new Boolean(true)=='1');
執行結果: 輸出true
分析過程: 2.0==’2’ 返回true;   true==new Boolean(true) 返回true;  true==’1’返回true;   因此最終結果是true.

 

 

56. 下面的代碼會輸出什麼?怎麼改動下面代碼, 使其依次輸出1,2,3,4,5

for(var i=1;i<=5;i++){
    setTimeout(function(){
        console.log(i);
    },1000);
}
執行結果:在控制檯輸出:6,6,6,6,6,緣由在於setTimeout中的代碼是異步執行的,
在該例子中,不論延時時間長或短,log語句老是會在循環結束後纔打印i的值,而此時i早已完成循環遞增,變爲了終值6
 
 

改造後的代碼:

for (var i = 1; i <= 5; i++) {
    (function (i) {
        setTimeout(function () {
            console.log(i);
        }, 1000*i)
    })(i)
}
或者使用es6 let聲明變量i
for (let i = 1; i <= 5; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000 * i)
}
 
 
 

 

57. 下面代碼執行結果是什麼?

var a=10;
function Foo(){
    if(true){
        let a=4;
    }
    alert(a);
}
Foo(); 
執行結果: 彈出10
分析過程: let聲明的變量有塊級做用域, 因此let聲明的a只在if條件的花括號中生效, 因此會向上級做用域查找.
 

 

58. 使用js 封裝一個冒泡排序

// 方案1
function sortBubble(arr){
  for(var i=0;i<arr.length;i++){
        for(var j=0;j<arr.length-i;j++){
            if(arr[j]>arr[j+1]){
              var temp=arr[j];
          arr[j]=arr[j+1];
         arr[j+1]=temp;
        }
       }
  return arr;
}

 

//方案2
function sortBubble(ary) {
    for (var i = 0; i < ary.length - 2; i++) {
        for (var j = i + 1; j < ary.length; j++) {
            if (ary[i] > ary[j]) {
                temp = ary[i];
                ary[i] = ary[j];
                ary[j] = temp;
            }
        }
    }
    return ary;
}

 

//方案3(單重循環)
function sortBubble(ary) {
    for (var i = 0, j = i + 1; i < ary.length - 2; j++) {
        if (ary[i] > ary[j]) {
            temp = ary[i];
            ary[i] = ary[j];
            ary[j] = temp;
        }
        if (j == ary.length - 1) {
            i++;
            j = i + 1;
        }
    }
    return ary;
}

 

 

59. 封裝一個方法實現去除數組中的重複元素

方案1:
function unique(arr){
  var newArr=[];
  for(var i=0;i<arr.length;i++){
    if(newArr.indexOf(arr[i])==-1){
      newArr.push(arr[i]);
    }
  }
  return newArr;
}

 

 方案二:

var arr = [1,2,2,3,3,4];
var newArr = Array.from(new Set(arr));

分析過程:
Set是es6中新增的一種數據類型,和數組很相似,可是元素不能重複;
Array.from也是es6新增的方法,能夠將類數組對象(僞數組、set),轉換成數組.

 

 

60. 已 知 數 組 var arr=[‘This’, ’is’, ‘Woqu’, ‘Company’], alert 出 」This is Woqu Company」.

var arr=[‘This’, ’is’, ‘Woqu’, ‘Company’];
alert(arr.join(' '));alert(arr.join(' '));

 

61. 編寫一個 js 函數 parseQueryString, 它的用途是把 url 中的參數解析爲一個對象, 如」http://www.demo.cn/index.html?key1=val1&key2=val2」

var url = "http://www.demo.cn/index.html?key1=val1&key2=val2";

function parseQueryString(argu) {
    var str = argu.split('?')[1];
    var result = {};
    var temp = str.split('&');
    for (var i = 0; i < temp.length; i++) {
        var temp2 = temp[i].split('=');
        result[temp2[0]] = temp2[1];
    }
    return result;
}

console.log("解析url參數:", parseQueryString(url));

 

62. 統計 'gjhgadfgskgjfajhdegwqeg'字符串中出現最多的字母?

var str = 'gjhgadfgskgjfajhdegwqeg';

function countStr(str) {
var json = {};
var iMax = 0;
var iIndex = '';
// 循環完畢後會獲得一個對象,如{a:0,b:1,c:2,d:3,e:4} for (var i = 0; i < str.length; i++) { if (!json[str.charAt(i)]) { json[str.charAt(i)] = 1; } else { json[str.charAt(i)]++; } }; // 查找出現次數作多的字符,和出現次數 for (var i in json) { if (json[i] > iMax) { iMax = json[i]; iIndex = i; } } return { count: iMax, //出現的最屢次數 char: iIndex //出現次數最多的字符 } } console.log("字符統計:", countStr(str));

 

63. 編碼實現對象深拷貝

function deepClone(obj) {
    let cloneObj = null;
    if (obj instanceof Object) {
        let isArray = Array.isArray(obj);
        cloneObj = isArray ? [] : {};
        for (let key in obj) {
            cloneObj[key] = obj[key] instanceof Object ? deepClone(obj[key]) : obj[key];
        }
    } else {
        throw new Error('obj 不是一個對象!');
    }
    return cloneObj;
}

 

64. 有 Student 和 Person 兩個類, Person 類有 name 屬性和 sayName 方法, Student 類繼承自 Person 類. 分別使用 ES5 和 ES6 的語法實現.

ES6 實現:
//定義父類
class Person {
    //父類構造方法
    constructor(name) {
        this.name = name;
    }

    //父類定義方法
    sayName() {
        console.log("The name is: " + this.name);
    }
}

//定義子類
class Student extends Person {
    //子類構造方法
    constructor(name, age) {
        super(name);
        this.age = age;
    }

    //子類定義方法
    showAge() {
        console.log("The age = " + this.age);
    }
}

//建立父類對象
let person = new Person("zs");
person.sayName();

//建立子類對象
let student = new Student("ls", 20);
student.sayName();
student.showAge();

 

ES5 實現:

//父類構造函數
function Person(name) {
    this.name = name;
}
Person.prototype.sayName = function() {
    console.log(`My name is ${this.name}`);
}

//子類構造函數
function Student(name, age) {
    Person.call(this, name);
    this.age = age;
}
//將子類原型對象指向一個父類對象以繼承父類的屬性和方法
Student.prototype = new Person();
//將子類自定義方法掛載到原型對象上
Student.prototype.showAge = function() {
    console.log(`My age is ${this.age}`)
};
//將原型對象的constructor指回子類構造函數自己以修正子類原型對象的指向錯誤
Student.prototype.constructor = Student;

//建立父類對象
let person = new Person("zs");
person.sayName();

//建立子類對象
let student = new Student("ls", 20);
student.sayName();
student.showAge();

 

 

65. 寫一個左中右佈局佔滿屏幕, 其中左右兩塊固定寬度 200,中間自適應,要求先加載中間塊, 請寫出結構和樣式

Css 樣式
<style>
    * {
        padding: 0;
        margin: 0;
    }
    
    html,
    body {
        height: 100%;
    }
    
    .center {
        height: 100%;
        background: #1FA363;
        margin: 0 200px;
    }
    
    .left {
        position: absolute;
        width: 200px;
        height: 100%;
        left: 0;
        top: 0;
        background: #DC4C3F;
    }
    
    .right {
        position: absolute;
        width: 200px;
        height: 100%;
        right: 0;
        top: 0;
        background: #FFCE44;
    }
</style>

html 結構:

<body>
    <div class="center">center</div>
    <div class="left">left</div>
    <div class="right">right</div>
</body>
思路分析: html 標籤的加載順序是自上而下, 因此要想讓中間部分先加載, 只須要把中間部分的標籤寫在最前面便可.

 

 

66. 如何擴展 jquery 的靜態方法, 如$.getName();

$.extend({
    getName: function () {
        // do something
    }
});

 

67. 使用 js 求 10000 之內的全部質數的和

求 10000 之內的全部質數的和
//求質數和
function getZs(num) {
    var sum = 0;
    for (var i = 2; i <= num; i++) { //4
        //假設全部的數都是質數
        var flag = true;
        //經過嵌套循環找到 i 除了 1 和自己之外全部可能出現的因子
        for (var j = 2; j < i; j++) {
            //判斷 i 是否爲質數
            if (i % j == 0) { //能進到當前的分支 說明不是質數
                flag = false;
            }
        }
        if (flag == true) {
            sum += i;
        }
    }
    return sum;
}
console.log("10000之內的素數和= ", getZs(10000));
輸出指定範圍內的素數(優化寫法)
//輸出指定範圍內的素數
function getPrimenumber(n) {
    var flag = 0;
    var result = [2, 3];
    for (i = 3; i <= n; i += 2) {
        for (j = 2; j <= Math.sqrt(i); j++) {
            if (i % j == 0) {
                flag = 0;
                break;
            } else {
                flag = 1;
            }
        }
        if (flag == 1) {
            result.push(i);
            flag = 0;
        }
    }
    return result;
}

 

 

68. 使用js 打印出1-10000 之間的全部對稱數(如121, 1331)

function isSymNum(start, end) {
    start = (start <= 11 ? 11 : start);
    for (var i = start; i <= end; i++) {
        var strI = +(i.toString().split('').reverse().join(''));
        if (strI == i) {
            console.log(i);
        }
    }
}
isSymNum(1, 10000);

 

69. 二維數組根據num 的值進行升序排序

var list = [{id: 32,num: 5}, {id: 28,num: 12}, {id: 23,num: 9}];
list.sort(function(a, b) {
return a.num - b.num; }) console.log(list);

 

70. Js 中eval 的功能是什麼? 缺點是什麼?

eval 函數的做用: 能夠將一個字符串當作js 代碼執行.
eval 函數的缺點: 執行效率比較低, 不安全.

 

71. 有一個數列(0,1,1,2,3,5,8,13,21...),定義函數求數列第n項 (斐波那鍥數列)

function getFibo(n) {
     if (n == 1) return 0;
     if (n == 2) return 1;
     return getFibo(n - 1) + getFibo(n - 2);
}

 

72. 使用什麼辦法能讓以下條件判斷成立?

if(a==1&&a==2&&a==3){
    console.log('ok')
}

//方案一:
var a = {
    value: 1,
    toString: function() {
        return this.value++;
    }
}
 
 

 

//方案二:
var
a = [1, 2, 3]; a.join = a.shift;
//數組做隱式轉換時會自動調用join方法,能夠將join方法替換爲shift方法以達到目的

 

//方案三:
var init = 1;
Object.defineProperty(window, 'a', {
    get: function() {
        return init++;
    }
});
 

 

73. 下面代碼輸出結果是什麼?

function changeObjectProperty(o) {
    o.siteUrl = "http://www.csser.com/";
    o = new Object();
    o.siteUrl = "http://www.popcg.com/";
}
var CSSer = new Object();
changeObjectProperty(CSSer);
console.log( CSSer.siteUrl );

結果:
http://www.csser.com/
 

 

4、WebAPI相關:

74.列舉DOM 元素增刪改查的API

建立DOM: document.createElement();
 
 
查找DOM:
    document.getElementById();
    document.getElementsByClassName();
    document.getElementsByName();
    document.querySelectorAll();
    document.querySelector();

 

追加DOM: parentDom.appendChild();

 

移除DOM: parentDom.removeChild();

 

 

75.BOM 中有哪些經常使用的對象?

location:
    location.href; 頁面url 地址
    location.hash; url 中#後的部分
    location.search; url 中?後的部分(查詢字符串)
    location.reload(); 刷新頁面;
 
 
navigator:    navigator.userAgent: 瀏覽器的userAgent信息

 

history:
    history.go(1);前進1步
    history.go(-1);後退1步;
    history.forward();前進
    history.back(); 後退

 

screen:
    screen.availWidth: 屏幕有效寬度
    screen.availHeight: 屏幕有效高度

 

 

76.列舉幾個常見的瀏覽器兼容問題?

主流瀏覽器發送ajax 使用XMLHttpRequest 建立異步對象,
IE 瀏覽器時候用XActive 建立異步對象;

 

主流瀏覽器註冊事件
    addEventListener("eventType","handler","true|false");
    removeEventListner("eventType","handler","true|false");
IE 瀏覽器註冊事件:
    註冊事件:attachEvent( "eventType""handler")
    移除事件:detachEvent("eventType""handler" )

 

阻止事件冒泡:
    主流瀏覽器:event.stopPropagation()
    IE 瀏覽器:event.cancleBubble=true;

 

獲取事件源:
    主流瀏覽器: event.target
    IE 瀏覽器:event.srcElement
 

 

77.什麼是事件委託以及時間委託的原理?

事件委託:    本應該註冊給子元素的事件, 註冊給父元素

 

事件委託的原理:事件冒泡, 由於有事件冒泡的存在, 因此子元素的事件會向外冒泡,觸發父元素的相同事件, 根據事件對象能夠找到真正觸發事件的事件源.
 

 

79.Javscript 中有幾種定時器, 有什麼區別?

setInterval: 間歇定時器, 間隔必定的時間就執行, 執行屢次;
setTimeout: 延時定時器, 只執行一次

 

80.如何實現多個標籤頁的通訊?

localStorage 能夠實現同一瀏覽器多個標籤頁之間通訊

localStorage 是Storage 對象的實例。對Storage 對象進行任何修改,都會在文檔上觸發storage 事件。
當經過屬性或者setItem()方法保存數據,使用delete 操做符或removeItem()刪除數據,或者調用clear()方法時,都會觸發該事件。
經過監聽該事件就能夠實現多個標籤頁之間的通訊

 

//監聽storage的改變
window.addEventListener("storage",function(event){ //do something },false);

 

 

81. jquery 中的$.each 和$(selector).each()有什麼不一樣?

$.each 能夠循環任何數組, 包括普通數組和jquery 對象組成的僞數組;
$(selector).each()只能循環遍歷jquery 對象組成的僞數組.

 

82. Jquery 中$.each 和原生js 中的forEach 方法有什麼區別?

 
 
1.jQuery中的$.each 不只能夠遍歷普通數組, 還能夠遍歷jQuery對象的僞數組, 原生js中的forEach只能遍歷普通數組;
 
 
2.參數列表不一樣
  //jquery
  $.each( obj/arr, function( key, value ) {   alert( key
+ ": " + value );   });

  //JavaScript
  arr.forEach(function callback(value, index, array) {
    //your iterator
    //thisArg表明this對象
  }, thisArg);
 
 
 

 

83. 原生JS 的window.onload 與Jquery 的$(document).ready(function(){}),$(function () {})有什麼不一樣?

執行時機不同: 
  window.onload 會等待頁面元素渲染完畢而且資源文件加載完畢後纔會執行;
  $(document).ready(function() {})是當頁面元素渲染完畢後就會執行, 因此執行時機先於window.onload

 

84. Jquery 實現連式編程的原理是什麼?

jquery中的方法中最後都會return 一個this, 這個this 就是當前元素的jquery對象

 

85. Jquery 如何屢次給同一個標籤綁定同一個事件?

使用addEventListener(‘事件名’,function(){})註冊的事件, 不會出現事件覆蓋, jquery中也是這樣作的.

 

86. 如何開發jquery 插件?

Jquery 提供了兩種開發插件的方式:
//$.fn: 能夠經過任意jquery 對象來調用
$.fn.green=function(){
console.log(this,$(this));
$(this).css({background:'green'});
}
// 調用之後, div 的背景色會被設置成green
$("div").green();

 

$.extend: 開發的插件只能經過$頂級對象來調用
// 定義
$.extend({
    alert: function (msg) {
        alert(msg);
    }
});
// 調用
$.alert('這是提示信息')

 

 

87. Jquery 中那些方法不支持鏈式操做?

$.trim(); 
$.each();
$(selector).html();
$(selector).text();

 

88. H5 都新增了那些新特性?

語義化的標籤:  (header,nav,footer,aside,article,section)
本地存儲:    sessionStorage,localStorage;
拖拽釋放:    (Drag and drop) API 音頻、視頻API(audio,video)
畫布:      (Canvas) API
地理:      (Geolocation) API
表單控件:    calendar、date、time、email、url、search
新的技術:    websocket

 

89. sessionStorage,localStorage 和cookie 三者有什麼區別?

共同點:它們三者都是瀏覽器端的存儲介質, 能夠存儲一些數據.

 

不一樣點:
sessionStorage 是將數據存儲在頁面的內存中, 因此數據會跟隨頁面的關閉而銷燬, 存儲數據相對較少(5M 左右), 只能存儲鍵值對;

 

localStorage 是將數據存儲在電腦的磁盤上, 存儲數據量大(20M 左右),須要手動刪除, 只能存儲鍵值對;

 

cookie 是http 協議的重要組成部分, 存儲數據量相對比較少(4K 左右),存儲cookie 的時候能夠設置過時時間, 到達過時時間後, 會自動銷燬,若是沒有設置, 則跟隨瀏覽器的關閉而銷燬. 
cookie 中存儲的數據會伴隨每一次http 請求被髮送到服務端, 因此不建議在cookie 中存儲大量數據.

 

 

 

90. 使用jquery 寫出一個簡單的$.ajax 的請求

$.ajax({
    url:'/api',
    type:'post',
    data:{},
    dataType:'json',
    success:function(res){
        console.log(res);
    }
});

 

91. 常見HTTP 狀態碼都有哪些?

100 => 正在初始化(通常是看不到的)
101 => 正在切換協議(websocket 瀏覽器提供的)
200 或者以2 開頭的兩位數=> 都是表明響應主體的內容已經成功返回了
202 => 表示接受
301 => 永久重定向/永久轉移
302 => 臨時重定向/臨時轉移(通常用來作服務器負載均衡)
304 => 本次獲取的內容是讀取緩存中的數據,會每次去服務器校驗
400 => 參數出現錯誤(客戶端傳遞給服務器端的參數出現錯誤)
401 => 未認證,沒有登陸網站
403 => 禁止訪問,沒有權限
404 => 客戶端訪問的地址不存在
500 => 未知的服務器錯誤
503 => 服務器超負荷(假設一臺服務器只能承受10000 人,當第10001 人訪問的時候,若是服務器沒有作負載均衡,那麼這我的的網絡狀態碼就是503)

 

92. 你知道的HTTP 請求方式有幾種?

1. GET 請求指定的頁面信息,並返回實體主體。
2. HEAD 相似於get 請求,只不過返回的響應中沒有具體的內容,用於獲取報頭
3. POST 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST 請求可能會致使新的資源的創建和/或已有資源的修改。
4. PUT 從客戶端向服務器傳送的數據取代指定的文檔的內容。
5. DELETE 請求服務器刪除指定的頁面。
6. CONNECT HTTP/1.1 協議中預留給可以將鏈接改成管道方式的代理服務器。
7. OPTIONS 容許客戶端查看服務器的性能。
8. TRACE 回顯服務器收到的請求,主要用於測試或診斷。
9. PATCH 實體中包含一個表,表中說明與該URI 所表示的原內容的區別。
10. MOVE 請求服務器將指定的頁面移至另外一個網絡地址。
11. COPY 請求服務器將指定的頁面拷貝至另外一個網絡地址。
12. LINK 請求服務器創建連接關係。
13. UNLINK 斷開連接關係。
14. WRAPPED 容許客戶端發送通過封裝的請求。
15. LOCK 容許用戶鎖定資源,好比能夠再編輯某個資源時將其鎖定,以防別人同時對其進行編輯。
16. MKCOL 容許用戶建立資源
17. Extension-mothed 在不改動協議的前提下,可增長另外的方法。

 

93. 請儘量詳盡的解釋ajax 的工做原理

第一步:建立一部對象var xhr=new XMLHttpRequest()
第二步:設置請求行xhr.open(‘請求方式’,請求地址);
第三步:發送請求Get 方式xhr.send(null),
若是是post 請求還要設置請求頭

xhr.setRequestHeader('Content-Type','application/x-www-formurlencoded');
xhr.send("name=zs&age=18");
//第四步:監聽服務端的響應
xhr.onreadystatechange=function(){
    if(xhr.status==200&&xhr.readyState==4){
    // 獲取json
    var json=xhr.responseText&&JSON.parse(xhr.responseText)
    // 獲取xml
    var xml=xhr.responseXML;
    console.log(json,xml)
    }
}
 

 

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

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".

 

95. 如何解決跨域問題?jsonp 跨域的原理是什麼?

動態在頁面中建立一個script 標籤, 使其src 屬性指向後端數據接口,後端數據接口必須返回一個js 函數的調用字符串( 如cb(‘{「name」:」zs」,」age」:18}’)), 
將要返回給前端的json 數據做爲函數的實參, 當script 標籤加載完畢後會在瀏覽器中執行後端返回的函數調用,因此前端必須事先對調用的函數進行聲明.
由於函數是在js 中聲明的, 因此能夠在函數內部拿到服務端調用的時候傳入的實參, 因此就間接實現了跨域請求數據.

 

97. 什麼是同步和異步, 那種執行方式更好?

同步是指一個程序執行完了接着去執行另一個程序, 異步是指多個程序同時執行. 因此異步效率更高, 由於異步不會出現阻塞現象,前一個程序的執行不會影響後一個程序的執行.

 

98.GET 和POST 的區別,什麼時候使用POST?

get是將要傳遞的參數拼接在url中進行傳遞,傳遞數據量少,不安全。post是將傳遞的參數放在請求體裏傳遞,攜帶數據量大,相對安全,要提交一些敏感數據(好比登陸),上傳文件時,必須使用post請求.
相關文章
相關標籤/搜索