大廠前端面試題


1、[單選題] 有以下 ES6 代碼 

function * gen() { 
  yield 1;
  yield 2;
  yield 3; 
} 

下面選項描述正確的是哪個? 

A.gen()執行后返回 2

B.gen()執行后返回 undefined

C.gen()執行后返回一個 Generator 對象

D.gen()執行后返回 1

答案:C

提示:這是 ES6 的新 feature, function 后面帶  * 的叫做 generator function。函數運行時, 返回一個迭代器。 

 

2、[不定項選擇題] 語句 var arr=[a,b,c,d];執行后,數組 arr 中每項都是一個整數,下面得到其中最大整數語 句正確的是哪幾項? 

A.Math.max(arr)

B.Math.max(arr[0], arr[1], arr[2], arr[3])

C.Math.max.call(Math, arr[0], arr[1], arr[2], arr[3])

D.Math.max.apply(Math,arr) 

答案:B C D 

提示: A 選項錯誤 

因為函數 Math.max(x);的參數是 Number 類型,可以使小數,整數,正數,負數或者是 0.如果不是上面所述類型就會返回 NaN. 

 

3、[問答題] 寫一個 traverse 函數,輸出所有頁面寬度和高度大於 50 像素的節點。 

<script language="javascript">
  function traverse() {
    var arr = [];
    var elements = [];
    if (document.all) {
      elements = document.all;
    } else {
      elements = document.getElementsByTagName("*");
    }
    for (var i = 0; i < elements.length; i++) {
      var ele = elements[i];
      // width 返回的是字符串   offsetWidth 返回的是帶邊框的 Number 型的數字 
      var width = parseFloat(ele.style.width) || ele.offsetWidth;
      var height = parseFloat(ele.style.height) || ele.offsetHeight;
      if (width > 50 && height > 50) {
        arr.push(elements[i].tagName);
      }
    }
    return arr;
  }
  window.onload = function () {
    console.log(traverse());
    console.log("a");
    console.log('a');
  }
</script>

 

4、[問答題] 請寫一個表格以及對應的 CSS,使表格奇數行為白色背景,偶數行為灰色背景,鼠標移 上去時為黃色背景。 

<table>
  <tr><td>第一行</td></tr>
  <tr><td>第二行</td></tr>
  <tr><td>第三行</td></tr>
  <tr><td>第四行</td></tr>
  <tr><td>第五行</td></tr>
</table>
table tr:nth-child(odd){
  background-color: white;
}
table tr:nth-child(even){
  background-color: gray;
}
table tr:hover{
  background-color: yellow;
}

 

5、[問答題]  寫一個求和的函數 sum,達到下面的效果  

// Should equal 15 
sum(1, 2, 3, 4, 5); 
// Should equal 0 
sum(5, null, -5); 
// Should equal 10 
sum('1.0', false, 1, true, 1, 'A', 1, 'B', 1, 'C', 1, 'D', 1, 'E', 1, 'F', 1, 'G', 1); 
// Should equal 0.3, not 0.30000000000000004 
sum(0.1, 0.2)

function sum() {
  var nResult = 0;
  for (var i = 0, l = arguments.length; i < l; i++) {
    nResult += window.parseFloat(arguments[i]) || 0;
  }
  return nResult.toFixed(3) * 1000 / 1000;
}

 

6、[填空題] 刪除給定數組中的第二項和第三項,並且在得到的新的數組中第二項后面添加一個新的 值:

var arr1 = ['a','b','c','d','e']; 

var arr2 = arr1. 1 ( 2 , 3 ,'newvalue') 

var arr1 = ['a','b','c','d','e']; 
var arr2 = arr1.splice( 1,2 ,'newvalue') 
console.log(arr1);

 

7、[填空題] 在空白處填入適當的代碼使輸出結果成立:

function showMoney() {
  1
};
var personA = new Object;
var personB = new Object;
personA.money = "100";
personB.money = "150";
personA.showMoney = showMoney;
personB.showMoney = showMoney;

// 輸出結果:
personA.showMoney(); //"100"  
personB.showMoney(); //"150"

答案: return this.money

 

8、[填空題] 使用 for in 循環數組中的元素會枚舉原型鏈上的所有屬性,過濾這些屬性的方式是使 用 ? 函數 

hasOwnProperty 

 

9、[問答題] 請實現一個 fibonacci 函數,要求其參數和返回值如下所示:

/** 
 * @desc: fibonacci  
 * @param: count {Number}  
 * @return: result {Number} 
 * 第 count 個 fibonacci 值,計數從 0 開始   
 * fibonacci 數列為:[1, 1, 2, 3, 5, 8, 13, 21, 34 „]   
 * 則 getNthFibonacci(0)返回值為 1   
 * 則 getNthFibonacci(4)返回值為 5  */
function getNthFibonacci(count) {
  if (count <= 1) {
    return 1;
  }
  return getNthFibonacci(count - 1) + getNthFibonacci(count - 2);
} 

 

