Open tomoya06 opened 4 years ago
64位中符号位占1位,指数位占11位,尾数52位。尾数默认第一位都是1,所以只存小数点以后的值。
例如十进制的0.1,化为二进制是0.0001100110011001...(无限循环) = 2^-4 * 1.10011(0011循环),保存为【0】【-4】【10011(0011x11次)010】(有进位)
因为 JS 的数字类型就用的是上面的标准,并且只要采用 IEEE 754 的语言都有该问题。数字运算都要先转成二进制,转换的过程中有误差,另外还有末尾进位,又导致误差。
0.1 -> 0.0001100110011001...(无限循环) = 2^-4 * 1.10011(0011x11次)001
0.2 -> 0.0011001100110011...(无限循环) = 2^-3 * 1.1(0011x12次)010
0.1 + 0.2 -> 2^-2 1.0011(0011 11次)0100 -> 0.30000000000000004
parseFloat((0.1 + 0.2).toFixed(10))
aka. image beacon
new Image().src = targetUrl
有传闻提出,用1x1透明gif图片发送数据埋点。部分存疑(哪来的图片?)不过用1x1 gif的好处在于:
AJAX,全称Asynchronous JavaScript And XML,就是使用 XMLHttpRequest 对象与服务器通信。
可以通过XMLHttpRequest或fetch两个接口发起。自己实现参考这里
完整示例:
参考MDN文档。
function sendRequestWithXML() {
const httpRequest = new XMLHttpRequest();
if (!httpRequest) {
alert('not support XMLHttpRequest');
return;
}
httpRequest.onreadystatechange = handleReadyStateChange;
httpRequest.open('GET', mockApi);
httpRequest.send();
function handleReadyStateChange() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
alert(httpRequest.responseText);
} else {
alert('oops: ', httpRequest.status);
}
}
}
}
完整示例:
function sendRequestWithFetch() {
fetch(mockApi)
.then(response => {
if (response.status === 200) {
return response.json();
} else {
throw new Error(response.status);
}
})
.then(data => {
alert(JSON.stringify(data));
}).catch(e => {
alert('oops: ', e);
})
}
来自本人面试经验。
AJAX hook的目的是能拦截所有ajax请求,统一处理请求数据和相应数据。目前市面上已经有一款ajax-hook的项目实现了类似的功能。下文参考该项目的实现来设计hook的实现思路。
Ajax-hook实现的整体思路是实现一个XMLHttpRequest的代理对象,然后覆盖全局的XMLHttpRequest,这样一旦上层调用 new XMLHttpRequest
这样的代码时,其实创建的是Ajax-hook的代理对象实例。
Ajax-hook也使用了es5的setter/getter方法来设置代理,在setter中把用户的自定义方法hook到XMLHttpRequest实例上。
来自栈溢出网友回答,感觉是不错的方法,通过改写prototype实现。
(function() {
var origOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function() {
console.log('request started!');
this.addEventListener('load', function() {
console.log('request completed!');
console.log(this.readyState); //will always be 4 (ajax is completed successfully)
console.log(this.responseText); //whatever the response was
});
origOpen.apply(this, arguments);
};
})();
对fetch的hook比较方便,引用另一个栈溢出网友的回答,只需包装一个promise来处理即可:
var taperFunction = response => response;
var originalFetch = fetch;
fetch = (input, init) => originalFetch(input, init)
.then(response => new Promise((resolve) => {
resolve(taperFunction(response));
}));
JSONP的基本思想:通过<script>
的src,向服务器请求数据,且这不受同源策略限制(img和iframe的src也是如此);然后服务器将相应的数据放入指定的函数回调名中,返回给前端。
使用<script>
请求API时,理论上相当于浏览器把接口返回的数据当成一个js文档来解析并执行。所以接口需要返回一段合法的js语句即可。
前端可以通过约定的API传参给后台提供一个函数名如callback
,后台只要返回callback(data)
即可。
前端需要动态创建一个<script>
标签,src设置为api并设好传参,同时还要声明一个对应的callback
方法,让script返回后可以有效执行。最好在收到数据之后,即callback方法执行之后把创建的<script>
标签再清除掉。
业务常用函数实现
防抖
_.debounce(func, [wait=0], [options={}])
doc here节流
_.throttle(func, [wait=0], [options={}])
doc here