一)vue router 跳轉方式javascript
1.this.$router.push() css
跳轉到不一樣的url,但這個方法會向history棧添加一個記錄,點擊後退會返回到上一個頁面。html
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變化時會觸發beforeUpdate和updated方法;
銷燬先後:beforeDestory和destoryed,在執行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
。
在函數中以函數做爲參數傳遞,例如 setTimeOut
和 setInterval
等,這些函數中傳遞的函數中的 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 原型下的方法,全部的函數都能使用。
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); //測試
這兩個方法在調用的時候,若是咱們傳入數字或者字符串,這兩個方法會把傳入的參數轉成對象類型。
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 ) 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調用函數的時候,會執行怎樣的流程:
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
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"