一)vue router 跳轉方式
1.this.$router.push()
跳轉到不同的url,但這個方法會向history棧添加一個記錄,點擊后退會返回到上一個頁面。
-
this.$ router.push({path: '/home/sort/detail',query:{id: 'abc'}})獲取參數 {{this.$ route.query.userId}}
-
this.$ router.push({name: 'detail',params:{id: 'abc'}})
獲取參數:{{this.$ route.params.userId}}
ps:
query和params 的區別:
1.用法上
query要用path來引入,params要用name來引入:eg
this.$router.push({
name:"detail",
params:{
name:'nameValue',
code:10011
}
});
2.展示上的
query更加類似於我們ajax中get傳參,params則類似於post,說的再簡單一點,前者在瀏覽器地址欄中顯示參數,后者則不顯示
2.this.$router.replace()
同樣是跳轉到指定的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保存過多,性能不太好 | 僅在客戶端存儲,不參與服務端通信 | |
用途 | 一般由服務器生成,來標識用戶身份 | 勇於瀏覽器端緩存數據 |
三)數組相關
參考文章數組相關:https://www.cnblogs.com/jiajiamiao/p/11641574.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樹。 8、關閉TCP連接(四次揮手)
參考博客:https://www.cnblogs.com/daijinxue/p/6640153.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的區別
1、HTTP是超文本傳輸協議,信息是明文傳輸,HTTPS是具有安全性的SSL加密傳輸協議。
2、HTTPS協議需要ca申請證書,一般免費證書少,因而需要一定費用。
3、HTTP和HTTPS使用的是完全不同的連接方式,用的端口也不一樣。前者是80,后者是443。
4、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 原型下的方法,所有的函數都能使用。
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"