2019 前端面試題總結 及 答案

一)vue router 跳轉方式javascript

1.this.$router.push() css

跳轉到不一樣的url,但這個方法會向history棧添加一個記錄,點擊後退會返回到上一個頁面。html

  1.  this.$ router.push({path: '/home/sort/detail',query:{id: 'abc'}})     
     獲取參數 {{this.$ route.query.userId}}
  2.  this.$ router.push({name: 'detail',params:{id: 'abc'}})
    獲取參數:{{this.$ route.params.userId}}

ps:前端

query和params 的區別:vue

1.用法上java

query要用path來引入,params要用name來引入:egnode

this.$router.push({
   name:"detail",
   params:{
    name:'nameValue',
    code:10011
 }
});

2.展現上的webpack

  query更加相似於咱們ajax中get傳參,params則相似於post,說的再簡單一點,前者在瀏覽器地址欄中顯示參數,後者則不顯示nginx

2.this.$router.replace()git

一樣是跳轉到指定的url,可是這個方法不會向history裏面添加新的記錄,點擊返回,會跳轉到上上一個頁面。上一個記錄是不存在的。

3.this.$router.go(n)

相對於當前頁面向前或向後跳轉多少個頁面,相似 window.history.go(n)。n可爲正數可爲負數。正數返回上一個頁面

4.聲明式

1) 根據路由路徑(/home/sort/detail)跳轉 <router-link :to="{path: '/home/sort/detail', query:{id: 'abc'}}">點擊查看子頁面</router-link>

2) 根據路由名稱(detail)跳轉 <router-link :to="{name: 'detail', params:{id: 'abc'}}">點擊查看子頁面</router-link>    :to="" 能夠實現綁定動態的 路由 和 參數

 

二)Cookie和localStorage、sessionStorage的區別

名稱 cookie localStorage sessionStorage
相同點 均可以用來在瀏覽器端存儲數據,都是字符串的鍵值對
數據聲明週期 通常由服務器生成,可設置失效時間;若在瀏覽器生成,默認關閉瀏覽器以後失效 除非被清除,不然永久有效 僅對當前對話有效,關閉當前頁面或者瀏覽器後被清除
存儲大小 4kb 通常5mb
與服務端通訊 每次都會攜帶在http請求頭中,若是使用cookie保存過多,性能不太好 僅在客戶端存儲,不參與服務端通訊
用途 通常由服務器生成,來標識用戶身份 敢於瀏覽器端緩存數據

三)數組相關

參考文章數組相關http://www.javashuo.com/article/p-uxnkehzk-em.html

四)let var const 的區別

1:var  全局變量,存在變量提高,在聲明前取值爲undefined 會掛載在window上 如:
var a = 1;
console.log(a,window.a) // 1 1
2:let 聲明局部變量,只在塊級做用域內有效
console.log(b); // 報錯:b在初始化以前不能接收
let b = 10;
var a = [];

for (var i = 0; i < 10; i++) {  
    a[i] = function () { 
       console.log(i);  
    };
}
a[2]();    //10

var b = []; 
for (let k = 0; k < 10; k++) {  
    b[k] = function () { 
        console.log(k);  
    };
}
b[2]();     //2
3:const 聲名的是常量,一經聲明不可改變。可是引用類型的對象和數組能夠改變:
const person = {
     name : 'jony',
     sex : '男'
 }
 person.name = '九九'
 
 console.log(person.name)   //九九

ps//由於對象是引用類型的,person中保存的僅是對象的指針,這就意味着,const僅保證指針不發生改變,修改對象的屬性不會改變對象的指針,因此是被容許的。也就是說const定義的引用類型只要指針不發生改變,其餘的不論如何改變都是容許的。

五)vue的經常使用指令有哪些?

 

v-for 循環 ps:若是list是對象,還有value,key屬性,如v-for="(value,key,index) in list";
v-for 中key必須爲惟一的 做用是:主要是爲了高效的更新虛擬DOM v
-bind 綁定屬性 簡寫: v-bind:屬性名="常量 || 變量名" v-on 綁定時間 簡寫@ v-on:click = "方法名 || 直接改變 vue 內部變量" 雙向綁定:v-model 所謂的雙向綁定,就是你在視圖層裏面改變了值,vue裏面對應的值也會改變。只能給具有value屬性的元素進行雙向數據綁定。 v-html 插入HMTL v-text 插入文本 條件渲染: v-if v-show v-show 本質就是標籤display設置爲none,控制隱藏 v-if 是動態的向DOM樹內添加或者刪除DOM元素 從性能上來講: v-show只編譯一次,後面其實就是控制css,而v-if不停的銷燬和建立,故v-show性能更好一點

 

六)Ajax請求原理解析

1:建立XMLHttpRequest對象

var xhr;
if(XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}

2:準備請求

xhr.open(method,url,async);
method:get   post
url:請求地址
async:true異步 false同步

3:發送請求

xhr.send();
get :xhr.open("GET",url,true);
xhr.send(null);

post:
xhr.open("POST",url,true);
xhr.setRequestHeder("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");   //規定表頭
xhr.send("name="+userName+"&age="+userAge);//參數

4:處理響應

xhr.onreadystatechange = function(){
  if(xhr.readyState == 4 && xhr.status == 200){
    console.log(「響應成功成功」,xhr.responseText);
  }
}

七)get和post請求的區別

 

八)從輸入url到頁面加載完成發生了什麼?——前端角度

1、瀏覽器的地址欄輸入URL並按下回車。
2、瀏覽器查找當前URL的DNS緩存記錄。
3、DNS解析URL對應的IP。
4、根據IP創建TCP鏈接(三次握手)。
5、HTTP發起請求。
6、服務器處理請求,瀏覽器接收HTTP響應。
7、渲染頁面,構建DOM樹。
八、關閉TCP鏈接(四次揮手)

參考博客:http://www.javashuo.com/article/p-sqewywzj-b.html

 九)http和https的區別

Http:超文本傳輸協議(Http,HyperText Transfer Protocol)是互聯網上應用最爲普遍的一種網絡協議。設計Http最初的目的是爲了提供一種發佈和接收HTML頁面的方法。它可使瀏覽器更加高效。Http協議是以明文方式發送信息的,若是黑客截取了Web瀏覽器和服務器之間的傳輸報文,就能夠直接得到其中的信息。

Https:是以安全爲目標的Http通道,是Http的安全版。Https的安全基礎是SSL。SSL協議位於TCP/IP協議與各類應用層協議之間,爲數據通信提供安全支持。SSL協議可分爲兩層:SSL記錄協議(SSL Record Protocol),它創建在可靠的傳輸協議(如TCP)之上,爲高層協議提供數據封裝、壓縮、加密等基本功能的支持。SSL握手協議(SSL Handshake Protocol),它創建在SSL記錄協議之上,用於在實際的數據傳輸開始前,通信雙方進行身份認證、協商加密算法、交換加密密鑰等。

HTTP與HTTPS的區別

一、HTTP是超文本傳輸協議,信息是明文傳輸,HTTPS是具備安全性的SSL加密傳輸協議。

二、HTTPS協議須要ca申請證書,通常免費證書少,於是須要必定費用。

三、HTTP和HTTPS使用的是徹底不一樣的鏈接方式,用的端口也不同。前者是80,後者是443。

四、HTTP鏈接是無狀態的,HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,安全性高於HTTP協議。

https的優勢

儘管HTTPS並不是絕對安全,掌握根證書的機構、掌握加密算法的組織一樣能夠進行中間人形式的攻擊,但HTTPS還是現行架構下最安全的解決方案,主要有如下幾個好處:

1)使用HTTPS協議可認證用戶和服務器,確保數據發送到正確的客戶機和服務器;

2)HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,要比http協議安全,可防止數據在傳輸過程當中不被竊取、改變,確保數據的完整性。

3)HTTPS是現行架構下最安全的解決方案,雖然不是絕對安全,但它大幅增長了中間人攻擊的成本。

4)谷歌曾在2014年8月份調整搜索引擎算法,並稱「比起同等HTTP網站,採用HTTPS加密的網站在搜索結果中的排名將會更高」。

Https的缺點

1)Https協議握手階段比較費時,會使頁面的加載時間延長近。

2)Https鏈接緩存不如Http高效,會增長數據開銷,甚至已有的安全措施也會所以而受到影響;

3)SSL證書一般須要綁定IP,不能在同一IP上綁定多個域名,IPv4資源不可能支撐這個消耗。

4)Https協議的加密範圍也比較有限。最關鍵的,SSL證書的信用鏈體系並不安全,特別是在某些國家能夠控制CA根證書的狀況下,中間人攻擊同樣可行。

十)json和xml數據的區別

1,數據體積方面:xml是重量級的,json是輕量級的,傳遞的速度更快些。。

2,數據傳輸方面:xml在傳輸過程當中比較佔帶寬,json佔帶寬少,易於壓縮。

3,數據交互方面:json與javascript的交互更加方便,更容易解析處理,更好的進行數據交互

4,數據描述方面:json對數據的描述性比xml較差

5,xml和json都用在項目交互下,xml多用於作配置文件,json用於數據交互。

十一)svg和canvas的區別

cancas:

   經過js來繪製2D圖形  逐像素渲染的    canvas中,一旦圖形被繪製完成,他就不會繼續獲得瀏覽器的關注,若是他的位置變化,那麼就須要從新來繪製圖形,其中包括任何或者已經被圖形覆蓋的對象。

svg:

      svg是xml描述的2D圖形    svg是基於xml的,也就是svg dom中的每一個元素都是可用的,能夠爲某個元素附加js事件處理器。     在svg中,每一個被繪製的圖像均視爲對象,若是svg對象的屬性變化,那麼瀏覽器能夠自行重現圖形。

區別:

canvas       

  a:依賴分辨率

  b:不支持事件處理器

  c:  弱的文本渲染能力

  d:可以以.jpg或者.png格式保存結果圖像

  e:最適合圖像密集型的遊戲,其中的不少對象會被頻繁的繪製

svg

  a:不依賴分辨率

  b: 支持事件處理器

  c: 最適合帶有大型渲染區域的應用程序(谷歌地圖)

  d: 複雜度高會減慢渲染速度

  e:不適合遊戲應用

十二)不知寬高的盒子如何居中

 1 <div class="warp"><div class="box"></div></div>
 2 
 3 1)display:flex
 4 .warp{display:flex;   justify-content:center;  align-item:center;}
 5 
 6 2).warp{position:relative;}
 7 .box{position:absolute; left:50%; right:50%;  transform:translate(-50%,-50%)}
 8 
 9 3).warp{position:relative;}
10 .box{position:absolute; left:0; right:0; top:0; bottom:0; 
11  margin:auto;}
12 
13 4).warp{display:table;}
14 .box{display:table-cell; text-align:center; vertical-align:middle; }

十三)computed和watch的區別

computed

計算結果並返回,只有當被計算的屬性發生改變時纔會觸發(即:計算屬性的結果會被緩存,除非依賴的響應屬性變化纔會從新及孫)

watch

 監聽某一個值,當被監聽的值發生變化時,執行相關操做。(與computed的區別是,watch更加適用於監聽某一個值得變化,並作對應操做,好比請求後太接口等。而computed適用於計算已有的值並返回結果。)

監聽簡單數據類型:

 

data(){
      return{
        'first':2
      }
    },
    watch:{
      first(){
        console.log(this.first)
      }
    },

 

監聽複雜數據類型

 

data(){
      return{ 'first':{ second:0 } } }, watch:{ secondChange:{ handler(oldVal,newVal){ console.log(oldVal) console.log(newVal) }, deep:true } },

 

十四)vue的生命週期

Vue 實例有一個完整的生命週期,也就是從開始建立、初始化數據、編譯模板、掛載Dom→渲染、更新→渲染、卸載等一系列過程,咱們稱這是 Vue 的生命週期。通俗說就是 Vue 實例從建立到銷燬的過程,就是生命週期。

beforeCreate: vue元素的掛載元素el和數據都爲undefined,還未初始化;

 

 

created:vue實例的數據對象data有了,el尚未;

beforeMount:vue實例的$el和data都初始化了,可是還掛載在以前的虛擬dom節點上,data.message還未替換;

mounted:vue實例掛載完成,data.message成功渲染。

更新先後:data變化時會觸發beforeUpdateupdated方法;

銷燬先後:beforeDestorydestoryed,在執行destoryed方法後,對data的改變不會觸發周期函數,說明vue實例已經解除了事件監聽以及dom綁定,可是dom結構依然存在;

vue生命週期的做用:

他的生命週期中有多個事件鉤子,讓咱們控制整個vue實例的過程時更容易造成良好的邏輯。

生命週期鉤子的一些使用方法:

beforeCreate:loading事件,在加載實例時觸發。

created:初始化完成事件,異步請求。

mounted:掛載元素,獲取dom節點

uptaded:對數據統一處理

beforeDestory:確認事件中止。

nextTick:更新數據後當即操做dom。

十五)vuex如何實現按需加載配合webpack配置

webpack中提供了require.ensure()來實現按需加載。之前引入路由是經過import 這樣的方式引入,改成const定義的方式進行引入。

        不進行頁面按需加載引入方式:import  home   from '../../common/home.vue'

        進行頁面按需加載的引入方式:const  home = r => require.ensure( [], () => r (require('../../common/home.vue')))

十六)vue-router有哪幾種導航守衛

1》全局守衛

a:router.beforeEach 全局前置守衛,進入路由以前

b:router.beforResolve 全局解析守衛,在beforeRouterEnter調用以後調用

c:router.afterEach 全局後置鉤子,進入路由以後

 

//main.js  入口文件
import router from ’./router‘
router.beforeEach(to,from,next)=>{
    next();
}

router.beforeResolve(to,from,next)=>{
    next();
}

router.afterEach(to,from)=>{
    console.log('全局後置鉤子')
}

 

2》路由獨享守衛

若是不想全局配置守衛的話,能夠爲某些路由單獨配置守衛

 

{
    path: '/home',
    name: 'home',
    component: Home,
    beforeEnter(to, from, next) {
        if (window.localStorage.getItem("id")) {
            next()
        } else {
            next({ name: "login" })
        }
    }
}

 

 

 

3》路由組件內的守衛

 

beforeRouteEnter 進入路由前, 在路由獨享守衛後調用 不能 獲取組件實例 this,組件實例還沒被建立

 

beforeRouteUpdate (2.2) 路由複用同一個組件時, 在當前路由改變,可是該組件被複用時調用 能夠訪問組件實例 this

 

beforeRouteLeave 離開當前路由時, 導航離開該組件的對應路由時調用,能夠訪問組件實例 this

 

 

beforeRouteEnter(to, from, next) {
    // do someting
    // 在渲染該組件的對應路由被 confirm 前調用
},
beforeRouteUpdate(to, from, next) {
    // do someting
    // 在當前路由改變,可是依然渲染該組件是調用
},
beforeRouteLeave(to, from ,next) {
    // do someting
    // 導航離開該組件的對應路由時被調用
}

 十七)this--------參考https://github.com/koala-coding/goodBlog/blob/master/docs/javascript/this.md

默認綁定:

默認綁定是函數針對的獨立調用的時候,不帶任何修飾的函數引用進行調用,非嚴格模式下 this 指向全局對象(瀏覽器下指向 Window,Node.js 環境是 Global ),嚴格模式下,this 綁定到 undefined ,嚴格模式不容許this指向全局對象。

var  a = 'hello'

var obj =
 {
    a:'koala',
    foo: function(){
        console.log(this.a)    
    }
}

var  bar = obj.foo
bar()              
// 瀏覽器中輸出: "hello"

這段代碼, bar()就是默認綁定,函數調用的時候,前面沒有任何修飾調用,也能夠用以前的 call函數調用形式理解,因此輸出結果是 hello

默認綁定的另外一種狀況

在函數中以函數做爲參數傳遞,例如 setTimeOutsetInterval等,這些函數中傳遞的函數中的 this指向,在非嚴格模式指向的是全局對象。

var name='koala';
  var person2 ={
        name:'程序員成長指北',
      sayHi:sayHi
      }
  function sayHi() {
      console.log('Hello,',this.name);
    }
  setTimeout(function() {
      person2.sayHi();
  },200);
  // 輸出結果 Hello,koala

隱式綁定

判斷 this 隱式綁定的基本標準:函數調用的時候是否在上下文中調用,或者說是否某個對象調用函數

var name='koala';
  var person2 ={
        name:'程序員成長指北',
        sayHi:function{
       
console.log('Hello,',this.name);
}
}
  person2.sayHi(); // 瀏覽器中輸出: "程序員成長指北"
sayHi方法是做爲對象的屬性調用的,那麼此時 foo 方法執行時,this 指向person2對象。

隱式綁定的另外一種狀況

當有多層對象嵌套調用某個函數的時候,如 對象.對象.函數,this 指向的是最後一層對象。

var person2 ={
        name:'程序員成長指北',
      sayHi:sayHi
      }
  function sayHi() {
      console.log('Hello,',this.name);
    }
    var
  var person1 ={
    name:'koala',
    friend:person2
    }
  person1.friend.sayHi();  
// 輸出結果爲 Hello, 程序員成長指北

顯式綁定

顯式綁定,經過函數call apply bind 能夠修改函數this的指向。call 與 apply 方法都是掛載在 Function 原型下的方法,全部的函數都能使用。

call 和 apply 的區別

1,call和apply的第一個參數會綁定到函數體的this上,若是 不傳參數,例如 fun.call(),非嚴格模式,this默認仍是綁定到全局對象

2.call函數接收的是一個參數列表,apply函數接收的是一個參數數組。

var person ={
  "name":"koala"
};
function changeJob(company,work){
    this.company = company;
    this.work    = work;
};
changeJob.call(person,'百度','程序員');
console.log(person.work);
// '程序員'
changeJob.apply(person,['百度', '測試']);
console.log(person.work);
//測試

call和apply的注意點

這兩個方法在調用的時候,若是咱們傳入數字或者字符串,這兩個方法會把傳入的參數轉成對象類型。

var number = 1 , string = '程序員成長指北';
function getThisType(){
    var number = 3;
    console.log('this指向內容',this);
    console.log(typeof(this))
}
getThisType.call(number)
getThisType.apply(string)
 
// 輸出結果
// this指向內容 [Number: 1]
// object
// this指向內容 [String: '程序員成長指北']
// objec

bind函數      bind 方法 會建立一個新函數。當這個新函數被調用時,bind() 的第一個參數將做爲它運行時的 this,以後的一序列參數將會在傳遞的實參前傳入做爲它的參數。(定義內容來自於 MDN )

bind函數      bind 方法 會建立一個新函數。當這個新函數被調用時,bind() 的第一個參數將做爲它運行時的 this,以後的一序列參數將會在傳遞的實參前傳入做爲它的參數。(定義內容來自於 MDN )
var publicAccounts = {
  name:'測試11111',
  author:'hoster',
  subscribe:function(subscriber){
    console.log(subscriber+this.name)
  }

}
publicAccounts.subscribe('aa') 
//"aa 測試11111"

var subscribe1 = publicAccounts.subscribe.bind({name:'測試bbb',author:'持有者'},'bb')
subscribe1()//bb測試bbb

new 綁定

使用new調用函數的時候,會執行怎樣的流程:

1.建立一個空對象

2.將空對象的 proto 指向原對象的 prototype

3.執行構造函數中的代碼

4.返回這個新對象

function demo(name){
  this.name = name
}
var demoNew = new demo('妹妹');
console.log(demoNew);
console.log(demoNew.name)
//demo {name: "妹妹"}
//妹妹

new Demo('妹妹')的時候,會改變this指向,將 this指向指定到了studyDay對象。注意:若是建立新的對象,構造函數不傳值的話,新對象中的屬性不會有值,可是新的對象中會有這個屬性。

function demo(name){
  this.name = name
}
var demoNew = new demo();
console.log(demoNew);
console.log(demoNew.name)
// demo {name: undefined}
// undefined

手動實現一個new建立對象代碼(多種實現方式哦)

function New(func) {
    var res = {};
    if (func.prototype !== null) {
        res.__proto__ = func.prototype;
    }
    var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
    if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
        return ret;
    }
    return res;
}
var obj = New(A, 1, 2);
// equals to
var obj = new A(1, 2);

this綁定優先級

上面介紹了 this 的四種綁定規則,可是一段代碼有時候會同時應用多種規則,這時候 this 應該如何指向呢?其實它們也是有一個前後順序的,具體規則以下:

new綁定 > 顯式綁定 > 隱式綁定 > 默認綁定

箭頭函數表達式的語法比函數表達式更短,而且不綁定本身的this,arguments,super或 new.target。這些函數表達式最適合用於非方法函數(non-method functions),而且它們不能用做構造函數。

常規函數能夠直接拿到 arguments 屬性,可是在箭頭函數中若是使用 arguments 屬性,拿到的是箭頭函數外層函數的 arguments 屬性

function constant() {
    return () => arguments[0]
}

let result = constant(1);
console.log(result()); // 1

箭頭函數中沒有本身的 this,箭頭函數中的 this 不能用 call()、apply()、bind() 這些方法改變 this 的指向,箭頭函數中的 this 直接指向的是調用函數的 上一層運行時

let a = 'kaola'

let obj = {
    a: '程序員成長指北',
    foo: () => {
        console.log(this.a)
    }
}

obj.foo()             // 輸出結果: "koala"
(function(){
    console.log('測試1111')
})()

(function(){
  console.log('ceshi2222')
}())

(()=>{
  console.log('測試33333')
})()

 十八)操做運算符的一些常見的題

console.log( 0=={})
//1 false

console.log(0 == false)
//1 true

console.log(NaN == NaN)
// false

console.log(null === null)
// true

console.log(undefined === undefined)
// true

var a
console.log(a == Object)
// false

console.log(0 === false)
// false

console.log(0 == false)
// true

console.log(1 == true)
//true

console.log(1 === true)
// false

console.log("" == false)
// true

console.log("" === false)
// false

console.log(undefined == null )
// true

console.log(undefined === null )
//false

null == 0
//false

['']==''
//true

[0]==0
//true
ps**值得一提的是,在全等運算中, NaN 與其餘任何值相比,結果都是 false

 十八)經典面試題

//JS實現一個無限累加的add函數
add(1) //1
add(1)(2) //3
add(1)(2)(3) //6

 

function add(a) {
    function sum(b) { // 使用閉包
        a = a + b; // 累加
        return sum;
     }
     sum.toString = function() { // 重寫toString()方法
        return a;
    }
     return sum; // 返回一個函數
}

add(1); // 1
add(1)(2);  // 3
add(1)(2)(3);// 6

 十九)link和@inmport的區別

1》link是html的標籤,不只能夠加載css還能夠定義Rss , rel鏈接屬性;@import是css的語法規則,只能引入樣式;
2》加載頁面時,link是同時加載的,@impor是頁面加載完後才加載
3》link沒有兼容性的問題,而@import只在較高版本的瀏覽器才能夠識別
4》link能夠經過js插入操做dom,@import 不能夠!

二十)css寫一個三角形及0.5px的線

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>三角形及0.5px的線</title>
    <style>
    .box{
        width:0;
        height:0;
        border-color: transparent transparent red;
        border-width: 0 15px 15px;
        border-style: solid ; 
    }
    .line {
        position: relative;
    }
    .line:after {
        content: "";
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 1px;
        background-color: #000000;
        -webkit-transform: scaleY(.5);
        transform: scaleY(.5);
    }
    </style>

</head>

<body>
    <div class="box"></div>
    <div class="line"></div>
</body>
</html>

 二十一)vuex:Vue.js應用程序的狀態管理模式+庫。

1.state

保存vuex中的數據源,經過this.$store.state獲取

 

2.getters

用於監聽state中的值的變化,返回計算後的結果。getter的返回值會根據它的依賴被緩存起來

 

3.mutations

是修改store中的值得惟一方式

 

4.action 

官方建議提交一個actions,在actions中提交mutations再去修改狀態值。 this.$store.dispatch('add')

//this.$store.commit('add')

5.modules 模塊化

二十二)如何理解js中的原型鏈

1;每一個構造函數都有一個原型對象

2;每一個原型對象都有一個指向構造函數的指針

3;每一個實例函數都有一個指向原型對象的指針。

4;查找方式是一層一層查找,直至頂層。Object.prototype

二十三)怎麼理解js中的內存泄露

定義:程序不須要的內存,因爲某些緣由其不會返回到操做系統或者可用內存池中。   內存泄露會致使(運行緩慢 ,高延遲,崩潰)的問題

常見的致使內存泄露的緣由有:

1;意外的全局變量

2;被遺忘的計時器或回調函數

3;脫離文檔的DOM的引用

4;閉包

 二十四)跨域問題

因爲瀏覽器的同源策略會致使跨域,同源策略又分爲

一:DOM同源策略:禁止對不一樣源頁面的DOM進行操做,主要是不一樣域名的ifram是限制互相訪問的

二:xmlHttpRequest同源策略:禁止使用XHR對象向不一樣源的服務器地址發起http請求,只要域名  協議  端口有一個不一樣都被當作不一樣的域之間的請求,即跨域請求

解決方式:

1.CORS跨域資源共享   後端須要設置Access--Control-Allow-Credentials:true

2.jsonp實現跨域:動態建立script,利用src屬性進行跨域

3. nginx代理跨域

4.nodejs中間件代理跨域

5WebSokect協跨域

6.window.name+ifram跨域

二十五)JS 實現千位分隔符

1:正則表達式和replace函數

function numFormat(num){
  var res=num.toString().replace(/\d+/, function(n){ // 先提取整數部分
       return n.replace(/(\d)(?=(\d{3})+$)/g,function($1){
          return $1+",";
        });
  })
  return res;
}

var a=1234567890123;
var b=123456.123456;
console.log(numFormat(a)); // "1,234,567,890,123"
console.log(numFormat(b)); // "123,456.123456"

 

2:js自帶函數toLocaleString()   //返回這個數字在特定語言環境下的表示字符串

var a=1234567894532;
var b=673439.4542;

console.log(a.toLocaleString());  // "1,234,567,894,532"
console.log(b.toLocaleString());  // "673,439.454"  (小數部分四捨五入了)

3:先轉字符串--》轉數組---》反轉---》三位加逗號----》反轉----》轉字符串-----》實現

function numFormat(num){
    num=num.toString().split(".");  // 分隔小數點
    var arr=num[0].split("").reverse();  // 轉換成字符數組而且倒序排列
    var res=[];
    for(var i=0,len=arr.length;i<len;i++){
      if(i%3===0&&i!==0){
         res.push(",");   // 添加分隔符
      }
      res.push(arr[i]);
    }
    res.reverse(); // 再次倒序成爲正確的順序
    if(num[1]){  // 若是有小數的話添加小數部分
      res=res.join("").concat("."+num[1]);
    }else{
      res=res.join("");
    }
    return res;
}

var a=1234567894532;
var b=673439.4542;
console.log(numFormat(a)); // "1,234,567,894,532"
console.log(numFormat(b)); // "673,439.4542"
相關文章
相關標籤/搜索