一、vue router跳转方式
1.this.$router.push()
跳转到不同得url,但这个方法会向history栈添加一个记录,点击后退会返回到上一个页面。
1.this.$router.push({path:'/home/sort/detail',query:{id:'abc'}})
获取参数{{this.$route.query.userId}}
2.this.$router.push({name:'detail',params:{'abc'}})
获取参数:{{this.$route.params.userId}}
query和params的区别
1.用法上
query要用path来引入,params要用name来引入:
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仅对当前对话有效,关闭当前页面或者浏览器后被清除
存储大小:cookie :4kb localStorage一般5mb
与服务器通信 cookie每次都会携带http请求头,如果使用cookie保存过多,性能不太好,localStorage仅存在客户端存储,不参与服务端通信
用途 cookie 一般由服务器生成,来标识用户身份,localstorage用于浏览器端缓存数据
四 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',
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 插入html
v-text插入文本
条件渲染:v-if v-show
v-if 是动态的向DOM树内添加或者删除DOM元素
从性能上来说:
v-shadow只编译一次,后面其实就是控制css,而v-if不停的销毁和创建,故v-show性能更好一点
六)Ajax请求原理解析
1.创建XMLHttpRequest对象
var xhr;
if(XMLHttpRequest){
xhr=new XMLHttpRequest();
}else{
xhr=new ActiveXObject("Microsofot.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请求的区别
后退按钮/刷新 GET:无害 POST:数据会被重新提交(浏览器应该告知用户数据会被重新提交)
书签:GET可收藏为书签 POST不可收藏为书签
缓存 GET能被缓存POST不能缓存
编码类型 GET application//x-www-form-unlencoded POST application/x-www-urlencoded或multipart/form-data。为二进制数据使用多重编码。
历史:GET参数保留在浏览器历史中。POST参数不会保存在浏览器历史中。
对数据长度的限制 GET是的。当发送数据时,GET方法向URL添加数据;URL的长度是受限制的(URL的长度是2048个字符)。POST无限制
对数据类型的限制 GET只允许ASCLL字符。POST比GET更安全,因为参数不会被保存在浏览器历史或web服务器日志中。
可见性:GET数据在URL中对所有人都是可见的。数据不会显示在URL中。
八)从输入url到页面加载完成发生了什么?--前端角度
1.浏览器的地址栏输入URL并按下回车
2.浏览器查找当前URL的DNS缓存记录。
3.DNS解析url对应的IP
根据IP建立TCP连接(三次握手)
HTTP发起请求。
服务器处理请求,浏览器接收HTTP响应。
渲染页面,构建DOM树
关闭TCP连接(四次挥手)
九)http和https的区别
Http:超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。设计Http最初的目的是为了提供一种发布和接收HTML页面的方法。它可以使浏览器更加高效。Http协议是以明文方式发送信息的,如果黑客截取了Web浏览器和服务器之间的传输报文,就可以直接获得其中的信息。
Https:是以安全为目标的Http通道,是Http的安全版。Https的安全基础是SSL。SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层:SSL记录协议,它建立在可靠的传输协议(如TCP之上),为高层协议提供数据封装、压缩、加密等基本功能的支持。SSL握手协议,它建立在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的区别
canvas:
通过js来绘制2D图形 逐像素渲染的,canvas中,一旦图形被绘制完成,他就不会继续得到浏览器的关注,如果他的位置变化,那么就需要重新来绘制图形,其中包括任何或者已经被图形覆盖的对象。
svg:
svg是xml描述的2D图形 svg 是基于xml的,也就是svg dom中的每个元素都是可用的,可以为某个元素附加js事件处理器。在svg中,每个被绘制的图像均视为对象,如果svg对象的属性变化,那么浏览器可以自行重现图形。
区别:
canvas
依赖分辨率
不支持事件处理器
弱的文本渲染能力
能够以.jpg或者.png格式保存结果图像
最适合图像密集型的游戏,其中的很多对象会被频繁的绘制
svg不依赖分辨率
支持事件处理器
最适合带有大型渲染区域的应用程序
十二)不知宽高的盒子如何居中
<div class="wrap"><div class="box"></div></div>
1)display:flex;justify-content:center;align-item:center}
2).wrap{position:relative;}
.box {position:absolute;left:50%;top:50%;transform:translate(-50%,-50%)}
3).wrap{position:relative;}
.box{position:absolute;left:0;right:0;top:0;bottom:0
margin:auto;
}
.wrap{display:table}
.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)
},
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,在执行destroyed方法后,对data的改变不会触发周期函数,说明vue实例已经解除了事件监听以及dom绑定,但是dom结构依然存在;
vue的生命周期的作用:
他的生命周期中有多个事件钩子,让我们控制整个vue实例的过程时更容易形成良好的逻辑。
生命周期钩子的一些使用方法;
beforeCreate:loading事件,在加载实例时触发。
created:初始化完成事件,异步请求。
mounted:挂载元素,获取dom节点
updated:对数据统一处理
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有哪几种导航守卫
全局守卫
router.beforeEach全局前置守卫,进入路由之前
router.beforeResolve全局解析守卫,在beforeRouterEnter调用之后调用
router.afterEach全局后置钩子,进入路由之后
import router from './router'
router.beforeEach((to,from,next)=>{
next();
}
router.beforeResolve((to,from,next)=>{
next()
}
router.afterEach((to,from)=>{
next()
}
router.afterEach((to,from,next)=>{
console.log("全局后置钩子")
}
2》路由独享守卫
如果不想全局配置守卫的话,可以为某些路由单独配置守卫
{
path:'/home',
name:'home',
component:Home,
beforeEnter(to,from,next){
if(window.localStroage.getItem("id")){
next();
}else{
next({name:"login"})
}
}
}
3》路由组件内守卫
beforeRouteEnter进入路由前,在路由独享守卫后调用不能获取组件实例this,组件实例还没被创建
beforeRouteUpdate(2.2)路由复用用同一个组件时,在当前路由改变,但是该组件被复用时调用可以访问组件实例this
beforeRouteLeave离开当前路由时,导航离开该组件的对应路由调用,可以访问组件实例this
beforeRouteEnter(to,from,next){
//do something
//在渲染该组件的对应路由被confirm前调用
},
beforeRouteUpDate(to,from,next){
//do something
//在当前路由改变,但是依然渲染该组件是调用
},
beforeRouteLeave(to,from,next){
//do something
//导航离开该组件的对应路由时被调用
}
十七)this
默认绑定:
默认绑定是函数针对的独立调用的时候,不带任何修饰的函数引用进行调用,非严格模式下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 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:'程序员成长指北']
bind函数 bind方法会创建一个新函数。当这个新函数被调用时,bind()的第一个参数将作为它运行时的this,之后一序列参数将会在传递的参数前传入作为它的参数。
bind函数 bind方法会创建一个新函数。当这个新函数被调用时,bind()的第一个参数将作为它运行时的this,之后一序列参数将会在传递的实参前作为传入它的参数。
var publicAccounts={
name:'测试1111',
author:'hoster',
subscribe:function(subscrber){
console.log(subscriber+this.name)
}
}
publicAccounts.subscibe('aa')
//"aa测试1111"
var subscribe1=publicAccounts.subscribe.bind({name:"测试bbb",author:'持有者'},'bb')
publicAccounts.subscribe('aa')
var subscribel=publicAccounts.subsribe.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)
在new Demo('妹妹')的时候,会改变this指向,将this指向指定到了studyDay对象。注意:如果创建新的对象,构造函数不传值的话,新对象中的属性不会有值,但是新的对象中会有这个属性。
function demo(name){
this.name=name;
}
var demoNew=new demo();
console.log(demoNew);
console.log(demoNew.name)
在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.prototype!==null
}
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);
var obj=new A(1,2);
this绑定优先级
上面介绍了this的四种绑定规则,但是一段代码有时候会同时应用多种规则,这时候this应该如何指向呢?其实它们也是有一个先后顺序的,具体规则如下:
new绑定>显式绑定>隐式绑定>默认绑定
箭头函数表达式的语法比函数表达式更短,并且不绑定自己的this,arguments,super或new.target。这些函数表达式最适合用于非方法函数,并且他们不能用作构造函数。
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”
操作运算符的一些常见的题
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
cosole.log(undefined==null)
//true
console.log(undefined===null)
//false
null==0
//false
['']==''
//true
[0]==0
//true
ps**值得一提的是,在全等运算中,NaN与任何值相比,结果都是false
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(){
return a;
}
return sum;
}
add(1)//1
add(1)(2);//3
add(1)(2)(3);//6
link和@important的区别
link 是html的标签,不仅可以加载css还可以定义Rss,rel连接属性;@important是css的语法规则,只能引入样式;
2》加载页面时,link是同时加载,@important是页面加载完后才加载
3》link没有兼容性的问题,而@important只在较高版本的浏览器才可以识别
4》link可以通过js插入操作dom,@important不可以
二十)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-color:0 15px 15px;
border-stype: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>
</html>
<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.每个实例函数都有一个指向原型对象的指针。
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中间件代理跨域
5.websocket协跨域
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){
})})}
2:js自带函数toLocalString()
var a=1234567894532;
var b=673439.4532;
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));
console.log(numFormat(b))