10、[填空題] 

輸出對象中值大於 2 的 key 的數組 

var data = {a: 1, b: 2, c: 3, d: 4}; 

Object.keys(data).filter(function(x) { return ? ;})

期待輸出:[“c”,”d”] 

答案: data[x] > 2 

 

11、[填空題] 填寫內容讓下面代碼支持 a.name = “name1”; b.name = “name2”;

function obj(name) {
  ?
}
obj.? = "name2";
var a = obj("name1");
var b = new obj; 
function obj(name) {
  if(name){
    this.name = name
  }
  return this
}
obj.prototype.name = "name2";
var a = obj("name1");
var b = new obj; 

 

12、JavaScript語言特性中,有很多方面和我們接觸的其他編程語言不太一樣,比如說,JavaScript語言實現繼承機制的核心就是 《prototype》,而不是Java語言那樣的類式繼承。JavaScript解析引擎在讀取一個 Object 的屬性的值時,有沿着《原型鏈》向上尋找,如果最終沒有找到,則該屬性值為《undefined》;如果最終找到該屬性的值,則返回結果。與這個過程不同的是,當JavaScript解析引擎執行“給一個Object的某個屬性賦值”的時候,如果當前Object存在該屬性,則改寫該屬性的值,如果當前的Object本身並不存在該屬性,則賦值該屬性的值。

 

13、[單選題] 下面有關 html 的描述,不推薦的是? 

A.在頁面頂部添加 doctype 聲明; 

B.在 </head> „ <body> 中間插入 HTML 代碼; 

C.避免使用 <font> 標簽; 

D.使用 <table> 元素展現學生成績表等數據。 

答案:B

 

14、[單選題] 下面關於 CSS 布局的描述,不正確的是? 

A.塊級元素實際占用的寬度與它的 width 屬性有關; 

B.塊級元素實際占用的寬度與它的 border 屬性有關; 

C.塊級元素實際占用的寬度與它的 padding 屬性有關; 

D.塊級元素實際占用的寬度與它的 background 屬性有關。 

答案:D

 

15:、[單選題]下列事件哪個不是由鼠標觸發的事件()

A.click 

B.contextmenu 

C.mouseout 

D.keydown 

答案:D

 

16、[問答題] 請說說 cache-control 是怎么回事? 

  網頁的緩存是有 HTTP 消息頭中的 “Cache-control” 來控制的,常見的取值有 private 、no-cache、max-age、must-revalidate 等,默認為 private

  Expires 頭部字段提供一個日期和時間,響應在該日期和時間后被認為失效。允許客戶端在這個時間之前不去檢查(發請求),等同 max-age 的效果。但是如果同時存在,則被 Cache-Control 的 max-age 覆蓋

  Expires = "Expires" : "HTTP-date"

  例如: Expires: Thu,01 Dec 1994 16:00:00 GMT  (必須是GMT格式)

  如果把它設置為-1,則表示立即過期

  Expires 和 max-age 都可以用來指定文檔的過期時間,但是二者有一些細微差別

  1.Expires 在 HTTP/1.0 中已經定義,Cache-Control:max-age 在HTTP/1.1中才有定義,為了向下兼容,僅使用 max-age不夠。

  2.Expires 指定一個絕對的過期時間(GMT 格式),這么做會導致至少 2 個問題: 

    2.1 客戶端和服務器時間不同步導致 Expires 的配置出現問題。 

     2.2 很容易在配置后忘記具體的過期時間,導致過期來臨出現浪涌現象 

  3. max-age 指定的是從文檔被訪問后的存活時間,這個時間是個相對值(比如:3600s), 相對的是文檔第一次被請求時服務器記錄的 Request_time(請求時間) 

  4. Expires 指定的時間可以是相對文件的最后訪問時間(Atime)或者修改時間(MTime),而 max-age 相對對的是文檔的請求時間(Atime) 

  5.如果值為 no-cache,那么每次都會訪問服務器。如果值為 max-age,則在過期之前不 會重復訪問服務器。

 

17、[問答題] 你了解 HTTP 狀態碼嗎,請隨便介紹一下。 

  100 Continue  繼續,一般在發送 post 請求時,已發送了 http header 之后服務端將返回 此信息,表示確認,之后發送具體參數信息 

  200 OK   正常返回信息 

  201 Created  請求成功並且服務器創建了新的資源 

  202 Accepted  服務器已接受請求,但尚未處理 

  301 Moved Permanently  請求的網頁已永久移動到新位置 

  302 Found  臨時性重定向 

  303 See Other  臨時性重定向,且總是使用 GET 請求新的 URI 

  304 Not Modified  自從上次請求后,請求的網頁未修改過 

  400 Bad Request  服務器無法理解請求的格式,客戶端不應當嘗試再次使用相同的內容 發起請求 

  401 Unauthorized  請求未授權 

  403 Forbidden  禁止訪問 

  404 Not Found  找不到如何與 URI 相匹配的資源 

  500 Internal Server Error  最常見的服務器端錯誤 

  503 Service Unavailable 服務器端暫時無法處理請求(可能是過載或維護) 

 

