前端基础题-P1
最近跟朋友讨论一些前端面试题,总结如下,巩固下基础
TCP三次握手
三次握手,四次挥手需要了解,推荐朝三暮四
这个词辅助记忆。
图解如下
数字精度
console.log(0.1 + 0.2 > 0.3); // true
原因
十进制的0.1
和0.2
都会被转换成二进制,但由于浮点数用二进制表达时是无穷的,因此会出现这个问题。
解决办法
以使用第三方类库big.js
console.log(new Big(0.1).plus(0.2)==0.3); // true
前端本地化存储方案
- localstorage
- sessionStorage
- cookie
注意
localstorage的存储
无过期时间
sessionStorage的存储
无法跨tab使用
对于cookie,浏览器并没有提供删除cookie的方法,需要利用
过期时间
来实现删除前端存储最终都是字符串,如果存储对象,存取需要序列化操作,否则并不会直接报错,而是JS自动调用String化。
localStorage.setItem('name', 'alan'); // alan localStorage.setItem('age', 1); // 1 console.log(typeof localStorage.getItem('age')); // string localStorage.setItem('user', { name: 'alan', age: 1 }); // [object Object] localStorage.setItem('null', null); // null localStorage.setItem('undefined', undefined); // undefined
变量提升
- JavaScript 中,函数及变量的
声明
都将被提升
到函数的最顶部。 - JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明。
- JavaScript 只有声明的变量会提升,
初始化不会
。 - function,var,let,const,class声明都会提升,只是var声明时初始化是undefined,而let,const还是uninitialized。
例题
// source code
console.log(a); // undefined
var a= 'Hello World!';
// transformed
var a;
console.log(a); // undefined
a = 'Hello World!';
helloWorld(); // TypeError: helloWorld is not a function
var helloWorld = function () {
console.log('Hello World!');
};
闭包
一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。
例题
var btn = document.getElementsByTagName('button');
for (var i = 0; i < btn.length; i++) {
btn[i].onclick = function () {
console.log(i); // 永远是5
};
}
可以利用闭包,方式如下
var btn = document.getElementsByTagName('button');
for (var i = 0; i < btn.length; i++) {
btn[i].onclick = ((j) => () => console.log(j))(i);
}
异步执行顺序
异步指两个或两个以上的对象或事件不同时存在或发生(或多个相关事物的发生无需等待其前一事物的完成)。在计算机技术中,“异步"一词被用于两大语境(网络与通信,软件设计)。
注意
- Promise是异步的
- XHR可同步,可异步
- window.setTimeout是异步的
例题
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
async1();
new Promise(function (resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end');
答案是
- script start
- async1 start
- async2
- promise1
- script end
- async1 end
- promise2
- setTimeout
解码多次编码的URL
let url = 'https://baike.baidu.com/item/%25E8%2583%25A1%25E6%25AD%258C/312718';
do {
url = decodeURI(url);
} while (url !== decodeURI(url));
console.log(url);
CSS盒模型
当对一个文档进行布局(lay out)的时候,浏览器的渲染引擎会根据标准之一的 CSS 基础框盒模型(CSS basic box model),将所有元素表示为一个个矩形的盒子(box)。CSS 决定这些盒子的大小、位置以及属性(例如颜色、背景、边框尺寸…)。
例题
.box {
width: 100px;
height: 100px;
background-color: red;
padding: 10px;
border: 10px solid blue;
margin: 10px;
}
红色区域宽度为120px,原因是100px+10px+10px
CSS三大特性
- 层叠性
就近原则,后覆盖前
- 继承性
- 子继承父
- 但是有些特殊的标签不继承的
- 优先级
- ID > class【属性】> 标签,优先级递减
例题
<style>
.red {
color: red;
}
.blue {
color: blue;
}
* {
color: black !important;
}
</style>
<div class="blue red">hello world</div>
实际文本会显示为黑色,因为important为最高优先级,但当去掉这个,会是蓝色,因为CSS层叠性决定后覆盖前。
前端性能优化
- gzip压缩/预压缩
- HTML,CSS,JS压缩
- 前端缓存
- 懒加载,预加载,降低需要加载JS的体积
- 充分利用请求带宽,比如并发执行多个请求
注意单域名下请求个数限制
- CDN静态资源,提升缓存/请求速度
- code本身优化,比如SPA优化render,降低渲染频次,比如部分轮询可以走WebSocket降低请求次数
- SSR
- 高频高耗计算请求可以走Web Worker
写在最后
透过这些题可以看出还是那些基础问题,但也需要了解如今的前端知识点并不少,除了本身熟悉前端三剑客【HTML,CSS,JS】,对于网络,算法,浏览器运行原理等都需要熟悉。