jacascript 面試題整理

一、React 中 keys 的做用是什麼?

Keys 是 React 用於追蹤哪些列表中元素被修改、被添加或者被移除的輔助標識。javascript

render () {  
    return (
        <ul>
            {this.state.todoItems.map(
                ({item, key}) => { 
                    return <li key={key}>{item}</li>
                })
            }    
        </ul>  
    )}
複製代碼

在開發過程當中,咱們須要保證某個元素的 key 在其同級元素中具備惟一性。在 React Diff 算法中 React 會藉助元素的 Key 值來判斷該元素是新近建立的仍是被移動而來的元素,從而減小沒必要要的元素重渲染。此外,React 還須要藉助 Key 值來判斷元素與本地狀態的關聯關係,所以咱們毫不可忽視轉換函數中 Key 的重要性。css

二、正則表達式驗證相關面試題。

// 手機號碼
function checkPhone(phone){ 
    if(!(/^1[3456789]\d{9}$/.test(phone))){ 
        alert("手機號碼有誤,請重填");  
        return false; 
    } 
}
// 判斷字符串以字母開頭,後面能夠是數字,下劃線,字母,長度爲6-30
function checout(str){
    var reg=/^[a-zA-Z]\w{5,29}$/;
    if(str && reg.test(str)){
        alert('正確')
    }
}
// 寫一個function,清除字符串先後的空格。
function trim(str) {
    if (str & typeof str === "string") {
        return str.replace(/(^s*)|(s*)$/g,""); 
    }
}
複製代碼

三、javascript的typeof返回哪些數據類型.

string,boolean,number,undefined,function,objecthtml

四、例舉3種強制類型轉換和2種隱式類型轉換?

答案:強制(parseInt,parseFloat,number) 隱式(== ===)前端

四、split() join() 的區別

答案:前者是將字符串切割成數組的形式,後者是將數組轉換成字符串vue

五、 ajax請求的時候get 和post方式的區別

  • GET請求會將參數跟在URL後進行傳遞,而POST請求則是做爲HTTP消息的實體內容發送給WEB服務器。固然在Ajax請求中,這種區別對用戶是不可見的
  • GEt傳輸數據容量小,不安全,post傳輸數據內容大,更加安全;

六、call和apply的區別

相同點:改變函數的this指向java

var obj = {name: 'lisi'}
function fn() {
   console.log(this) 
}
fn.call(null)    //this指向window
fn.apply(null)   //this指向window
fn.call(obj)     //this指向obj
fn.apply(obj)    //this指向obj
複製代碼

不一樣點: call傳參形式是,從第二個開始一個一個傳,apply的第二個參數爲數組,數組的每一項爲函數的參數react

Object.call(this,obj1,obj2,obj3)
Object.apply(this,arguments)
複製代碼

七、事件委託是什麼

利用事件冒泡的原理,讓本身的所觸發的事件,讓他的父元素代替執行!git

八、閉包是什麼,有什麼特性,對頁面有什麼影響,有什麼好處,閉包使用場景:

***閉包***就是可以讀取其餘函數內部變量的函數,使得函數不被GC回收,若是過多使用閉包,容易致使內存泄露(再也不用到的內存,沒有及時釋放,就叫作內存泄漏) 閉包的好處 但願一個變量長期駐紮在內存當中(不被垃圾回收機制回收), 避免全局變量的污染,私有成員的存在,安全性提升 閉包使用場景: 函數做爲返回值;函數做爲參數傳遞;閉包實際應用中主要用於封裝變量,收斂權限;web

九、如何阻止事件冒泡,如何阻止默認事件

阻止事件冒泡:ev.stopPropagation();何阻止默認事件: (1)return false;(2) ev.preventDefault();面試

十、 解釋jsonp的原理,以及爲何不是真正的ajax

動態建立script標籤,回調函數,Ajax是頁面無刷新請求數據操做

十一、」==」和「===」的不一樣

前者會自動轉換類型,再判斷是否相等,後者不會自動類型轉換,直接去比較

十二、函數聲明與函數表達式的區別?