18、[問答題] 如何獲取 UA? 

通過JS獲取瀏覽器UA(User Agent,用戶代理)

//獲取完整的瀏覽器名稱
document.Browser.Name.value=navigator.appName; 
//獲取瀏覽器的版本,一般不與實際的瀏覽器版本對應
document.Browser.Version.value=navigator.appVersion; 
//獲取瀏覽器的名稱。通常都是Mozilla,即使在非Mozilla的瀏覽器中也是如此
document.Browser.Code.value=navigator.appCodeName; 
//獲取瀏覽器的用戶代理字符串
document.Browser.Agent.value=navigator.userAgent;

 

19、[問答題] 說說對網站重構的理解。 

網站重構:在不改變外部行為的前提下,簡化結構、添加可讀性,而在網站前端保持一致性的行為。也就是說在不改變UI的情況下,對網站進行優化,在擴展的同時保持一致性的UI

對於傳統的網站來說,重構通常是:

(1)表格(table)布局改為 DIV + CSS

(2)使網頁前端兼容於現代瀏覽器(針對於不合規范的CSS、如對 IE6 有效的)

(3)對於移動平台的優化

(4)針對SEO進行優化

(5)深層次的網站重構應該考慮的方面

(6)減少代碼的耦合

(7)讓代碼保持彈性

(8)嚴格按規范編寫代碼

(9)設計可擴展的API

(10)代替舊有的框架、語言

(11)增強用戶體驗

(12)通常來說對於速度的優化也包含在重構中

(13)壓縮JS、CSS、image 等前端資源(通常是由服務器來解決的)

(14)程序的性能優化(如數據讀寫)

(15)采用CDN來加速資源加載

(16)對於 JS DOM 的優化

(17)HTTP服務器的文件緩存

SEO:(Search Engine Optimization):漢譯為搜索引擎優化。是一種方式:利用搜索引擎的規則提高網站在有關搜索引擎內的自然排名。

目的是讓其在行業內占據領先地位,獲得品牌收益。很大程度上是網站經營者的一種商業行為,將自己或自己公司的排名前移。
 
20、[問答題] js 對象的深度克隆代碼實現。 
function clone(obj) {
  let ret
  if (Array.isArray(obj)) {
    ret = [] // 創建一個空數組
    for (let i = 0; i < obj.length; i++) {
      ret[i] = clone(obj[i])
    }
    return ret
  } else if (Object.prototype.toString.call(obj) === "[object Object]") {
    ret = {} // 創建一個空對象
    for (let i in obj) {
      ret[i] = clone(obj[i])
    }
    return ret
  } else {
    return obj
  }
}

 

 

 21、[問答題] Ajax 是什么?Ajax 的交互模型?同步和異步的區別?如何解決跨域問題? 

(1)ajax 的全稱是異步的 JavaScript 和 XML ,是一種創建快速動態的技術,通過在后台與服務器進行少量數據交互,實現網頁的異步更新,在不重新加載整個界面的情況下,做到網頁的部分刷新

(2)ajax的交互模型(ajax的過程)

  • 用戶發出異步請求
  • 創建 XMLHttpRequest 對象
  • 告訴 XMLHttpRequest 對象哪個函數會處理  XMLHttpRequest 對象狀態的改變,為此要把對象的 onReadyStateChange 屬性設置為響應該事件的 JavaScript 函數的引用
  • 創建請求,用 open 方法指定是get還是post,是否異步,url地址
  • 發送請求,send方法
  • 接收結果並分析
  • 實現刷新

(3)同步和異步的區別:

  • 同步:腳本會停留並等待服務器發送回復然后在繼續
  • 異步:腳本允許頁面繼續其進程並處理可能的回復

(4)跨域問題的解決:

  • 使用 document.domain + iframe 解決跨子域問題
  • 使用 window.name
  • 使用 flash
  • 使用 iframe + location.hase
  • 使用 html5 的 postMessage
  • 使用 jsonp (創建動態 script)

 

22、[問答題] IE 與火狐的事件機制有什么區別? 如何阻止冒泡? 

(1)我們在網頁中的某個操作(有的操作對應多個事件)。例如:當我們點擊一個按鈕就會產生一個事件。是可以被JavaScript偵測到的行為

(2)事件處理機制:IE是事件冒泡,firefox 同時支持兩種事件模型(捕獲型事件和冒泡型事件)

(3)ev.stopPropagation()  ---注意舊 ie 的方法:ev.cancelBubble = true

 

23、[問答題]  WEB 應用從服務器主動推送 Data 到客戶端有那些方式? 

(1)html5 websoket

(2)websocket 通過 flash

(3)XHR 長時間連接

(4)XHR Multipart Streaming

(5)不可見的 Iframe

