js面試常問問題含詳細答案

總結一些前端js的知識,將筆記整理跟你們分享,有些知識會常常在前端面試的時候會問到,因此作個記錄,但願對你們有所幫助,若是有什麼問題,能夠指出,會積極修正。
若是你們喜歡,能夠點贊或留言我再繼續更新面試題~~~~,謝謝你們~~~javascript

一、前++、後++、區別?

var i=2 ;
a = i++ //將i的值賦給a , 即a = i,以後再執行i = i + 1; 2
a = ++i //將i+1 的值賦給a,即a = i + 1 ,以後再執行i = i + 1; 3
console.log(a)
複製代碼

【總結】:css

前++是先自加後計算、後++是後自加先計算html

1:前置++ 是將自身+1 後的值賦給變量,同時自身加1;前端

2:後置++ 是將自身的值賦給變量,以後自身再加1;java

二、JS 有哪些數據類型?

Js基本數據類型 undefined null boolean number string bigint
Js引用類型 object Array function
ES6基本數據類型 多了個symboljquery

三、js判斷類型?

一、typeof
檢測不出null 和 數組,結果都爲object,因此typeof經常使用於檢測基本類型
二、instanceof
不能檢測出number、boolean、string、undefined、null、symbol類型,因此instancof經常使用於檢測複雜類型以及級成關係
三、constructor
null、undefined沒有construstor方法,所以constructor不能判斷undefined和null。可是contructor的指向是能夠被改變,因此不安全
四、Object.prototype.toString.call
全類型均可以判斷git

四、數據類型怎麼檢測?

1typeof
例:console.log(typeof true) // boolean

2instanceof
例:console.log([1,2] instanceof Array) // true

3constructor
例: console.log([1, 2].constructor === Array) // ture

四、Object.prototype.toString.call
例:Object.prototype.toString.call([1, 2]) // [object Array]
複製代碼

五、Js數組的方法

join()數組轉換成字符串
push()尾部添加
pop()尾部刪除
shift() 頭部刪除
unshift() 頭部添加
sort()排序
reverse()反轉
concat()連接兩個或多個數組
slice()
var arr=[1,2,3,4,5]
console.log(arr.slice(1)) //[2,3,4,5]選擇序列號從1到最後的全部元素組成的新數組
console.log(arr.slice(1,3)) //[2,3]不包含序列號,序號爲3的元素
splice()
splice(index,howmany,item1,...itemx)
index參數:必須,整數,規定添加或刪除的位置,使用負數,從數組尾部規定位置
howmany參數:必須,要刪除的數量,若是爲0則不刪除項目
item1,...itemx參數:可選,向數組添加的新項目
var arr=[1,2,3,4,5]
console.log(arr.splice(2,1,"hello"));//[3]返回的新數組
console.log(arr);//[1,2,"hello",4,5]
indexOf()和 lastIndexOf() (ES5新增)
forEach() (ES5新增)
map() (ES5新增)
filter() (ES5新增)
every() (ES5新增)
some() (ES5新增)
reduce()和 reduceRight() (ES5新增)程序員

六、JS中的Array.splice()和Array.slice()方法有什麼區別?

話很少說,來看第一個例子:es6

var arr=[0,1,2,3,4,5,6,7,8,9];//設置一個數組
console.log(arr.slice(2,7));//2,3,4,5,6
console.log(arr.splice(2,7));//2,3,4,5,6,7,8
//由此咱們簡單推測數量兩個函數參數的意義,
slice(start,end)第一個參數表示開始位置,第二個表示截取到的位置(不包含該位置)
splice(start,length)第一個參數開始位置,第二個參數截取長度
複製代碼

接着看第二個:github

var x=y=[0,1,2,3,4,5,6,7,8,9]
console.log(x.slice(2,5));//2,3,4
console.log(x);[0,1,2,3,4,5,6,7,8,9]原數組並未改變
//接下來用一樣方式測試splice
console.log(y.splice(2,5));//2,3,4,5,6
console.log(y);//[0,1,7,8,9]顯示原數組中的數值被剔除掉了
複製代碼