在Javscript中,解析器在向執行環境中加載數據時,對函數聲明和函數表達式並不是是一視同仁的,解析器會率先讀取函數聲明,並使其在執行任何代碼以前可用(能夠訪問),至於函數表達式,則必須等到解析器執行到它所在的代碼行,纔會真正被解析執行。

// 函數聲明   
 function add(){} 
 // 函數表達式
var del = function del(){} // 命名函數函數表達式
var update= function(){} // 命名函數函數表達式
function(){} // 匿名函數表達式
複製代碼

函數表達式能夠直接在函數定義後面加小括號執行,而函數聲明則不行

var mult = function(x,y){ return(x*y); }();//正常
function div(x,y){ return(x/y); }()//報錯 
複製代碼

1三、對做用域上下文和this的理解,看下列代碼:

var User = {
 count: 1,
 getCount: function() {
  return this.count;
 }
};
console.log(User.getCount()); // what?
var func = User.getCount;
console.log(func()); // what?
複製代碼

問兩處console輸出什麼?爲何? 答案:是1和undefined。  func是在window的上下文中被執行的,因此不會訪問到count屬性。

1四、看下面代碼,給出輸出結果

for(var i = 1; i <= 3; i++){  //建議使用let 可正常輸出i的值
  setTimeout(function(){
      console.log(i);   
  },0); 
};
複製代碼

答案:4 4 4。 緣由:Javascript事件處理器在線程空閒以前不會運行。

1五、Javascript的事件流模型都有什麼?以及事件流的典型應用事件代理

  • 「事件冒泡」:事件開始由最具體的元素接受,而後逐級向上傳播
  • 「事件捕捉」:事件由最不具體的節點先接收,而後逐級向下,一直到最具體的
  • 「DOM事件流」:三個階段:事件捕捉,目標階段,事件冒泡

事件代理

  • 事件代理的原理用到的就是事件冒泡和目標元素,把事件處理器添加到父元素,等待子元素事件冒泡,而且父元素可以經過target(IE爲srcElement)判斷是哪一個子元素或者e.stopPropagation()阻止冒泡,從而作相應處理。
  • 1)將多個事件處理器減小到一個,由於事件處理器要駐留內存,這樣就提升了性能。想象若是有一個100行的表格,對比傳統的爲每一個單元格綁定事件處理器的方式和事件代理(即table上添加一個事件處理器),不可貴出結論,事件代理確實避免了一些潛在的風險,提升了性能。 2)DOM更新無需從新綁定事件處理器,由於事件代理對不一樣子元素可採用不一樣處理方法。若是新增其餘子元素(a,span,div等),直接修改事件代理的事件處理函數便可,不須要從新綁定處理器,不須要再次循環遍歷。

1六、下滿代碼輸出什麼

var a = null;
alert(typeof a);
答案:object
複製代碼

解釋:null是一個只有一個值的數據類型,這個值就是null。表示一個空指針對象,因此用typeof檢測會返回」object」。

1七、回答如下代碼,alert的值分別是多少?

<script>
    var a = 100;  
    function test(){  
        alert(a);  
        a = 10;  //去掉了var 就變成定義了全局變量了
        alert(a);  
    }  
    test();
    alert(a);
</script>
複製代碼

正確答案是: 100, 10, 10

1八、javaScript的2種變量範圍有什麼不一樣?

  • 全局變量:當前頁面內有效
  • 局部變量:函數方法內有效

1九、js 實現一個函數對javascript中json 對象進行克隆

var oldObject ="sdf";
var newObject = JSON.parse(JSON.stringify(oldObject));
console.log(newObject);
複製代碼

20、js 實現 ajax 請求或者submit請求時 鎖屏功能以及開鎖功能(請求時界面Loading以及元素不能點擊,請求完成即消除Loading)

function(url, fn) {
    // XMLHttpRequest對象用於在後臺與服務器交換數據
    var obj = new XMLHttpRequest(); 
    obj.open('GET', url, true);
    obj.onreadystatechange = function() {
        if(obj.readyState == 4 && obj.status == 200||obj.status == 304){
            loading.style.display = "none"
        } else {
            alert("不能點擊,哈哈哈!");
        }
    };
    obj.send(null);
}
複製代碼

2一、請用js計算1-10000中出現的0 的次數