(6)<sctipt>標簽的長時間連接(可跨域)

 

24、[問答題] JavaScript 原型,原型鏈 ? 有什么特點? 

(1)原型對象也是普通的對象,是對象一個自帶隱式的 __proto__ 屬性,原型也有可能有自己的原型,如果一個原型對象的原型不為 null 的話,我們就稱之為原型鏈

(2)原型鏈是由一些用來繼承和共享屬性的對象組成的(有限的)對象鏈

 

25、[問答題]  Node.js 的適用場景 

(1)高並發

(2)聊天

(3)實時消息推送

 

26、[問答題]  eval 是做什么的,有什么建議? 

(1)它的功能是把對應的字符串解析成 JS 代碼並運行

(2)應該避免使用eval,不安全,非常耗性能(2次,一次解析成js語句,一次執行)

 

27、[問答題]  哪些地方會出現 css 阻塞,哪些地方會出現 js 阻塞? 

(1)js的阻塞特性:
  所有瀏覽器在下載JS的時候,會阻止一切其他活動,比如其他資源的下載,內容的呈現等等。
  直到JS下載、解析、執行完畢后才開始繼續並行下載其他資源並呈現內容。
  為了提高用戶體驗,新一代瀏覽器都支持並行下載JS,但是JS下載仍然會阻塞其它資源的下載(例如.圖片,css文件等)。
由於瀏覽器為了防止出現JS修改DOM樹,需要重新構建DOM樹的情況,所以就會阻塞其他的下載和呈現。
嵌入JS會阻塞所有內容的呈現,而外部JS只會阻塞其后內容的顯示,2種方式都會阻塞其后資源的下載。
也就是說外部樣式不會阻塞外部腳本的加載,但會阻塞外部腳本的執行。
 
(2)CSS怎么會阻塞加載了?
CSS本來是可以並行下載的,在什么情況下會出現阻塞加載了(在測試觀察中,IE6下CSS都是阻塞加載)
  • 當CSS后面跟着嵌入的JS的時候,該CSS就會出現阻塞后面資源下載的情況;
  • 而當把嵌入JS放到CSS前面,就不會出現阻塞的情況了。
根本原因:
  • 因為瀏覽器會維持html中css和js的順序,樣式表必須在嵌入的JS執行前先加載、解析完。
  • 而嵌入的JS會阻塞后面的資源加載,所以就會出現上面CSS阻塞下載的情況。
嵌入JS應該放在什么位置?
  • 放在底部,雖然放在底部照樣會阻塞所有呈現,但不會阻塞資源下載。
  • 如果嵌入JS放在head中,請把嵌入JS放在CSS頭部。
  • 使用defer(只支持IE)
  • 不要在嵌入的JS中調用運行時間較長的函數,如果一定要用,可以用`setTimeout`來調用

 

28、[問答題]  GET 和 POST 的區別,何時使用 POST? 

GET:一般用於信息獲取,使用URL傳遞參數,對所發送的信息數量有限制,一般在 2000 個字符

POST:一般用於修改服務器上的資源,對所發送的信息沒有限制

GET方式需要使用 Request.QueryString 來取得變量的值

POST方式通過 Request.Form 來獲取變量的值

也就是說Get是通過地址欄來傳值,而Post是通過提交表單來傳值

在以下情況下,使用POST請求:

(1)無法使用緩存文件(更新服務器上的文件或數據庫)

(2)向服務器發送大量數據(POST沒有數據量限制)

(3)發送包含未知字符的用戶輸入時,POST比GET更穩定也更可靠

 

29、[問答題]  請解釋一下 JavaScript 的同源策略。 

  同源策略是客戶端腳本(尤其是JavaScript)的重要安全度量標准。其目的是防止某個文檔或腳本從多個不同源裝載。

  這里的同源策略指的是:協議、域名、端口號相同,同源策略是一種安全協議,指一段腳本只能讀取來自同一來源的窗口和文檔的屬性。

為什么要有同源限制:

  我們舉例說明:比如一個黑客程序,他利用 Iframe 把真正的銀行登錄頁面嵌入他的頁面上,當你使用真實的用戶名、密碼登錄時,他的頁面就可以通過JavaScript讀取到你的表單中input中的內容,這樣用戶名、密碼就輕松到手了。

 

30、[問答題]  什么叫優雅降級和漸進增強? 

(1)優雅降級:Web站點在所有新式瀏覽器中都能正常工作,如果用戶使用的是老式瀏覽器,則代碼會檢查以確認它們是否能正常工作。由於 IE 獨特的盒模型布局問題,針對不同版本的 IE 的 hack實踐過優雅降級了,為那些無法支持功能的瀏覽器增加候選方案,使之在舊式瀏覽器上以某種形式降級體驗卻不至於完全失效。

(2)漸進增強:從被所有瀏覽器支持的基本功能開始,逐步地添加那些只有新式瀏覽器才支持的功能,向頁面增加無害於基礎瀏覽器的額外樣式和功能。當瀏覽器支持時,它們會自動地呈現出來並發揮作用。

 

