# 202105
# 为什么 0.1 + 0.2 !== 0.3,请描述原因并手写解决该问题的函数。
因为js采用IEEE745双精度版本(64位),浮点数用二进制表示的时候是无穷的,因为精度问题,两个浮点数相加会造成截断丢失精度。
因此在转换为十进制就除了问题
解决:
function addNum(num1, num2) {
let sq1;
let sq2;
let m;
try{
sq1 = num1.toString().split('.')[1].length;
}catch (e) {
sq1 = 0;
}
try{
sq2 = num2.toString().split('.')[1].length;
}catch (e) {
sq2 = 0;
}
m = Math.pow(10, Math.max(sq1, sq2))
return (Math.round(num1 * m) + Math.round(num2 * m))/m;
}
# Vue 有了数据劫持为什么还要 DOM diff?这不是多此一举么。
vue数据变化,响应式系统立刻知道哪里变化,但是一个数据就要绑定一个Watcher,增加内存消耗及依赖追踪的开销;而颗粒度过低就不能精准侦测变化。vue在组件级别进行响应式侦测,组件内部通过Diff算法查找变化
# 闭包
形成过程:
- 形成执行上下文 Execution Content Stack
- 执行上下文返回的是引用类型,引用类型都是堆
- 执行上下文中,有变量被下面的执行上下文中的堆引用。导致没办法被垃圾回收,所以,形成了闭包
- 定义全局函数和重命名函数的时候,对引用类型的函数内存地址会改变,例如:AAAFF000 => BBBFFF000
- 执行ES stack 栈队列形式执行上下文(作用域),它们之间的变量(参数)相互引用就会形成闭包
var test = (function(i) {
return function() {
alert(i*=2); //
}
})(i)
test(5)
闭包解决了函数变量被外部作用域变量污染的问题(或者是全局变量污染的问题)更好的保护一些变量,调用变量的时候效率也会变高
# promise和async await
async/await是一种便携异步代码的新方法。在这之前编写异步代码使用的是回调函数和promise
async/await实际是建立在promise之上的。因此你不能把它和回调函数搭配使用
async/await可以使异步代码在形式上更接近于同步代码,这就是它的最大价值
# eval()
eval(string)
string 表示javascript表达式、语句或一系列语句的字符串。表达式可以包含变量与已存在对象的属性
返回值:返回字符串代码的返回值。如果返回值为空,则返回undefined
# 为什么data是一个函数
组件中的data写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。而单纯的写成对象形式,就使得所有组件实例共用一份data,就会造成一个变了全都会变的结果
# 怎样理解vue 的单向数据流
数据总是从父组件传到子组件,子组件没有权利修改父组件传过来的数据,只能请求父组件队员数数据进行修改。这样会防止从子组件意外改变父组件的状态。从而导致你的应用数据流向难以理解。
TIP
注意:在子组件直接用v-model绑定父组件传过来的prop这样是不规范的写法,开发环境会报警
如果实在要改变父组件的prop值,可以在data里面定义一个变量,并用prop的值初始化它,之后用$emit通知父组件取修改