// 建立一個1-10000的數組集合
var arr = new Array(10000).fill('').map((item, index) => {
     return index + 1
    }
)
// 篩選出了全部帶0的數字
var nerArrrr = arr.filter(item => /0/.test(item))
var length = nerArrrr.reduce((count, item) => { 
    return count + (String(item).match(/0/g)).length
}, 0)
console.log(length)
複製代碼

2二、數組降維

var arr = [[0,1,2,3], [4,5,6,7], [8,9,0,1], [2,3,4,5]];
// 方法一
var result = [];
for(var i=0;i<arr.length;i++){
    for(var j=0;j<arr[i].length;j++){
        result.push(arr[i][j]);
    }
}
// 方法二
var result = [];
for(var i=0;i<arr.length;i++){
    result = result.concat(arr[i]);
}
// 方法三
function Jw(obj){
    return Array.prototype.concat.apply([],obj);
}
Jw(arr);
複製代碼

2三、將url的查詢參數解析成字典對象

function getUrlDic(){
    var queryDec = window.location.search.substring(1).split("&")
    var decObect = {}
    for(var i = 0; i < queryDec.length; i++){
        var searchHash = queryDec[i].split("=")
        var key = decodeURIComponent(searchHash[0])
        var value = decodeURIComponent(searchHash[1])
        decObect[key] = value   
    }
    console.log(decObect)
}
getUrlDic()
複製代碼

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

let str = 'asfjasiofoivnoi';
function count(str){
   let obj = {},
   arr = str.split('');
   //遍歷數組
   arr.forEach(function(val,index){
       //將數組的元素存入對象,初始值爲1,若是後面遍歷的元素以前已存在就+1
       if(obj[val]){
           obj[val]+=1;
       }else{
           obj[val]=1                      
       }
   })
   //遍歷對象中的屬性(字符),值(出現的次數)
   let num=0
   for(let key in obj){
       if(num < obj[key]){
           //將最多的次數賦給num
           num = obj[key];
       }
   }
   for(let key in obj){
       if(num == obj[key]){
           console.log('最多的字符串是'+key+', 出現次數是'+num);
       }
   }
}
count(str);
複製代碼

2五、null和undefined的區別?

一、首先看一個判斷題:null和undefined 是否相等

console.log(null==undefined)//true
    console.log(null===undefined)//false
    typeof null; // "object"
    typeof undefined; // "undefined"
複製代碼
  • 緣由:null: Null類型,表明「空值」
  • 當一個聲明瞭一個變量未初始化時,獲得的就是undefined。

二、那到底何時是null,何時是undefined呢?null表示"沒有對象",即該處不該該有值。典型用法是

  • 做爲函數的參數,表示該函數的參數不是對象。

  • 做爲對象原型鏈的終點。

undefined表示"缺乏值",就是此處應該有一個值,可是尚未定義。典型用法是:

  • 變量被聲明瞭,但沒有賦值時,就等於undefined。
  • 調用函數時,應該提供的參數沒有提供,該參數等於undefined。
  • 對象沒有賦值的屬性,該屬性的值爲undefined。
  • 函數沒有返回值時,默認返回undefined。

2六、new操做符具體幹了什麼呢?

咱們知道 new 運算符是用來實例化一個類,從而在內存中分配一個實例對象。

new共通過了4幾個階段 一、建立一個空對象

var obj=new Object();
複製代碼

二、設置原型鏈

obj.__proto__= Base.prototype;
複製代碼

三、讓Base中的this指向obj,並執行Base的函數體。

var result =Base.call(obj);
複製代碼

四、判斷Base的返回值類型:若是是值類型,返回obj。若是是引用類型,就返回這個引用類型的對象。

if (typeof(result) == "object"){
  Base=result;
}
else{
    Base=obj;;
}
複製代碼

2七、defer和async的區別

defer和async都是可選的,且只對外部腳本文件有效

<script src="main.js"></script>
複製代碼

瀏覽器會當即加載並執行指定的腳本,「當即」指在渲染該script標籤之下的文檔元素以前,也就是說不等待後續載入的文檔元素,讀到就加載並執行。

<script async src="main.js"></script>
複製代碼