31、[問答題]  哪些操作會造成內存泄漏? 

內存泄漏指任何對象在你不在擁有或需要它之后仍然存在。

垃圾回收器定期掃描對象,並計算引用了每個對象的其他對象的數量。如果一個對象的引用為0(沒有其他對象引用過該對象),或對該對象的唯一引用是循環的,那么該對象的內存即可回收。

(1)setTimeout 的第一個參數使用字符串而非函數的話,會引發內存泄漏

(2)閉包

(3)控制台日志

(4)循環引用(在兩個對象彼此引用且彼此保留時,就會產生一個循環引用)

 

32、[問答題]  .call() 和 .apply() 的作用? 

動態改變某個類的某個方法的運行環境

 

33、[單選題] 

function Foo() {
  var i = 0;
  return function () {
    document.write(i++);
  }
}
var f1 = Foo(), f2 = Foo();
f1();
f1();
f2(); 

請問以上程序的輸出是()

A.010 
B.012 
C.000 
D.011
答案:A
  這是一個閉包,閉包可以用在許多地方。它的最大用處有兩個,一個是可以讀取函數內部的變量,另一個就是讓這些變量的值始終保持在內存中。
  這里的局部變量 i ,對 f1() 來說是全局變量,對 f2() 來說也是全局變量,但是 f1() 的 i 和 f2() 的 i 有事相互獨立不可見的,f1() 每執行一次,f1() 的 i 就加 1 ,f2() 每執行一次,f2() 的 i 就加 1,但是相互之間不影響,因此是 010
 
34、[單選題]  以下 Js 程序的輸出是什么() 
var a = "undefined";
var b = "false";
var c = "";
function assert(aVar) {
  if (aVar)
    alert(true);
  else
    alert(false);
}
assert(a);
assert(b);
assert(c); 
A.true,true,true 
B.true,true,false 
C.false,false,true 
D.false,false,false 
答案:B
  undefined 和 false 都是 JavaScript的數據類型,但是用雙引號引起了就是字符串了,空串相當於 false,否則是 true
 
35、[問答題]  請實現 javascript 中的 indexOf 功能,判斷一個字符串 a 中是否包含另一個字符串 b。 
a)如果包含,需要返回匹配字符串 b 的位置。 
b)如果不包含,需要返回-1。 
如:indexOf("hello","el") return 1。 
// 方法1
function indexOf(str, subStr){
  var ret = str.match(subStr)
  return ret ? ret.index : -1
}

// 方法2
function indexOf(a, b){
  return a.search(b)
}

 

36、[單選題] 

var myObject = {
  foo: "bar",
  func: function () {
    var self = this;
    console.log(this.foo);
    console.log(self.foo);
    (function () {
      console.log(this.foo);
      console.log(self.foo);
    }());
  }
};
myObject.func(); 

程序的輸出是什么?

A.bar bar bar bar 
B.bar bar bar undefined 
C.bar bar undefined bar 
D.undefined bar undefined bar 
答案:C
方法/函數是由誰(對象)調用的,方法/函數內部的this就是指向誰(對象)
注意:是被誰調用,不是處於誰的作用域,即使在作用域
1、func 是由 myObject 調用的,this 指向 myObject 
2、self 指向 myObject ,相當於 myObject 的this副本
3、這個立即執行匿名函數表達式(IIFE)是由window調用的,this指向window
4、IIEF 的作用域處於 myObject 的作用域中,本作用域找不到 self 變量,沿着作用域鏈向上查找 self 變量,找到了指向 myObject 的self
 
 
37、[不定項選擇題] 下面有關 javascript 內部對象的描述,正確的有?
A.History 對象包含用戶(在瀏覽器窗口中)訪問過的 URL 
B.Location 對象包含有關當前 URL 的信息 
C.Window 對象表示瀏覽器中打開的窗口 
D.Navigator 對象包含有關瀏覽器的信息 
答案:ABCD
Navagator:提供有關瀏覽器的信息。
Window:Window對象處於對象層次的最頂層,它提供了處理Navagator窗口的方法和屬性。
Location:提供了與當前打開的URL一起工作的方法和屬性,是一個靜態的對象。
History:提供了與歷史清單有關的信息。
Document:包含與文檔元素一起工作的對象,它將這些元素封裝起來供編程人員使用。
 
38、[單選題] js 中字符串連接用那個比較高效? 
A.a+=b 
B.a = a+b 
C.Array.join() 
D.Array.push()
答案:C
JavaScript中字符串連接時用 Array.join() 替換 string += "xx" ,換來幾十倍的速度提升
 
39、[單選題]  在 文 件 /home/somebody/workspace/somemodule.js 中 第 一 行 引 用 了 一 個 模 塊 : require(‘othermodule‘),請問 required 的查找模塊的順序 
A. /home/somebody/workspace/mode_modules/othermodule/index.js  
B. /home/somebody/workspace/mode_modules/othermodule. Js  
C.CORE MODULES named othermodule  
D./home/somebody/mode_modules/othermodule/index.js 
 