slice和splice雖然都是對於數組對象進行截取,可是兩者仍是存在明顯區別,函數參數上slice和splice第一個參數都是截取開始位置,slice第二個參數是截取的結束位置(不包含),而splice第二個參數(表示這個從開始位置截取的長度),slice不會對原數組產生變化,而splice會直接剔除原數組中的截取數據!
slice不會改變原數組,splice會改變原數組

七、數值轉換

JSON.parse() 轉json對象
JSON.stringify() 轉json字符串
String(),toString() 轉字符串類型
Number parseInt()字符串轉數值類型
split 字符串轉數組
join 數組轉字符串

八、什麼是跨域,常見跨域

因爲瀏覽器獲取數據遵循同源策略,因此當訪問非同源資源的時候,就須要跨域,常見的跨域方式有jsonp,a img src cors
同源策略:同協議,端口,域名的安全策略
jsonp原理
動態建立script標籤,利用callpack回調函數獲取值

function callbackFunction(){
  alert("回滾");
}
var script=document.createElement("script");
script.src="http://frergeoip.net.json/?callback=callbackFunction";
複製代碼

CORS的原理
當傳輸數據量比較大,get形式搞不定的時候,能夠用到cors跨域,cors原理是定義一種跨域訪問的機制,可讓ajax實現跨域訪問。Cors容許一個域上的網絡應用向另外一個域提交跨域ajax請求。實現此功能很是簡單,只需由服務器發送一個響應標頭便可。 Jsonp是get形式,承載的信息量有限,因此信息量較大的時cors是不二選擇。

九、http協議:

http協議是定義服務器端和客戶端之間文件傳輸的溝通方式
請求服務器上的資源,請求html css js 圖片文件等
請求方法(全部方法全爲大寫)有多種,各個方法的解釋以下:
GET (get) 請求獲取Request-URI所標識的資源 --獲取資源
POST (post) 在Request-URI所標識的資源後附加新的數據 ---傳輸資源
HEAD (head) 請求獲取由Request-URI所標識的資源的響應消息報頭 ---獲取報文首部
PUT (put) 請求服務器存儲一個資源,並用Request-URI做爲其標識 ---更新資源
DELETE (delete) 請求服務器刪除Request-URI所標識的資源 ---刪除資源
TRACE (trace) 請求服務器回送收到的請求信息,主要用於測試或診斷
CONNECT(connect) 保留未來使用
OPTIONS(options) 請求查詢服務器的性能,或者查詢與資源相關的選項和需求
常見狀態碼:
200 請求成功
301 資源(網頁等)被永久轉移到其餘url
404 請求的資源不存在
500 內部服務器錯誤

十、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 服務器端暫時沒法處理請求(多是過載或維護)。

十一、說說你對閉包的理解?

使用閉包主要是爲了設計私有的方法和變量。閉包的優勢是能夠避免全局變量的污染,缺點是閉包會常駐內存,會增大內存使用量,使用不當很容易形成內存泄露。
閉包有三個特性:
1.函數嵌套函數
2.函數內部能夠引用外部的參數和變量
3.參數和變量不會被垃圾回收機制回收
閉包用途
1緩存
設想咱們有一個處理過程很耗時的函數對象,每次調用都會花費很長時間,那麼咱們就須要將計算出來的值存儲起來,當調用這個函數的時候,首先在緩存中查找,若是找不到,則進行計算,而後更新緩存並返回值,若是找到了,直接返回查找到的值便可。閉包正是能夠作到這一點,由於它不會釋放外部的引用,從而函數內部的值能夠得以保留。
2 實現封裝
能夠先來看一個關於封裝的例子,在person以外的地方沒法訪問其內部的變量,而經過提供閉包的形式來訪問:

var person = function(){    
    //變量做用域爲函數內部,外部沒法訪問 
    var name = "default";              
    return {    
       getName : function(){    
           return name;    
       },    
       setName : function(newName){    
           name = newName;    
       }    
    }    
}();        
print(person.name);//直接訪問,結果爲undefined 
print(person.getName());    
person.setName("abruzzi");    
print(person.getName()); 
複製代碼

十二、如何阻止事件冒泡?

ie:阻止冒泡ev.cancelBubble = true;
非IE ev.stopPropagation();

1三、如何阻止默認事件?

