2019年前端面试题

一)vue router 跳转方式

1.this.$router.push()

跳转到不同的url,但这个方法会向history栈添加一个记录,点击后退会返回到上一个页面。

this.KaTeX parse error: Expected '}', got 'EOF' at end of input: … 获取参数 {{this.route.query.userId}}
this.KaTeX parse error: Expected '}', got 'EOF' at end of input: …}) 获取参数:{{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)跳转 点击查看子页面

  2. 根据路由名称(detail)跳转 点击查看子页面 :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);
};
}
a2; //10

var b = [];
for (let k = 0; k < 10; k++) {
b[k] = function () {
console.log(k);
};
}
b2; //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


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的线

复制代码

三角形及0.5px的线
复制代码 二十一)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属性进行跨域

  1. 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”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BAT前端面试题是指腾讯(Tencent)、阿里巴巴(Alibaba)和百度(Baidu)等中国互联网巨头公司在前端开发职位面试中常问到的题目。这些面试题的目的是评估应聘者的前端技术水平和解决问题的能力。 2019的BAT前端面试题可能包括以下几个方面的内容: 1. 基础知识和算法:应聘者可能会被要求解释JavaScript的闭包、原型链和作用域链等基本概念。同时,算法题可能会涉及到数组、字符串、递归等方面的问题,如反转字符串、找出数组中的重复元素等。 2. CSS和HTML:应聘者可能会被要求解释盒模型、CSS选择器的优先级、浮动和定位等常见的CSS概念。同时,可能需要用HTML和CSS实现一些特定的布局和效果。 3. 前端框架和库:在2019的面试中,可能会有一些关于React、Vue.js等前端框架和库的问题。应聘者可能需要解释虚拟DOM的概念、React组件的生命周期、Vue.js的响应式数据等。 4. 性能优化和前端工程化:面试中可能会涉及到如何优化前端性能以及前端工程化的问题。应聘者可能需要解释如何减少HTTP请求、压缩和合并资源、使用缓存等优化技巧,以及如何使用构建工具和自动化部署工具来提高开发效率。 5. 前端安全:面试中可能会问到如何防止XSS(跨站脚本攻击)和CSRF(跨站请求伪造)等前端安全问题。应聘者可能需要解释如何验证用户输入、使用CSP(内容安全策略)等安全技术。 综上所述,2019的BAT前端面试题会覆盖前端基础知识、算法、CSS和HTML、前端框架、性能优化、前端工程化和前端安全等多个方面。应聘者需要对这些知识有深入的了解,并且能够通过解答问题展示出自己的技术实力和解决问题的能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值