A.C D A B 
B.C B D A 
C.C B A D 
D.C D B A 
答案:C
(1)首先,Node在當前目錄下查找 package.json(CommonJS包規范定義的包描述文件),通過 JSON.parse() 解析出包描述對象,從中取出 main 屬性指定的文件名進行定位。如果文件確實擴展名,將會進入擴展名分析的步驟。
(2)如果 main 屬性制定的文件名錯誤,或者壓根沒有 package.json 文件,Node會將 index當做默認文件名,然后依次查找 index.js   index.node   index.json
(3)如果在目錄分析的過程中沒有定位成功任何文件,則自定義模塊進入下一個路徑進行查找。如果模塊路徑數組都被遍歷完畢,依然沒有查找到目標文件,則會拋出查找失敗異常。
 
  按照上面的思路,首先應該查找 package.json 文件,看看里面有沒有核心模塊,應該是 C 最先,
othermodule不是核心模塊,那么接着應該進入擴展名分析的步驟,就應該是查找 othermodule.js,對應B
緊接着就是以 index 為默認文件名,也就是A,
再接下來就是上一個文件目錄 D 了
 
40、[單選題]如下代碼輸出的結果是什么: 
console.log(1 + "2" + "2");
console.log(1 + +"2" + "2");
console.log("A" - "B" + "2");
console.log("A" - "B" + 2); 
A.122 122 NaN NaN 
B.122 32 NaN NaN2 
C.122 32 NaN2 NaN 
D.122 32 NaN2 NaN2 
答案:C
(1)console.log(1+"2"+"2")
做加法時要注意雙引號,當使用雙引號時,JavaScript認為是字符串,字符串相加等於字符串合並
(2)console.log(1 + + "2" + "2")
第一個 + "2" 中的加號是一元加操作符,+"2" 會變成數值 2,因此 1 + + "2" 相當於 1+2=3
(3)console.log("A" - "B" + "2")
"A"-"B"的運算中,需要先把 "A" 和 "B" 用 Number函數轉換成數值,其結果是 NaN,在減法操作中,如果有一個是 NaN,則結果是NaN,因此 "A"-"B"結果為 NaN
然后和 “2” 進行字符串拼接,變成了 NaN2
(4)console.log("A"-"B" + 2)
根據上述,"A"-"B"的結果為 NaN,然后和數值2進行加法操作,在加法操作中,如果有一個操作數是 NaN,則結果為 NaN
 
41、[不定項選擇題] 下列關於比較 Ajax 與 Flash 的優缺點,相關描述正確的是? 
A.Ajax 的優勢在意在於可搜索性,開放性,易用性及易於開發 
B.Flash 的優勢在於多媒體處理,可以更容易的調用瀏覽器以外的外部資源 
C.Ajax 最主要的批評就是它可能破壞瀏覽器的后退功能 
D.flash 文件經常會很大,用戶第一次使用的時候需要忍耐較長的等待時間 
答案:ABCD
(1)Ajax的優勢:1.可搜索性 2.開放性 3.費用 4.易用性 5.易於開發
(2)Flash的優勢:1.多媒體處理 2.兼容性 3.矢量圖形 4.客戶端資源調度
(3)Ajax的劣勢:1.它可能破壞瀏覽器的后退功能  2.使用動態頁面更新使得用戶難於將某個特定的狀態保存到收藏夾中   ---不過這些都有相關方法解決
(4)Flash的劣勢:1.二進制格式  2.格式私有  3.flash文件經常會很大,用戶第一次使用的時候需要忍耐較長的等待時間   4.性能問題
 
42、[不定項選擇題]  下面哪些語句可以在 JS 里判斷一個對象 oStringObject 是否為 String。 
A.oStringObject instanceof String 
B.typeof oStringObject == 'string'
C.oStringObject is String
D.以上答案都不正確 
答案:A
通常來說判斷一個對象的類型使用 typeof,但是在 new String 的情況下,結果會是 object 此時需要通過 instanceof 來判斷
 
43、[問答題]  Flappy Bird 是風靡一時的手機游戲,玩家要操作一只小鳥穿過無窮無盡的由鋼管組成的 障礙。如果要你在 HTML 前端開發這個游戲,為了保證游戲的流暢運行,並長時間運行也不 會崩潰,請列舉開發要注意的性能問題和解決的方法。 
(1)長時間運行會崩潰的原因就是 ‘內存泄漏’。我們在日常的JS程序中並不太在意內存泄漏問題,因為JS解釋器會有垃圾回收機制,大部分無效內存會被回收,另一方面JS運行在客戶端,即使出現內存泄漏也不是太大的問題,簡單的刷新頁面即可。但是如果要預防內存泄漏的場景還是要注意一些問題。
(2)針對這個場景來說,即使長期運行出現內存泄漏的可能還是很低。第一方面,數據量很少,水管維護一個數組即可,然后每隔一段時間更新數組,來達到水管長度不同的效果。小鳥只要維護一個對象即可。通過移動水管檢查碰撞就可以實現游戲邏輯。因為在瀏覽器端,JS程序和頁面UI渲染公用一條線程,如果計算時間過長會使渲染阻塞,在HTML5中利用 webworker 已經可以開辟一個新線程專門負責計算解決這個問題了。
 