瀏覽器會當即下載腳本,但不妨礙頁面中的其餘操做,好比下載其餘資源或等待加載其餘腳本。加載和渲染後續文檔元素的過程和main.js的加載與執行並行進行(異步)。

async不保證按照腳本出現的前後順序執行,所以,確保二者以前互不依賴很是重要,指定async屬性的目的是不讓頁面等待兩個腳本的下載和執行,從而異步加載頁面其餘內容,建議異步腳本不要在加載期間修改DOM。

異步腳本必定會在頁面的load事件前執行,但可能會在DOMContentLoaded事件觸發以前或以後執行。

<script defer="defer" src="main1.js"></script>
<script defer="defer"  src="main2.js"></script>
複製代碼

表示腳本會被延遲到文檔徹底被解析和顯示以後再執行,加載後續文檔元素的過程將和main.js的加載並行進行(異步)。HTML5規範要求腳本按照它們出現的前後順序執行,所以第一個延遲腳本會先於第二個延遲腳本執行,而這兩個腳本會先於DOMContentLoaded事件。在現實當中,延遲腳本並不必定會按照順序執行,也不必定會在DOMContentLoaded事件觸發前執行,所以***最好只包含一個延遲腳本。***

  • defer 和 async 在網絡讀取(下載)這塊兒是同樣的,都是異步的(相較於 HTML 解析)
  • 它倆的差異在於腳本下載完以後什麼時候執行,顯然defer是最接近咱們對於應用腳本加載和執行的要求的
  • 關於 defer,此圖未盡之處在於它是按照加載順序執行腳本的,這一點要善加利用
  • async 則是一個亂序執行的主,反正對它來講腳本的加載和執行是牢牢挨着的,因此無論你聲明的順序如何,只要它加載完了就會馬上執行 仔細想一想,async 對於應用腳本的用處不大,由於它徹底不考慮依賴(哪怕是最低級的順序執行),不過它對於那些能夠不依賴任何腳本或不被任何腳本依賴的腳原本說倒是很是合適的,最典型的例子:Google Analytics

2七、js延遲加載的方式有哪些?

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

2八、javaScript的2種變量範圍有什麼不一樣?

  • 全局變量:當前頁面內有效
  • 局部變量:函數方法內有效

29vue雙向數據綁定的原理是什麼

首先傳輸對象的雙向數據綁定 Object.defineProperty(target, key, decription),在decription中設置get和set屬性(此時應注意description中get和set不能與描述屬性共存) 數組的實現與對象不一樣。

let obj = {}
let input = document.getElementById('input')
let span = document.getElementById('span')
Object.defineProperty(obj, 'text', {
  configurable: true,
  enumerable: true,
  get() {
    console.log('獲取數據了')
  },
  set(newVal) {
    console.log('數據更新了')
    input.value = newVal
    span.innerHTML = newVal
  }
})
input.addEventListener('keyup', function(e) {
  obj.text = e.target.value
})
複製代碼

同時運用觀察者模式實現wather, 完成用戶數據和view視圖的更新

2八、如下JS函數用於獲取url參數:

function getQueryVariable(variable)
{
   var query = window.location.search.substring(1);
   var vars = query.split("&");
   for (var i=0;i<vars.length;i++) {
       var pair = vars[i].split("=");
       if(pair[0] == variable){return pair[1];}
   }
   return(false);
}
複製代碼

2九、react setState後會發生什麼?

setState() 將老是觸發一次重繪,除非在 shouldComponentUpdate() 中實現了條件渲染邏輯。若是可變對象被使用了,但又不能在 shouldComponentUpdate() 中實現這種邏輯,僅在新 state 和以前的 state 存在差別的時候調用 setState() 能夠避免沒必要要的從新渲染。

react setState後:

  • React會將當前傳入的參數對象與組件當前的狀態合併,而後觸發調和過程,在調和的過程當中,React會以相對高效的方式根據新的狀態構建React元素樹而且從新渲染整個UI界面.
  • React獲得的元素樹以後,React會自動計算出新的樹與老的樹的節點的差別,而後根據差別對界面進行最小化的渲染,在React的差別算法中,React可以精確的知道在哪些位置發生看改變以及應該如何去改變,這樣就保證了UI是按需更新的而不是從新渲染整個界面.

