2020年的开头并不是很好啊,想要跳槽是难上加难。整理一波面试题就当是巩固自己的只是积累了。
js
1.前端如何解决精度问题
前端的精度问题经典案例就是0.1+0.2 = 0.30000000000000004
出现的原因:在计算机角度,计算机算的是二进制,而不是十进制。二进制后变成了无线不循环的数,而计算机可支持浮点数的小数部分可支持到52位,所有两者相加,在转换成十进制,得到的数就不准确了,加减乘除运算原理一样。
如何解决:
- 首先再要求不是很精确的情况下可以使用
toFixed()
指定要保留的小数位数,或者Math.round(x)
来进行四舍五入。 - 将浮点数转换为整数后在转换成浮点数,例如
(0.1*10+0.2*10)/10
- 其他可自己查阅
2.闭包
-
什么是闭包?
闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。 -
闭包带来的影响
闭包有两个最大的用处,一个是可以在全局作用域中读取内部函数的的变量,另一个就是可以让闭包中引用的变量始终保存在内存中。这句话很重要了,这样垃圾回收机制就不会释放掉这些内存,这样的后果就是造成内存泄露,所以在使用完闭包后要及时把变量清掉
题外话:这个时候也许会问你还有那些操作会造成内存泄露?
- 计时器或回调函数
- 以外的全局变量
- dom清空或删除时,事件未清除导致的内存泄漏
再插一个题外话:能说说什么垃圾回收机制吗?
可以查阅这篇文章点击查看
3.jsonp的原理
jsonp是为了解决前端跨域问题的一种解决方案,是一种非正式的传输协议。
这里先了解一下什么的跨域:跨域是指一个域下的文档或脚本要去访问另一个域下的内容。
在了解一下同源策略:同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
在js中img
标签和script
标签是不受同源策略影响的,所以jsonp就是利用
<script>
var script = document.createElement('script');
script.type = 'text/javascript';
// 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';
document.head.appendChild(script);
// 回调执行函数
function handleCallback(res) {
alert(JSON.stringify(res));
}
</script>
4. es6定义变量的方法
es5定义变量的方法有两种一个是var
、一个是function
es6定义变量的方法有六种,除了var
和function
之外,还有let、const 、import、class
var
命令
var a // undefined
var b = 1
- var定义的变量可以修改,如果不初始化会输出undefined,不会报错 var声明的变量在window上,用let或者const去声明变量,这个变量不会被放到window上
- 很多语言中都有块级作用域,但JS没有,它使用var声明变量,以function来划分作用域,大括号“{}”却限定不了var的作用域,因此用var声明的变量具有变量提升的效果
- var 声明的变量作用域是全局的或者是函数级的
function
命令
- 声明了一个名为 add的新变量,并为其分配了一个函数定义 {}之间的内容被分配给了 add
- 函数内部的代码不会被执行,只是存储在变量中以备将来使用
const
命令
- const定义的变量不可以修改,而且必须初始化
- 该变量是个全局变量,或者是模块内的全局变量
- 如果一个变量只有在声明时才被赋值一次,永远不会在其它的代码行里被重新赋值,那么应该使用const,但是该变量的初始值有可能在未来会被调整(常变量)
- 创建一个只读常量,在不同浏览器上表现为不可修改;建议申明后不修改;拥有块级作用域
- const 代表一个值的常量索引 ,也就是说,变量名字在内存中的指针不能够改变,但是指向这个变量的值可能 改变
- const定义的变量不可修改,一般在require一个模块的时候用或者定义一些全局常量
- 可以在全局作用域或者函数内声明常量,但是必须初始化常量
- 常量不能和它所在作用域内其它变量或者函数拥有相同名称
4.let
命令
- 需要”javascript 严格模式”:‘use strict’; 不存在变量提升 不允许重复声明
- let声明的变量作用域是在块级域中,函数内部使用let定义后,对函数外部无影响(块级作用域)
- 可以在声明变量时为变量赋值,默认值为undefined,也可以稍后在脚本中给变量赋值,在生命前无法使用(暂时死区)
5.import
命令
6. class
命令
5.promise all race 的作用分别是什么
- Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。
- Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
6.window.onload 和document.ready的区别
ready事件在DOM结构绘制完成之后就会执行,这样能确保就算有大量的媒体文件没加载出来,JS代码一样可以执行。
load事件必须等到网页中所有内容全部加载完毕之后才被执行。如果一个网页中有大量的图片的话,则就会出现这种情况:网页文档已经呈现出来,但由于网页数据还没有完全加载完毕,导致load事件不能够即时被触发。
7.如何准确的判断一个数据类型
先想一下前端的基本数据类型有哪些?
- 基本数据类型:
String、Boolean、Number、null、undefined
- 复杂数据类型:
Object
例如我们有以下一些数据
var bool = true
var num = 1
var str = 'abc'
var und = undefined
var nul = null
var arr = [1,2,3]
var obj = {name:'haoxl',age:18}
var fun = function(){console.log('I am a function')}
判断数据类型的方法有:
typeof
console.log(typeof bool); //boolean
console.log(typeof num);//number
console.log(typeof str);//string
console.log(typeof und);//undefined
console.log(typeof nul);//object
console.log(typeof arr);//object
console.log(typeof obj);//object
console.log(typeof fun);//function
其中Array、Object、null
打印的都是object
- 使用
instanceof
instanceof不能区别undefined和null,而且对于基本类型如果不是用new声明的则也测试不出来,对于是使用new声明的类型,它还可以检测出多层继承关系。
- 使用
constructor
constructor不能判断undefined和null,并且使用它是不安全的,因为contructor的指向是可以改变的
- 使用
Object.prototype.toString.call
原理(摘自高级程序设计3):在任何值上调用 Object 原生的 toString() 方法,都会返回一个 [object NativeConstructorName] 格式的字符串。每个类在内部都有一个 [[Class]] 属性,这个属性中就指定了上述字符串中的构造函数名。 但是它不能检测非原生构造函数的构造函数名。
css
1.清除浮动
浮动可以理解为让某个元素脱离了正常文档流,与其他元素不在同一个层次上
如何清楚浮动呢?
- 可以设置属性
clear : none | left | right | both
值 | |
---|---|
none | 默认值。允许两边都可以有浮动对象 |
left | 不允许左边有浮动对象 |
right | 不允许右边有浮动对象 |
both | 不允许有浮动对象 |
但是要记住一点:这个规则只能影响使用清除的元素本身,不能影响其他元素。
vue
1. vue双向数据绑定的原理
vue.js是通过数据劫持结合发布-订阅者模式,通过object.defineProperty()
来劫持各个属性的getter
和setter
,在数据发生改变是通知订阅者,触发相应的监听回调
要实现mvvm的双向绑定,就必须要实现以下几点:
1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
4、mvvm入口函数,整合以上三者
react
1.react中的受控组件和非受控组件
在React中,所谓受控组件和非受控组件,是针对表单而言的。
表单受控组件
- 表单元素依赖于状态,表单元素需要默认值实时映射到状态的时候,就是受控组件,这个和双向绑定相似.
- 受控组件,表单元素的修改会实时映射到状态值上,此时就可以对输入的内容进行校验.
- 受控组件只有继承React.Component才会有状态.
- 受控组件必须要在表单上使用onChange事件来绑定对应的事件.
非受控组件
- 非受控组件即不受状态的控制,获取数据就是相当于操作DOM。
- 非受控组件的好处是很容易和第三方组件结合。
小程序
1.小程序授权被拒绝后如何再次让用户授权
众所周知小程序的例如获取地址授权,在用户拒绝后就不会在弹出了,但是也可能存在误操作需要重新授权,这时候可以使用wx.openSetting()
打开微信授权页面让用户手动授权
2.小程序登陆流程
略 点击查看