44、[問答題]  以下代碼輸出的值為?( )
function f1() {
  var n = 100;
  nAdd = function () {
    n += 1
  }
  function f2() {
    alert(n);
  }
  return f2;
}
var result = f1();
result();
nAdd();
result(); 

輸出:100   undefined   100

 

45、什么樣的請求是簡單請求?

 請求方法是以下三種方法之一:

  • HEAD
  • GET
  • POST

 HTTP的請求頭信息不超出以下幾種字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限於三個值 application/x-www-form-urlencoded、multipart/form-data、text/plain

 

46、能說說首屏加載優化有哪些方案嗎?

  • Vue-Router路由懶加載(利用Webpack的代碼切割)
  • 使用CDN加速,將通用的庫從vendor進行抽離
  • Nginx的gzip壓縮
  • Vue異步組件
  • 服務端渲染SSR
  • 如果使用了一些UI庫,采用按需加載
  • Webpack開啟gzip壓縮
  • 如果首屏為登錄頁,可以做成多入口
  • Service Worker緩存文件處理
  • 使用link標簽的rel屬性設置 prefetch(這段資源將會在未來某個導航或者功能要用到,但是本資源的下載順序權重比較低,prefetch通常用於加速下一次導航)、preload(preload將會把資源的下載順序權重提高,使得關鍵數據提前下載好,優化頁面打開速度)

 

47、談談你對作用域鏈的理解

了解作用域鏈之前我們要知道以下幾個概念:

  • 函數的生命周期
  • 變量和函數的聲明
  • Activetion Object(AO)、Variable Object(VO)

函數的生命周期:

  • 創建:JS解析引擎進行預解析,將函數聲明提前,同時將該函數放到全局作用域或當前函數的上一級函數的局部作用域中。
  • 執行:JS引擎會將當前函數的局部變量和內部函數進行聲明提前,然后再執行業務代碼,當函數執行完退出時,釋放該函數的執行上下文,並注銷該函數的局部變量。

變量和函數的聲明:如果變量名和函數名聲明時相同,函數優先聲明

Activetion Object(AO)、Variable Object(VO):

  • AO:Activetion Object(活動對象)
  • VO:Variable Object(變量對象)

VO對應的是函數創建階段,JS解析引擎進行預解析時,所有的變量和函數的聲明,統稱為 Variable Object。該變量與執行上下文相關,知道自己的數據存儲在哪里,並且知道如何訪問。VO是一個與執行上下文相關的特殊對象,它存儲着在上下文中聲明的以下內容:

  • 變量(var,變量聲明)
  • 函數聲明(FunctionDeclaration)
  • 函數的形參

AO對應的是函數執行階段,當函數被調用執行時,會建立一個執行上下文,該執行上下文包含了函數所需的所有變量,該變量共同組成了一個新的對象就是Activetion Object。該對象包含了:

  • 函數的所有局部變量
  • 函數的所有命名參數
  • 函數的參數集合
  • 函數的this指向

作用域鏈

        當代碼在一個環境中創建時,會創建變量對象的一個作用域鏈來保證對執行環境有權訪問的變量和函數。作用域第一個對象始終是當前執行代碼所在環境的變量對象(VO)。如果是函數執行階段,那么將其AO作為作用域鏈第一個對象,第二個對象是上級函數的執行上下文AO,下一個對象依次類推。

        當查找變量的時候,會先從當前上下文的變量對象中查找,如果沒有找到,就會從父級(詞法層面上的父級)執行上下文的變量對象中查找,一直找到全局上下文的變量對象,也就是全局對象。這樣由多個執行上下文的變量對象構成的鏈表就叫做作用域鏈。

 

 48、在ES5中如何實現繼承

 寄生組合式繼承:

  所謂寄生組合式繼承,及通過借用構造函數來繼承屬性,通過原型鏈的混和形式來繼承方法。其背后的基本思想是:不必為了指定子類型的原型而調用超類型的構造函數,我們所需要的無非就是超類型原型的一個副本而已。本質上,就是使用寄生式繼承來繼承超類型的原型,然后再將結果指定給子類型的原型。

 

49、絕對定位

如果不設置子元素 left top的話,absolute的子元素是頂在父元素的 content左上方的