setState—常規狀況:在同一個方法中屢次setState是會被合併的,而且對相同屬性的設置只保留最後一次的設置 參考詳情

3一、react 生命週期函數

初始化階段,這是組件即將開始其生命之旅並進入 DOM 的階段。

  • getDefaultProps:獲取實例的默認屬性

  • getInitialState:獲取每一個實例的初始化狀態

  • componentWillMount:組件即將被裝載、渲染到頁面上,在渲染以前執行,在客戶端和服務器端都會執行

  • render:組件在這裏生成虛擬的 DOM 節點

  • componentDidMount:僅在第一次渲染後在客戶端執行,組件真正在被裝載以後(請求數據)

  • 運行中狀態;一旦組件被添加到 DOM,它只有在 prop 或狀態發生變化時纔可能更新和從新渲染。這些只發生在這個階段。

  • componentWillReceiveProps:經過父組件修props改時候調用,當從父類接收到 props 而且在調用另外一個渲染器以前調用。

  • shouldComponentUpdate:(nextProps及nextState)組件接受到新屬性或者新狀態的時候(能夠返回 false,接收數據後不更新,阻止 render 調用,後面的函數不會被繼續執行了)

  • componentWillUpdate:在 DOM 中進行渲染以前調用,組件即將更新不能修改屬性和狀態

  • render:組件從新描繪

  • componentDidUpdate:在渲染髮生後當即調用,組件已經更新

銷燬階段,這是組件生命週期的最後階段,組件被銷燬並從 DOM 中刪除

componentWillUnmount:組件被卸載的時候調用。在此方法中執行任何須要的清理,通常在componentDidMount裏面註冊的事件須要在這裏刪除,例如使計時器無效、取消網絡請求或清除在組件,清理內存空間

3二、React綁定this的三種方式

  • bind()
  • 構造函數內部綁定,在構造函數constructor內綁定this,好處是僅須要綁定一次,避免每次渲染時都要從新綁定,函數在別處複用時也無需再次綁定
  • 箭頭函數 ##3三、 javascript對象和數組的深拷貝與淺拷貝 juejin.im/post/5d4830…

3四、Cookie在客戶機上是如何存儲的

Cookies就是服務器暫存放在你的電腦裏的文本文件,好讓服務器用來辨認你的計算機。當你在瀏覽網站的時候,Web服務器會先送一小小資料放在你的計算機上,Cookies 會幫你在網站上所打的文字或是一些選擇都記錄下來。當下次你再訪問同一個網站,Web服務器會先看看有沒有它上次留下的Cookies資料,有的話,就會依據Cookie裏的內容來判斷使用者,送出特定的網頁內容給你。

3五、編寫一個方法 去掉一個數組的重複元素

方法一:Array.from()方法能夠將Set結構轉化爲數組結構

function unique(array) {
    return Array.from(new Set(array));
}
unique([1,2,3,3]);
複製代碼

方法二:擴展運算符(…)內部使用for…of循環

let arr = [1,2,3,3];
let unique = [...new Set(arr)];
複製代碼

方法三

function unique(arr){
    var isRepeated, result = [];
    for(var i=0; i<arr.length; i++){
        isRepeated = false;
        for(var j=0; j<result.length; j++){
            if(arr[i] === result[j]){
                isRepeated = true;
                break;
            }
        }
        if(!isRepeated){
            result.push(arr[i]);
        }
    }
    return result;
}
var arr = [1,2,3,4,3,2,1,2,3];
console.log(unique(arr)); 
複製代碼

3六、7三、你如何組織本身的代碼?是使用模塊模式,仍是使用經典繼承的方法?

對內:模塊模式

對外:繼承

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

  • 代碼重用

  • 避免全局變量(命名空間,封閉空間,模塊化mvc..)

  • 拆分函數避免函數過於臃腫

  • 註釋

你能解釋一下JavaScript中的繼承是如何工做的嗎?

子構造函數中執行父構造函數,並用call\apply改變this 克隆父構造函數原型上的方法

3八、dom選擇器優先級是什麼,以及權重值計算(一道老問題了)

  • 1.行內樣式 1000
  • 2.id 100
  • 3.類選擇器、僞類選擇器、屬性選擇器[type="text"] 10
  • 4.標籤選擇器、僞元素選擇器(::first-line) 1
  • 5.通配符*、子選擇器、相鄰選擇器 0

3九、react和vue比較來講有什麼區別

react總體是函數式的思想,把組件設計成純組件,狀態和邏輯經過參數傳入,因此在react中,是單向數據流,推崇結合immutable來實現數據不可變。react在setState以後會從新走渲染的流程,若是shouldComponentUpdate返回的是true,就繼續渲染,若是返回了false,就不會從新渲染,PureComponent就是重寫了shouldComponentUpdate,而後在裏面做了props和state的淺層對比。

而vue的思想是響應式的,也就是基因而數據可變的,經過對每個屬性創建Watcher來監聽,當屬性變化的時候,響應式的更新對應的虛擬dom。

總之,react的性能優化須要手動去作,而vue的性能優化是自動的,可是vue的響應式機制也有問題,就是當state特別多的時候,Watcher也會不少,會致使卡頓,因此大型應用(狀態特別多的)通常用react,更加可控。

40、水平垂直居中

// 第一種
#container{
    position:relative;
}
#center{
    width:100px;
    height:100px;
    position:absolute;
    top:50%;
    left:50%;
    transform: translate(-50%,-50%);
}
// 第二種
#container{
    position:relative;
}
#center{
    width:100px;
    height:100px;
    position:absolute;
    top:50%;
    left:50%;
    margin:-50px 0 0 -50px;
}
// 第三種
#container{
    position:relative;
}

#center{
    position:absolute;
    margin:auto;
    top:0;
    bottom:0;
    left:0;
    right:0;
}
// 第四種 flex
#container{
    display:flex;
    justify-content:center;
    align-items: center;
}
複製代碼

4一、怎麼判斷兩個對象相等

JSON.stringify(obj)==JSON.stringify(obj);//true
複製代碼

4二、Vue router怎麼實現跳轉?

router-link 
router.go(1)
router.push('/')
複製代碼

4三、Vue router 跳轉和 location.href 有什麼區別?

router 是 hash 改變
location.href 是頁面跳轉,刷新頁面
複製代碼

4四、重排和重繪,什麼狀況會觸發重排和重繪

部分渲染樹(或者整個渲染樹)須要從新分析而且節點尺寸須要從新計算。這被稱爲重排。注意這裏至少會有一次重排-初始化頁面佈局。 因爲節點的幾何屬性發生改變或者因爲樣式發生改變,例如改變元素背景色時,屏幕上的部份內容須要更新。這樣的更新被稱爲重繪。

  • 添加、刪除、更新 DOM 節點
  • 經過 display: none 隱藏一個 DOM 節點-觸發重排和重繪
  • 經過 visibility: hidden 隱藏一個 DOM
  • 節點-只觸發重繪,由於沒有幾何變化
  • 移動或者給頁面中的 DOM 節點添加動畫
  • 添加一個樣式表,調整樣式屬性
  • 用戶行爲,例如調整窗口大小,改變字號,或者滾動。

4五、git使用過程當中,若是你在開發着業務,忽然另外一個分支有一個bug要改,你怎麼辦

git stash       //將本次修改存到暫存區(緊急切換分支時)
git stash list  
git stash pop   //將全部暫存區的內容取出來
複製代碼

4六、Git 經常使用命令

git add # 將工做區的修改提交到暫存區
git commit # 將暫存區的修改提交到當前分支
git reset # 回退到某一個版本
git stash # 保存某次修改
git pull # 從遠程更新代碼
git push # 將本地代碼更新到遠程分支上
git reflog # 查看歷史命令
git status # 查看當前倉庫的狀態
git diff # 查看修改
git log # 查看提交歷史
git revert # 回退某個修改
複製代碼

4七、js加載位置區別優缺點

html文件是自上而下的執行方式,但引入的css和javascript的順序有所不一樣,css引入執行加載時,程序仍然往下執行,而執行到script腳本是則中斷線程,待該script腳本執行結束以後程序才繼續往下執行。 因此,大部分網上討論是將script腳本放在body以後,那樣dom的生成就不會由於長時間執行script腳本而延遲阻塞,加快了頁面的加載速度。 但又不能將全部的script放在body以後,由於有一些頁面的效果的實現,是須要預先動態的加載一些js腳本。因此這些腳本應該放在body以前。 其次,不能將須要訪問dom元素的js放在body以前,由於此時尚未開始生成dom,因此在body以前的訪問dom元素的js會出錯,或者無效 script放置位置的原則「頁面效果實現類的js應該放在body以前,動做,交互,事件驅動,須要訪問dom屬性的js均可以放在body以後

4七、vue-cli 工程經常使用的 npm 命令有哪些?

npm install
npm run dev
npm run build
安裝模塊;
-save-dev 是指將包信息添加到 package.json 裏的 devDependencies節點,表示開發時依賴的包。
npm install --save-dev
-save 是指將包信息添加到 package.json 裏的dependencies節點,表示發佈時依賴的包。
npm install --save
複製代碼

4八、vue中 keep-alive 組件的做用?

keep-alive是Vue.js的一個內置組件。它可以把不活動的組件實例保存在內存中,而不是直接將其銷燬,它是一個抽象組件,不會被渲染到真實DOM中,也不會出如今父組件鏈中。 它提供了include與exclude兩個屬性,容許組件有條件地進行緩存。

4九、從瀏覽器地址欄輸入url到顯示頁面的步驟

(1)域名解析 在瀏覽器地址欄輸入URL,瀏覽器查看緩存,判斷請求資源是否新鮮,瀏覽器解析URL獲取協議,主機,端口,path。瀏覽器組裝一個HTTP(GET)請求報文,瀏覽器獲取主機ip地址(從緩存、hosts、路由、DNS解析等)

(2)TCP鏈接HTTP協議是使用TCP協議做爲其傳輸層協議的,在拿到服務器的IP地址後,瀏覽器客戶端會與服務器創建TCP鏈接。該過程包括三次握手

第一次握手:創建鏈接時,客戶端向服務端發送請求報文 第二次握手:服務器收到請求報文後,如贊成鏈接,則向客戶端發送確認報文 第三次握手,客戶端收到服務器的確認後,再次向服務器給出確認報文,完成鏈接。

三次握手主要是爲了防止已經失效的請求報文字段發送給服務器,浪費資源。 **(3)瀏覽器發送HTTP請求 瀏覽器構建http請求報文,並經過TCP協議傳送到服務器的指定端口。http請求報文一共包括三個部分: 請求行:指定http請求的方法、url、http協議版本等 請求頭:描述瀏覽器的相關信息,語言、編碼等,是否包含緩存驗證信息若是驗證緩存新鮮,返回304 請求正文:當發送POST,PUT等請求時,一般須要向服務器傳遞數據。這些數據就儲存在請求正文中。

(4)服務器處理HTTP請求 服務器處理http請求,並返回響應報文。響應報文包括三個部分: 狀態碼:略 響應頭:包含了響應的相關信息,如日期等 響應正文:服務器返回給瀏覽器的文本信息,一般的html、js、css、圖片等就包含在這一部分裏面。

(4)瀏覽器接受相應

而後根據狀況選擇關閉TCP鏈接或者保留重用; 若是資源可緩存,進行緩存; 對響應進行解碼(例如gzip壓縮); 根據資源類型決定如何處理(假設資源爲HTML文檔);

(6)瀏覽器頁面渲染 解析HTML文檔,構件DOM樹,下載資源,構造CSSOM樹,執行js腳本,這些操做沒有嚴格的前後順序,如下分別解釋 構建DOM樹: 根據HTML規範將字符流解析爲標記 詞法分析將標記轉換爲對象並定義屬性和規則 根據HTML標記關係將對象組成DOM樹 解析過程當中遇到圖片、樣式表、js文件,啓動下載 構建CSSOM樹: 字符流轉換爲標記流 根據標記建立節點 節點建立CSSOM樹 根據DOM樹和CSSOM樹構建渲染樹: 從DOM樹的根節點遍歷全部可見節點,不可見節點包括:

- script,meta這樣自己不可見的標籤
- 被css隱藏的節點,如display: none
複製代碼

對每個可見節點,找到恰當的CSSOM規則並應用 發佈可視節點的內容和計算樣式

js解析以下:

瀏覽器建立Document對象並解析HTML,將解析到的元素和文本節點添加到文檔中,此時document.readystate爲loading HTML解析器遇到沒有async和defer的script時,將他們添加到文檔中,而後執行行內或外部腳本。這些腳本會同步執行,而且在腳本下載和執行時解析器會暫停。這樣就能夠用document.write()把文本插入到輸入流中。同步腳本常常簡單定義函數和註冊事件處理程序,他們能夠遍歷和操做script和他們以前的文檔內容 當解析器遇到設置了async屬性的script時,開始下載腳本並繼續解析文檔。腳本會在它下載完成後儘快執行,可是解析器不會停下來等它下載。異步腳本禁止使用document.write(),它們能夠訪問本身script和以前的文檔元素 當文檔完成解析,document.readState變成interactive 全部defer腳本會按照在文檔出現的順序執行,延遲腳本能訪問完整文檔樹,禁止使用document.write() 瀏覽器在Document對象上觸發DOMContentLoaded事件 此時文檔徹底解析完成,瀏覽器可能還在等待如圖片等內容加載,等這些內容完成載入而且全部異步腳本完成載入和執行,document.readState變爲complete,window觸發load事件 顯示頁面(HTML解析過程當中會逐步顯示頁面)

5九、H5與iOS/Android的通訊方式(原生內嵌H5頁面通訊模式淺析

引入JsBridge(安卓)或WebViewJavascriptBridge(iOS)庫的方案,首先安卓、iOS、web前端三方要在一塊兒定義好須要使用的接口的方法名及傳遞的參數,三方統一,定義好各個方法及傳遞的方式

60、redux中間件

redux中間件中間件提供第三方插件的模式,自定義攔截 action -> reducer 的過程。變爲 action -> middlewares -> reducer 。這種機制可讓咱們改變數據流,實現如異步 action ,action 過濾,日誌輸出,異常報告等功能。常見的中間件:

  • redux-logger:提供日誌輸出
  • redux-thunk:處理異步操做
  • redux-promise:處理異步操做,actionCreator的返回值是promise

61.redux有什麼缺點

  • 一個組件所須要的數據,必須由父組件傳過來,而不能像flux中直接從store取。
  • 當一個組件相關數據更新時,即便父組件不須要用到這個組件,父組件仍是會從新render,可能會有效率影響,或者須要寫複雜的shouldComponentUpdate進行判斷。

6二、react組件的劃分業務組件技術組件?

根據組件的職責一般把組件分爲UI組件和容器組件。UI 組件負責 UI 的呈現,容器組件負責管理數據和邏輯。二者經過React-Redux 提供connect方法聯繫起來。、

6三、爲何虛擬dom會提升性能?

虛擬dom至關於在js和真實dom中間加了一個緩存,利用dom diff算法避免了沒有必要的dom操做,從而提升性能。

具體實現步驟以下:用 JavaScript 對象結構表示 DOM 樹的結構;而後用這個樹構建一個真正的 DOM 樹,插到文檔當中當狀態變動的時候,從新構造一棵新的對象樹。而後用新的樹和舊的樹進行比較,記錄兩棵樹差別把2所記錄的差別應用到步驟1所構建的真正的DOM樹上,視圖就更新了。

6四、react diff算法?

把樹形結構按照層級分解,只比較同級元素。給列表結構的每一個單元添加惟一的key屬性,方便比較。React 只會匹配相同class的component (這裏面的class指的是組件的名字)合併操做,調用 component 的 setState 方法的時候, React 將其標記爲 dirty.到每個事件循環結束, React 檢查全部標記 dirty 的component從新繪製.選擇性子樹渲染。開發人員能夠重寫shouldComponentUpdate提升diff的性能。

6五、react性能優化方案

  • 重寫shouldComponentUpdate來避免沒必要要的dom操做。
  • 使用 production 版本的react.js。
  • 使用key來幫助React識別列表中全部子組件的最小變化。

6五、Vue的生命週期

相關文章
相關標籤/搜索