(1)return false;(2) ev.preventDefault();

1四、事件代理

事件代理是指,對父盒子綁定事件,而後子盒子觸發事件,因爲產生事件冒泡,致使父盒子事件也被觸發,此時,在父盒子的時間處理函數中,能夠經過srcElement或者target屬性來獲取目標時間,並對其進行相應的處理

1五、添加 刪除 替換 插入到某個節點的方法?

1)建立新節點
createElement() //建立一個具體的元素
createTextNode() //建立一個文本節點
 
2)添加、移除、替換、插入
appendChild() //添加
removeChild() //移除
replaceChild() //替換
insertBefore() //插入
 
3)查找
getElementsByTagName() //經過標籤名稱
getElementsByName() //經過元素的Name屬性的值
getElementById() //經過元素Id,惟一性
複製代碼

1六、document load 和document ready的區別?

document.onload 是在結構和樣式,外部js以及圖片加載完才執行js
document.ready是dom樹建立完成就執行的方法,原生種沒有這個方法,jquery中有 $().ready(function)

1七、Javascript的事件流模型都有什麼?

「事件捕捉」:是從上往下,window,document,document.documentelment(獲取的html) document,body 、……..目標元素

「事件冒泡」:是從下往上:反之

「DOM事件流」:三個階段:事件捕捉、目標階段、事件冒泡

image.png
Dom事件類:

Dom0  element.onclick=function(){}

DOM2 element.addEventlistener(‘click’,function(){},flase)

DOM3 element.addEventlistener(‘keyup’,function(){},flase)

Event.preventdefault()  阻止默認事件

Event.stoppropagation()  阻止冒泡

Event.currenTtarget()事件代理 

Event.target 當前被點擊元素
複製代碼

1八、null和undefined的區別?

null是一個表示"無"的對象,轉爲數值時爲0;undefined是一個表示"無"的原始值,轉爲數值時爲NaN。
當聲明的變量還未被初始化時,變量的默認值爲undefined。 null用來表示還沒有存在的對象,經常使用來表示函數企圖返回一個不存在的對象。

1九、call() 和 .apply() 的區別和做用?

相同點:兩個方法產生的做用是徹底同樣的,都是改變this指向的

不一樣點:方法傳遞的參數不一樣

Object.call(this,obj1,obj2,obj3)

Object.apply(this,arguments)

Apply()接收兩個參數,一個是函數運行的做用域(this),另外一個是參數數組。

Call()方法的第一個參數與apply()相同,但傳遞的參數必須列舉出來。

20、mvc和mvvm模式原理:

image.png

2一、JS爲何要區分微任務和宏任務?

(1)js是單線程的,可是分同步異步
(2)微任務和宏任務皆爲異步任務,它們都屬於一個隊列
(3)宏任務通常是:script,setTimeout,setInterval、setImmediate
(4)微任務:原生Promise
(5)遇到微任務,先執行微任務,執行完後若是沒有微任務,就執行下一個宏任務,若是有微任務,就按順序一個一個執行微任務

2二、setTimeout和setInterval

//setTimeout是3秒後執行
 setTimeout(function(){
 alert(123)
 },3000)

//setInterval是每隔三秒執行一次,不斷的重複執行
 setInterval(function(){
 alert(1121222)
 },3000)
//兩個執行都是異步進行的
複製代碼

2三、深拷貝淺拷貝

深拷貝和淺拷貝最根本的區別在因而否真正獲取一個對象的複製實體,而不是引用。

假設B複製了A,修改A的時候,看B是否發生變化:

若是B跟着也變了,說明是淺拷貝,拿人手短!(修改堆內存中的同一個值)

若是B沒有改變,說明是深拷貝,自食其力!(修改堆內存中的不一樣的值)
淺拷貝實現:

var a = [1, 2, 3, 4, 5];
  var b = a;
  a[0] = 2
  console.log(a);//[2,2,3,4,5]
  console.log(b);//[2,2,3,4,5] ////b會隨着a的變化而變化
複製代碼

深拷貝實現:

var a = [{"name":"weifeng"},{"name":"boy"}];
  var a_copy =[].concat(JSON.parse(JSON.stringify(a)));//深拷貝
  a_copy[1].name = "girl"
  console.log(a);//[{"name":"weifeng"},{"name":"boy"}]
  console.log(a_copy );//[{"name":"weifeng"},{"name":"girl"}] 
複製代碼

2四、重排重繪

迴流(重排):
當render tree中的一部分(或所有)由於元素的規模尺寸,佈局,隱藏等改變而須要從新構建。這就稱爲迴流(reflow)。每一個頁面至少須要一次迴流,就是在頁面第一次加載的時候,這時候是必定會發生迴流的,由於要構建render tree。在迴流的時候,瀏覽器會使渲染樹中受到影響的部分失效,並從新構造這部分渲染樹,完成迴流後,瀏覽器會從新繪製受影響的部分到屏幕中,該過程成爲重繪。
重繪:
當render tree中的一些元素須要更新屬性,而這些屬性只是影響元素的外觀,風格,而不會影響佈局的,好比background-color。則就叫稱爲重繪。
區別:
迴流必將引發重繪,而重繪不必定會引發迴流。好比:只有顏色改變的時候就只會發生重繪而不會引發迴流 當頁面佈局和幾何屬性改變時就須要迴流 好比:添加或者刪除可見的DOM元素,元素位置改變,元素尺寸改變——邊距、填充、邊框、寬度和高度,內容改變。

2五、防抖和節流?

在前端開發的過程當中,咱們常常會須要綁定一些持續觸發的事件,如 resize、scroll、mousemove keyup 等等,但有些時候咱們並不但願在事件持續觸發的過程當中那麼頻繁地去執行函數。

一般這種狀況下咱們怎麼去解決的呢?通常來說,防抖和節流是比較好的解決方案。
一、防抖:
指觸發事件後在n秒後函數執行,若是在n秒內又觸發了事件,則會從新計算函數執行時間。應用場景(適合屢次事件只響應一次的狀況):給按鈕加防抖函數防止表單屢次提交;判斷scroll是否滑到底部;對於輸入框連續輸入進行AJAX驗證時,用函數防抖能有效減小請求次數。
現給一個場景:現監聽一個輸入框,文字變化後觸發change事件。若直接用keyup事件,則會頻繁觸發change事件。加了防抖後,用戶輸入結束或暫停時,纔會觸發change事件。
所謂防抖,就是指觸發事件後在 n 秒內函數只能執行一次,若是在 n 秒內又觸發了事件,則會從新計算函數執行時間。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input type="text" id="input1">
</body>
<script> const input1 = document.getElementById('input1') //一、不加防抖 ,會一直觸發change事件 input1.addEventListener('keyup', function(){ console.log(input1.value) }) //二、簡單實現防抖 let timer = null input1.addEventListener('keyup', function(){ if(timer){ clearTimeout(timer) } timer = setTimeout(() => { //模擬觸發change事件 console.log(input1.value) //清空定時器 timer = null }, 1000) }) //三、將防抖函數這個工具進行封裝 function debounce(fn, delay = 50){ //timer是閉包中的,不能被別人修改 let timer = null return function(){ if(timer){ clearTimeout(timer) } timer = setTimeout(() => { fn.apply(this, arguments) timer = null }, delay) } } input1.addEventListener('keyup', debounce(function(){ console.log(input1.value) }, 600)) </script>
</html>
複製代碼

則封裝後的防抖函數爲:

function debounce(fn, delay = 50){
        let timer = null  //timer是閉包中的,不能被別人修改
        return function(){
            if(timer){
                clearTimeout(timer)
            }
            timer = setTimeout(() => {
                fn.apply(this, arguments)
                timer = null
            }, delay)
        }
    }
複製代碼

二、節流:
連續發送的事件在n秒內只執行一次函數。應用場景(適合大量事件按時間作平均分配觸發):DOM元素拖拽;Canvas畫筆功能。
現給一個場景:拖拽一個元素,要隨時拿到該元素被拖拽的位置。若直接用drag事件,則會頻繁觸發,很容易致使卡頓。加了節流後,不管拖拽速度多快,都會每隔固定時間觸發一次。
所謂節流,就是指連續觸發事件可是在 n 秒中只執行一次函數。節流會稀釋函數的執行頻率。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style> #div1{ border: 1px solid #ccc; width: 200px; height: 100px; } </style>
</head>
<body>
    <div id = "div1" draggable="true">可拖拽</div>
    <script> const div1 = document.getElementById('div1') //一、簡單實現節流 let timer = null div1.addEventListener('drag', function(e){ if(timer){ return } timer = setTimeout(() => { console.log(e.offsetX, e.offsetY) timer = null //定時器執行了,才讓timer爲空 }, 1000) }) //二、將節流函數這個工具進行封裝 function throttle(fn, delay = 100){ let timer = null return function(){ if(timer){ return } timer = setTimeout(() => { fn.apply(this, arguments) timer = null },delay) } } div1.addEventListener('drag', throttle(function(e){ //形參e會傳給throttle函數運行後返回的函數 console.log(e.offsetX, e.offsetY) },200)) </script>
</body>
</html>
複製代碼

則封裝後的節流函數爲:

function throttle(fn, delay = 100){
            let timer = null
            return function(){ 
                if(timer){
                    return
                }
                timer = setTimeout(() => {
                    fn.apply(this, arguments)
                    timer = null
                },delay)
            }
        }
複製代碼

2六、一個頁面從輸入 URL 到頁面加載顯示完成,這個過程當中都發生了什麼?

分爲4個步驟:
(1),當發送一個URL請求時,無論這個URL是Web頁面的URL仍是Web頁面上每一個資源的URL,瀏覽器都會開啓一個線程來處理這個請求,同時在遠程DNS服務器上啓動一個DNS查詢。這能使瀏覽器得到請求對應的IP地址。
(2), 瀏覽器與遠程Web服務器經過TCP三次握手協商來創建一個TCP/IP鏈接。該握手包括一個同步報文,一個同步-應答報文和一個應答報文,這三個報文在 瀏覽器和服務器之間傳遞。該握手首先由客戶端嘗試創建起通訊,然後服務器應答並接受客戶端的請求,最後由客戶端發出該請求已經被接受的報文。
(3),一旦TCP/IP鏈接創建,瀏覽器會經過該鏈接向遠程服務器發送HTTP的GET請求。遠程服務器找到資源並使用HTTP響應返回該資源,值爲200的HTTP響應狀態表示一個正確的響應。
(4),此時,Web服務器提供資源服務,客戶端開始下載資源。
請求返回後,便進入了咱們關注的前端模塊
簡單來講,瀏覽器會解析HTML生成DOM Tree,其次會根據CSS生成CSS Rule Tree,而javascript又能夠根據DOM API操做DOM
詳情:從輸入 URL 到瀏覽器接收的過程當中發生了什麼事情?

2七、說說TCP傳輸的三次握手策略

爲了準確無誤地把數據送達目標處,TCP協議採用了三次握手策略。用TCP協議把數據包送出去後,TCP不會對傳送 後的狀況置之不理,它必定會向對方確認是否成功送達。握手過程當中使用了TCP的標誌:SYN和ACK。 發送端首先發送一個帶SYN標誌的數據包給對方。接收端收到後,回傳一個帶有SYN/ACK標誌的數據包以示傳達確認信息。最後,發送端再回傳一個帶ACK標誌的數據包,表明「握手」結束 若在握手過程當中某個階段莫名中斷,TCP協議會再次以相同的順序發送相同的數據包。

2八、說說你對語義化的理解?

1,去掉或者丟失樣式的時候可以讓頁面呈現出清晰的結構
2,有利於SEO:和搜索引擎創建良好溝通,有助於爬蟲抓取更多的有效信息:爬蟲依賴於標籤來肯定上下文和各個關鍵字的權重;
3,方便其餘設備解析(如屏幕閱讀器、盲人閱讀器、移動設備)以意義的方式來渲染網頁;
4,便於團隊開發和維護,語義化更具可讀性,是下一步吧網頁的重要動向,遵循W3C標準的團隊都遵循這個標準,能夠減小差別化

2九、你如何對網站的文件和資源進行優化?

期待的解決方案包括:
文件合併
文件最小化/文件壓縮
使用 CDN 託管
緩存的使用(多個域名來提供緩存)
其餘

30、請說出三種減小頁面加載時間的方法?

一、壓縮css、js文件
二、合併js、css文件,減小http請求
三、外部js、css文件放在最底下
四、減小dom操做,儘量用變量替代沒必要要的dom操做

3一、js延遲加載的方式有哪些?

defer和async、動態建立DOM方式(建立script,插入到DOM中,加載完畢後callBack)、按需異步載入js

3二、你有哪些性能優化的方法?

(詳情請看雅虎14條性能優化原則)。
(1) 減小http請求次數:CSS Sprites, JS、CSS源碼壓縮、圖片大小控制合適;網頁Gzip,CDN託管,data緩存 ,圖片服務器。
(2) 前端模板 JS+數據,減小因爲HTML標籤致使的帶寬浪費,前端用變量保存AJAX請求結果,每次操做本地變量,不用請求,減小請求次數
(3) 用innerHTML代替DOM操做,減小DOM操做次數,優化javascript性能。
(4) 當須要設置的樣式不少時設置className而不是直接操做style。
(5) 少用全局變量、緩存DOM節點查找的結果。減小IO讀取操做。
(6) 避免使用CSS Expression(css表達式)又稱Dynamic properties(動態屬性)。
(7) 圖片預加載,將樣式表放在頂部,將腳本放在底部 加上時間戳。

3三、異步加載和延遲加載

1.異步加載的方案: 動態插入script標籤
2.經過ajax去獲取js代碼,而後經過eval執行
3.script標籤上添加defer或者async屬性
4.建立並插入iframe,讓它異步執行js
5.延遲加載:有些 js 代碼並非頁面初始化的時候就馬上須要的,而稍後的某些狀況才須要的。

3四、GET和POST的區別,什麼時候使用POST?

GET:通常用於信息獲取,使用URL傳遞參數,對所發送信息的數量也有限制,通常在2000個字符
POST:通常用於修改服務器上的資源,對所發送的信息沒有限制。
GET方式須要使用Request.QueryString來取得變量的值,而POST方式經過Request.Form來獲取變量的值,也就是說Get是經過地址欄來傳值,而Post是經過提交表單來傳值。
然而,在如下狀況中,請使用 POST 請求:
沒法使用緩存文件(更新服務器上的文件或數據庫)
向服務器發送大量數據(POST 沒有數據量限制)
發送包含未知字符的用戶輸入時,POST 比 GET 更穩定也更可靠

3五、平時如何管理你的項目?

先期團隊必須肯定好全局樣式(globe.css),編碼模式(utf-8) 等;
編寫習慣必須一致(例如都是採用繼承式的寫法,單樣式都寫成一行);
標註樣式編寫人,各模塊都及時標註(標註關鍵樣式調用的地方);
頁面進行標註(例如 頁面 模塊 開始和結束);
CSS跟HTML 分文件夾並行存放,命名都得統一(例如style.css);
JS 分文件夾存放 命名以該JS功能爲準的英文翻譯。

3六、你如何優化本身的代碼?

代碼重用
避免全局變量(命名空間,封閉空間,模塊化mvc…)
拆分函數避免函數過於臃腫
註釋

3七、什麼是 FOUC(無樣式內容閃爍)?你如何來避免 FOUC? 

FOUC - Flash Of Unstyled Content 文檔樣式閃爍
<style type="text/css" media="all">@import "../fouc.css";</style>
複製代碼

而引用CSS文件的@import就是形成這個問題的罪魁禍首。IE會先加載整個HTML文檔的DOM,而後再去導入外部的CSS文件,所以,在頁面DOM加載完成到CSS導入完成中間會有一段時間頁面上的內容是沒有樣式的,這段時間的長短跟網速,電腦速度都有關係。

解決方法簡單的出奇,只要在<head>之間加入一個<link>或者<script>元素就能夠了。
複製代碼

3八、網站重構的理解?

網站重構:在不改變外部行爲的前提下,簡化結構、添加可讀性,而在網站前端保持一致的行爲。也就是說是在不改變UI的狀況下,對網站進行優化,在擴展的同時保持一致的UI。
對於傳統的網站來講重構一般是:
表格(table)佈局改成DIV+CSS
使網站前端兼容於現代瀏覽器(針對於不合規範的CSS、如對IE6有效的)
對於移動平臺的優化
針對於SEO進行優化
深層次的網站重構應該考慮的方面
減小代碼間的耦合
讓代碼保持彈性
嚴格按規範編寫代碼
設計可擴展的API
代替舊有的框架、語言(如VB)
加強用戶體驗
一般來講對於速度的優化也包含在重構中
壓縮JS、CSS、image等前端資源(一般是由服務器來解決)
程序的性能優化(如數據讀寫)
採用CDN來加速資源加載
對於JS DOM的優化
HTTP服務器的文件緩存

3九、什麼叫優雅降級和漸進加強?

優雅降級:Web站點在全部新式瀏覽器中都能正常工做,若是用戶使用的是老式瀏覽器,則代碼會檢查以確認它們是否能正常工做。因爲IE獨特的盒模型佈局問題,針對不一樣版本的IE的hack實踐過優雅降級了,爲那些沒法支持功能的瀏覽器增長候選方案,使之在舊式瀏覽器上以某種形式降級體驗卻不至於徹底失效.
漸進加強:從被全部瀏覽器支持的基本功能開始,逐步地添加那些只有新式瀏覽器才支持的功能,向頁面增長無害於基礎瀏覽器的額外樣

40、棧和隊列的區別?

棧的插入和刪除操做都是在一端進行的,而隊列的操做倒是在兩端進行的。
隊列先進先出,棧先進後出。
棧只容許在表尾一端進行插入和刪除,而隊列只容許在表尾一端進行插入,在表頭一端進行刪除

4一、棧和堆的區別?

棧區(stack)— 由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。
堆區(heap) — 通常由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收。
堆(數據結構):堆能夠被當作是一棵樹,如:堆排序;
棧(數據結構):一種先進後出的數據結構。

4二、對前端界面工程師這個職位是怎麼樣理解的?它的前景會怎麼樣?

前端是最貼近用戶的程序員,比後端、數據庫、產品經理、運營、安全都近。
一、實現界面交互
二、提高用戶體驗
三、有了Node.js,前端能夠實現服務端的一些事情
前端是最貼近用戶的程序員,前端的能力就是能讓產品從 90分進化到 100 分,甚至更好,
參與項目,快速高質量完成實現效果圖,精確到1px;
與團隊成員,UI設計,產品經理的溝通;
作好的頁面結構,頁面重構和用戶體驗;
處理hack,兼容、寫出優美的代碼格式;
針對服務器的優化、擁抱最新前端技術。

代碼算法之類

4三、數組去重indexOf

var arr=[1,1,2,2,3,4,5,7,8,9,6,4,6,2,]
var arr2=[]
for(var i=0;i<arr.length;i++){
    if(arr2.indexOf(arr[i])<0){
        arr2.push(arr[i])
    }
}
console.log(arr2) 
複製代碼

4四、es6方法數組去重

let a = [1,5,6,3,8,0,5,7,0,4,2,7,5,4,5,9,22]
let b=new Set([...a])
console.log(b);
b=[...b];
console.log(b)
複製代碼

4五、冒泡排序

var arr=[1,3,4,6,8,0,2,5,7,4,9,2];
var temp=0;
for (var i=0;i<arr.length;i++) {
    for(var j=0;j<arr.length-i;j++){
        if(arr[j]<arr[j+1]){
            temp=arr[j+1];
            arr[j+1]=arr[j];
            arr[j]=temp;
        }
    }
}
console.log(arr)
複製代碼

4六、獲取url中的參數

//測試地址:http://www.runobb.com/jqur/dfev.html?name=xiaohong&age=22
   function showWindowHref(){
        var sHref=window.location.href;
        var args=sHref.split('?');
        if(args[1]==sHref){
            return '';
        }
        var aa=args[1].split('&');
        var obj={}
        for (var i=0;i<aa.length;i++) {
            var bb=aa[i].split('=')
            obj[bb[0]]=bb[1]
        }
        return obj;             
    }
複製代碼

4七、降維數組

//利用[].concat.apply實現降維 
    var arr=[[1,2],[3,4]];
    function Jw(obj){
        console.log(Array.prototype.concat.apply([],obj))
            return Array.prototype.concat.apply([],obj);
    }
    Jw(arr);
//若是concat方法的參數是一個元素,該元素會直接插入新數組中;若是參數是一個數組,該數組的各個元素將被插入到新數組中
    function reduceDimension(arr){
        let ret = [];
        for(let i=0;i<arr.length;i++){
            ret=ret.concat(arr[i])
        }
        console.log(ret)
        return ret;
    }
    reduceDimension(arr)  
//遞歸
    function reduceDimension(arr){
        let ret = [];
        let toArr = function(arr){
            arr.forEach(function(item){
                item instanceof Array ? toArr(item) : ret.push(item);
            });
        }
        toArr(arr);
        console.log(ret)
        return ret;
    }
    reduceDimension([1, 2, [3, 4, [5, 6]]])   
 //flat
     let list = [1, 2, 3, [4, [5]]];
     let res = list.flat(Infinity)
     console.log(res) // [1, 2, 3, 4, 5]
複製代碼

4八、js判斷一個字符串中出現次數最多的字符,統計這個次數

var str = 'asdfssaaasasasasaa';
var json = {};
for (var i = 0; i < str.length; i++) {
    if(!json[str.charAt(i)]){
       json[str.charAt(i)] = 1;
    }else{
       json[str.charAt(i)]++;
    }
};
var iMax = 0;
var iIndex = '';
for(var i in json){
    if(json[i]>iMax){
         iMax = json[i];
         iIndex = i;
    }
}
console.log('出現次數最多的是:'+iIndex+'出現'+iMax+'次');  //出現次數最多的是:a出現 9次
複製代碼
let string = 'kapilalipak';
const table={}; 
for(let char of string) {
    table[char]=table[char]+1 || 1;
}
// 輸出
console.log(table)// {k: 2, a: 3, p: 2, i: 2, l: 2}
複製代碼

4九、寫一個function,清除字符串先後的空格。(兼容全部瀏覽器)

function trim(str) {
    if (str & typeof str === "string") {
        return str.replace(/(^s*)|(s*)$/g,""); //去除先後空白符
    }
}
複製代碼

50、如何用jquery禁用瀏覽器的先後進退按鈕?

<script type="text/javascript" language="javascript">
$(document).ready(function() { 
     window.history.forward(1);
     //OR 
     window.history.forward(-1);  
});  
</script>
複製代碼

獲取頁面中全部的checkbox怎麼作?(不使用第三方框架)

var inputs = document.getElementsByTagName("input");//獲取全部的input標籤對象
var checkboxArray = [];//初始化空數組,用來存放checkbox對象。
for(var i=0;i<inputs.length;i++){
  var obj = inputs[i];
  if(obj.type=='checkbox'){
     checkboxArray.push(obj);
  }
}
複製代碼

5一、程序中捕獲異常的方法?

try{
  
}catch(e){
  
}finally{
  
}
複製代碼

5二、js排序

升序降序排序函數sortNumber

const arr1 = [6,1,2,3,4];
function sortNumber(a,b){
     return b-a;
}
arr1.sort(sortNumber);
console.log(arr1)
// [6, 4, 3, 2, 1]
複製代碼

按照flag排序,爲true的在前面顯示

const arr2 = [
            { id: 10, flag: true },
            { id: 5, flag: false },
            { id: 6, flag: true },
            { id: 9, flag: false }
];
const r = arr2.sort((a, b) => b.flag - a.flag);
console.log(r);
// [
// { id: 10, flag: true },
// { id: 6, flag: true },
// { id: 5, flag: false },
// { id: 9, flag: false }
// ]
複製代碼

喜歡的小夥伴點個贊吧,感受對身邊人有幫助的,麻煩動動手指,分享一下。感謝各位花時間閱讀完,同時也感謝各位的點贊和分享。

結語

若是你以爲這篇文章對你有點用的話,麻煩請給咱們的開源項目點點star: http://github.crmeb.net/u/defu   不勝感激 !
 
來自 「開源獨尊 」 ,連接:   https://ym.baisou.ltd/post/836.html
相關文章
相關標籤/搜索