如果設置子元素 left = 0  top = 0 的話,子元素是頂在父元素的 padding 左上方的(在border內) 

  • 一旦給元素加上了 absolute 或 float 就相當於給元素加上了 display: block
  • absolute 元素覆蓋正常文檔流內元素(不用設 z-index,自然覆蓋)
  • 可以減少重繪和回流的開銷(如 absolute + top:-9999em,或 absolute + visibility:hidden,將動畫效果放到 absolute 元素中)

屬性介紹:

  • static:默認值,位置設置為 static 的元素,它始終會處於文檔流給予的位置。
  • inherit:規定應該從父元素繼承 position 屬性的值。但是任何版本的 IE 都不支持屬性值 “inherit”
  • fixed:生成絕對定位的元素。默認情況下,可定位於相對於瀏覽器窗口的指定坐標。但當祖先元素具有 transform 屬性且不為 none 時,就會相對於祖先元素指定坐標,而不是瀏覽器窗口。
  • absolute:生成絕對定位的元素,相對於該元素最近的已定位的祖先元素進行定位。
  • relative:生成相對定位的元素,相對於該元素在文檔中的初始位置進行定位。

浮動、絕對定位和固定定位會脫離文檔流,相對定位不會脫離文檔流,絕對定位相對於該元素最近的已定位的祖先元素,如果沒有一個祖先元素設置定位,那么參照物是body

  • 如果祖先元素是塊級元素,包含塊則設置為該元素的內邊距邊界
  • 如果祖先元素是行內元素,包含塊則設置為該祖先元素的內容邊界

問答題:

  • 定位的元素的起始位置為父包含塊的內邊距(不會在border里,除非使用負值,會在padding里)
  • 定位的元素的margin還是能起作用的
  • background屬性是會顯示在border里的
  • z-index是由層疊層級的,需要考慮同一個層疊上下文的層疊優先級
  • z-index是負值不會覆蓋包含塊的背景色(但是如果有內容,會被包含塊的內容覆蓋)
  • z-index的值影響的元素是定位元素以及flex盒子
  • 上面一個定位元素,下面一個正常流的元素,定位元素會覆蓋在正常流元素之上,除非給z-index是負值
  • 頁面根元素html天生具有層疊上下文,稱之為“根層疊閃現給我”

 

50、講講MVVM,說說與MVC有什么區別?

  MVC允許在不改變視圖的情況下改變視圖對用戶輸入的響應方式,用戶對View的操作交給了Controller處理,在Controller中響應View的事件調用Model的接口對數據進行操作,一旦Model發生變化便通知相關視圖進行更新。

  如果前端沒有框架,只使用原生的 html+js,MVC模式可以這樣理解。將html看作view;js看作controller,負責處理用戶與應用的交互,響應對view的操作(對事件的監聽),調用Model對數據進行操作,完成model與view的同步(根據model的改變,通過選擇器對view進行操作);將js的ajax當做Model,也就是數據層,通過ajax從服務器獲取數據。

  Model看成模型,View看成這個模型的視圖化體現,而Controller根據需要寫在各自的方法里。

 

  MVVM與MVC最大的區別就是:它實現了View和Model的自動同步,也就是當Model的屬性改變時,我們不用再自己手動操作DOM元素,來改變View的顯示,而是改變屬性后該屬性對應View層會自動改變。

  從整體來看,MVVM比MVC精簡很多,不僅簡化了業務與界面的依賴,還解決了數據頻繁更新的問題,不用再使用選擇器操作DOM元素。因為在MVVM中,View不知道Model的存在,Model和ViewModel也觀察不到View,這種低耦合模式提高代碼的可重用性。

 

51、說說事件委托有什么好處?

 事件委托就是利用事件冒泡機制指定一個事件處理程序,來管理某一類型的所有事件。

即:利用冒泡的原理,把事件加到父級上,觸發執行效果。

好處:

  • 只在內存中開辟了一塊空間,節省資源同時減少了DOM操作,提供性能
  • 對於新添加的元素也會有之前的事件

 

52、target和currentTarget的區別

  •  target在事件流的目標階段
  •  currentTarget在事件流的捕獲、目標及冒泡階段

 只有當事件流處於目標階段的時候,兩個的指向才是一樣的,而處於捕獲和冒泡階段的時候,target指向被單擊的對象,而currentTarget指向當前事件活動的對象(注冊該事件的對象,一般為父級)。

 

53、Service Worker的作用

  •  網絡代理,轉發請求,偽造響應
  • 離線緩存
  • 消息推送
  • 后台消息傳遞

 

54、如何判斷兩個變量相等

 Object.is()方法判斷兩個值是否是相同的值

NaN === NaN   // false

+0 === -0   // true

Object.is(NaN, NaN)  // true

Object.is(+0, -0)  // false

 在ES5中實現 Object.is() 的 polyfill

if (!Object.is) {
  Object.is = function(x, y) {
    if (x === y) { // Steps 1-5, 7-10
      // 針對 +0不等於-0
      return x !== 0 || 1 / x === 1 / y;
    } else {
      // 針對 NaN等於NaN
      return x !== x && y !== y;
    }
  };
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM