首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

前端面试题库系列(1)

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

<style>

div+div{

color: red;

}

div>div{

color: blue;

}

div:nth-child(3n){

color: yellow;

}

</style>

</head>

<body>

<div>

<div>A-0</div>

<div>A-1</div>

<div>A-2</div>

<div>A-3</div>

<div>A-4</div>

<div>A-5</div>

</div>

<div></div>

<script>

// 1、浏览器是怎么解析css选择器的

// 浏览器解析css选择器的规则是从右向左的,这样会提高查找选择器所对应的元素的效率。

// CSS选择器的解析是从右向左解析的。若从左向右的匹配,发现不符合规则,需要进行回溯,会损失很多性能。

// 若从右向左匹配,先找到所有的最右节点,对于每一个节点,向上寻找其父节点直到找到根元素或满足条件的匹配规则,

// 则结束这个分支的遍历。两种匹配规则的性能差别很大,

// 是因为从右向左的匹配在第一步就筛选掉了大量的不符合条件的最右节点(叶子节点),

// 而从左向右的匹配规则的性能都浪费在了失败的查找上面。

// 而在 CSS 解析完毕后,需要将解析的结果与 DOM Tree 的内容一起进行分析建立一棵 Render Tree,

// 最终用来进行绘图。在建立 Render Tree 时(WebKit 中的「Attachment」过程),

// 浏览器就要为每个 DOM Tree 中的元素根据 CSS 的解析结果(Style Rules)来确定生成怎样的 Render Tree。

// 2、css新增伪类有哪些?

// :root 选择文档的根元素,等同于 html 元素

/* :empty 选择没有子元素的元素

:target 选取当前活动的目标元素

:not(selector) 选择除 selector 元素意外的元素

:enabled 选择可用的表单元素

:disabled 选择禁用的表单元素

:checked 选择被选中的表单元素

:after 在元素内部最前添加内容

:before 在元素内部最后添加内容

:nth-child(n) 匹配父元素下指定子元素,在所有子元素中排序第n

:nth-last-child(n) 匹配父元素下指定子元素,在所有子元素中排序第n,从后向前数

:nth-child(odd)

:nth-child(even)

:nth-child(3n+1)

:first-child

:last-child

:only-child

:nth-of-type(n) 匹配父元素下指定子元素,在同类子元素中排序第n

:nth-last-of-type(n) 匹配父元素下指定子元素,在同类子元素中排序第n,从后向前数

:nth-of-type(odd)

:nth-of-type(even)

:nth-of-type(3n+1)

:first-of-type

:last-of-type

:only-of-type

::selection 选择被用户选取的元素部分

:first-line 选择元素中的第一行

:first-letter 选择元素中的第一个字符

*/

// 3、css中rrba()和opacity的透明效果有什么不同?

/* 1.opacity 是属性,rgba()是函数,计算之后是个属性值;

2.opacity 作用于元素和元素的内容,内容会继承元素的透明度,取值0-1;

3.rgba() 一般作为背景色 background-color 或者颜色 color 的属性值,透明度由其中的 alpha 值生效,取值0-1;

扩展:

1.transparent 也是透明,是个属性值,颜色值,跟#000是一类,不过它是关键字来描述。*/

//4、css优化、提高性能的方法有哪些?

/*1,首推的是合并css文件,如果页面加载10个css文件,每个文件1k,那么也要比只加载一个100k的css文件慢。

2,减少css嵌套,最好不要套三层以上。

3,不要在ID选择器前面进行嵌套,ID本来就是唯一的而且人家权值那么大,嵌套完全是浪费性能。

4,建立公共样式类,把相同样式提取出来作为公共类使用,比如我们常用的清除浮动等。

5,减少通配符*或者类似[hidden="true"]这类选择器的使用,挨个查找所有...这性能能好吗?当然重置样式这些必须 的东西是不能少的。

6,巧妙运用css的继承机制,如果父节点定义了,子节点就无需定义。

7,拆分出公共css文件,对于比较大的项目我们可以将大部分页面的公共结构的样式提取出来放到单独css文件里, 这样一次下载后就放到缓存里,当然这种做法会增加请求,具体做法应以实际情况而定。

8,不用css表达式,表达式只是让你的代码显得更加炫酷,但是他对性能的浪费可能是超乎你的想象的。

9,少用css rest,可能你会觉得重置样式是规范,但是其实其中有很多的操作是不必要不友好的,有需求有兴趣的 朋友可以选择normolize.css

10,cssSprite,合成所有icon图片,用宽高加上bacgroud-position的背景图方式显现出我们要的icon图,这是一种 十分实用的技巧,极大减少了http请求。

11,当然我们还需要一些善后工作,CSS压缩(这里提供一个在线压缩 YUI Compressor ,当然你会用其他工具来压缩是十 分好的),

12,GZIP压缩,Gzip是一种流行的文件压缩算法,详细做法可以谷歌或者百度。*/

//5、html5存储类型有什么区别?

/* session级别的sessionStorage,只在当前域名内才有效,当浏览器窗口关闭,

存入的值跟着也消失,它提供三个方法getItem("key")\setItem(key,value)\removeItem(key);

cookie级别的localStorage,永久存在浏览器中,方法跟sessionStorage一样*/

//6、简述一下你对html语义化的理解?

/*(1)HTML 语义化让页面的内容结构化,结构更清晰,便于对浏览器、搜索引擎解析;

(2)即使在没有样式 CSS 的情况下也能以一种文档格式显示,并且是容易阅读的;

(3)搜索引擎的爬虫也依赖于 HTML 标记来确定上下文和各个关键字的权重,有利于 SEO;

(4)使阅读源代码的人更容易将网站分块,便于阅读、维护和理解。

————————————————

*/

// 7、从输入url到浏览器显示页面,在这个过程中发生了什么?

/*▍大致流程

1、DNS解析,将域名解析为IP地址;

2、浏览器与服务器建立TCP连接(三次握手);

3、浏览器向服务器发起HTTP请求;

4、服务器接收请求并响应,返回相应的HTML文件;

5、浏览器接收从服务器端返回的数据,并进行页面渲染。*/

//8、如何优化这段代码,提高js性能

/* function updateInfo() {

var imgs=document.getElementsByTagName('img');

for(var i=0;i<imgs.length;i++){

if(imgs[i].alt=='hellow world'){

imgs[i].title=doc.title+'image'+i;

}

}

var msg=document.getElementById('msg');

msg.innerHTML='Update complete';

}*/

//9、简单阐述一下扩展运算符的运用场景

// 1、函数调用

/*function add(x, y) {

return x + y;

}

console.log( add(...[4, 38]))//42

function f(v, w, x, y, z) {

console.log(v, w, x, y, z)

}

f(-1, ...[0, 1], 2, ...[3]);//-1 0 1 2 3*/

// 2、往数组里push多个元素

/* var arr1 = [0, 1, 2];

var arr2 = [3, 4, 5];

arr1.push(...arr2);

console.log(arr1); //[0,1,2,3,4,5]*/

// 3、替代函数的apply方法

/*function f(x, y, z) {

}

var args = [0, 1, 2];

f.apply(null, args); //ES5 的写法

f(...args); //ES6的写法*/

// 4、求一个数组的最大数简化

/* Math.max.apply(null, [14, 3, 77]) //ES5 的写法

Math.max(...[14, 3, 77]) //ES6 的写法,等同于Math.max(14, 3, 77)*/

// 5、扩展运算符后面可以放表达式

/* const arr = [...(5 > 0 ? ['a'] : []),'b'];

console.log(arr); //['a','b'] */

// 6、与解构赋值结合,用于生成数组

/*const a1 = [1, 2];

const a2 = [...a1]; //写法1

const [...a2] = a1; //写法2

const [first, ...rest] = [1, 2, 3, 4, 5];

first //1

rest //[2, 3, 4, 5]

const [first, ...rest] = [];

first //undefined

rest //[]

const [first, ...rest] = ["foo"];

first //"foo"

rest //[]*/

// 7、合并数组

// [...arr1, ...arr2, ...arr3] //[ 'a', 'b', 'c', 'd', 'e' ]

// 8、数组的克隆(坑在这儿 , 特别注意

/* var arr1 = [0, 1, 2];

var arr2 = [...arr1];

arr1[0]=100;

console.log(arr2); //[0, 1, 2]

/!* 乍一看,arr2与arr1不共用引用地址,arr2不随着arr1变化,接着往下看 *!/

var arr1 = [0, [1,11,111], 2];

var arr2 = [...arr1];

arr1[1][0]=100;

console.log(arr2); //[0, [100,11,111], 2]

/!* 通过打印结果发现,arr2与arr1里边的二维数组共用一块引用地址 *!/

结论:用一个扩展运算符,并不能实现复合对象类型的深克隆。

注意:项目开发中,遇到复合数据确认已经改变,页面上却没更新的情况,可以从

这块考虑进行排除。楼主从事的是React开发,入过坑,贴出来,希望能给大家带

来一些解决问题的思路。*/

// 10、关于异步处理:Generator,async,promise的区别

/*

Promise将原来的用回调函数的异步编程方法转成用resolve和reject触发事件,

用 then 和 catch 捕获成功或者失败的状态执行相应代码的异步编程的方法。

Generator函数是将函数分步骤阻塞 ,只有主动调用next()才能进行下一步。

dva 中异步处理用的是 Generator

简单的说async函数就相当于自执行的Generator函数,相当于自带一个状态机,在 await 的部分等待返回, 返回后自动执行下一步。而且相较于Promise,async 的优越性就是把每次异步返回的结果从 then 中拿到最外层的方法中,不需要链式调用,只要用同步的写法就可以了。

比 promise 直观,但是 async 必须以一个 Promise 对象开始 ,所以 async 通常是和Promise 结合使用的。

*/

// 11、简单阐述一下instanceof操作符的作用

/*instanceof操作符用来在运行时检测一个对象的类型。JavaScript里的每个对象都有一个协议类型,

可以通过__proto__ 属性访问。函数同样有一个协议类型的属性,

这是由它们创建的任何对象初始化的__proto__。

当创建一个函数时,为协议类型会给定一个唯一的对象。

instanceof 用一个对象的协议类型确定它是否是一个类的实例,或者是一个结构函数。

它返回一个布尔值,用以确定是否一个对象是一个指定类的实例。*/

// 12、如何深拷贝一个对象

/* function copyFn(obj) {

if (obj == null) {

return null

}

var result = Array.isArray(obj) ? [] : {};

for (let key in obj) {

if (obj.hasOwnProperty(key)) {

if (typeof obj[key] === 'object') {

result[key] = copyFn(obj[key]); // 如果是对象,再次调用该方法自身

} else {

result[key] = obj[key];

}

}

}

return result;

}*/

// 我们定义一个 clone 方法实现深度复制功能(Deep Copy),其内部实现原理就是将对象、数组的属性遍历一遍,赋给一个新的对象

/*function clone(obj) {

var copy = {};

for (var attr in obj) {

copy[attr] = typeof(obj[attr])==='object' ? clone(obj[attr]) : obj[attr];

}

return copy;

}*/

// 可以直接给 Object 增加个 clone 方法,其内部实现原来同上面是一样的

/* Object.prototype.clone = function() {

var copy = (this instanceof Array) ? [] : {};

for (var attr in this) {

if (this.hasOwnProperty(attr)){

copy[attr] = typeof(this[attr])==='object' ? clone(this[attr]) : this[attr];

}

}

return copy;

};*/

//13、简单阐述一下es6中新增的原始数据类型和其作用

// es6中新增一种原始数据类型Symbol,最大的特点是唯一性,Symbol值通过Symbol函数生成, 在es5中对象的属性都是字符串,我们使用他人定义的对象,然后去新增自己的属性,这样容易起冲突覆盖原有的属性, Symbol也可以看成为一个字符串,不过这个字符能保证是独一无二的

// 14、请阅读以下代码,并写出运行结果。

/* setTimeout(function () {

console.log(1)

},0)

new Promise(function executor(resolve) {

console.log(2);

for(var i=0;i<10000;i++){

i===9999&&resolve()

}

console.log(3)

}).then(function () {

console.log(4)

})

console.log(5)

//2 3 5 4 1*/

// 15、行内元素有哪些?块级元素有哪些?空(void)元素有哪些?

/*行内元素:a、b、span、img、input、strong、select、label、em、button、textarea

块级元素:div、ul、li、dl、dt、dd、p、h1-h6、blockquote

空元素:即系没有内容的HTML元素,例如:br、meta、hr、link、input、img*/

//16、<img>中title和alt的区别?

/*Alt是<img>的特有属性,是图片内容的等价描述,用于图片无法加载时显示,读屏器阅读图片。

title 可提高图片高可访问性,除了纯装饰图片外都必须设置有意义的值,搜索引擎会重点分析。鼠标滑过时显示的文字提示,用户体验上很重要。当然不必要所有的img标签都加此属性,比方说logo这样比较重要或者说用户会体验到的图片内容建议一定要加此属性。*/

//17、cookies,sessionStorage,localStorage的区别?

/*共同点:都是保存在浏览器端,且同源的。

区别:cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。Web Storage 的 api 接口使用更方便。

sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。

因此sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储。

而localStorage用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。*/

//18、display:inline-block什么时候会显示间隙?

/*就在子元素上加vertical-align:bottom;就不贴代码了,*/

//19、以下代码中,A-o~A-5和B的颜色分别为?如果希望每个两个(即:A-2和A-5等)均设置为黄色,应该如何做?

//蓝色

//20、es5和es6中的基本数据类型有哪些?

// es5中 undefined,null,boolean,number,string

// es6中 Number,String, Null, Undefined, Symbol, Boolean

//21、script标签的defer,async的区别?

/*async:与后续元素渲染异步执行,乱序执行,若js文件之间存在依赖关系,容易产生错误,只适用于完全没有依赖的文件,文档解析过程中异步下载,下载完成之后立即执行。

defer:(H5规范中,defer是有序执行的,但实际不一定是有序执行的)与后续渲染异步执行,延迟到界面文档解析完成之后执行,即为立即下载,延迟执行。所有执行均在DOMContentLoaded 事件触发之前完成。

不带属性:加载到script立即下载并执行,阻塞后续渲染的执行。

*/

//22、Ajax的缺点?

// 它可能破坏浏览器的后退与加入收藏书签功能,大量的使用了javascript和ajax引擎,这些取决于浏览器的支持.在编写的时候考虑对浏览器的兼容性.

// AJAX只是局部刷新,所以页面的后退按钮是没有用的.

// 对流媒体还有移动设备的支持不是太好等

//23、判断以下时间段是否有重叠范围(口述题)

// ['05:00-08:00','09:30-12:00','09:00-11:00','13:00-15:00']

// 24、git fetch 和git pull区别

// git fetch 相当于是从远程获取最新到本地,不会自动merge

// git pull:相当于是从远程获取最新版本并merge到本地

//25、用正则校验用户名,要求:6-16位(允许包含:大小写英文,数字,下划线,减号)

// var uPattern = /^[a-zA-Z0-9_-]{6,16}$/;

//26、JavaScript的存储方式有哪些?

/*1、sessionStorage

2、localStorage

3、cookier*/

//27、什么情况下会遇到跨域?怎么解决?

/*浏览器最核心,最基本的安全功能是同源策略。限制了一个源中加载文本或者脚本与其他源中资源的交互方式,当浏览器执行一个脚本时会检查是否同源,只有同源的脚本才会执行,如果不同源即为跨域。

jsonp

:原理就是利用了script标签src属性外联引入文件不受同源策略的限制,在页面中动态插入了script,script标签的src属性就是后端api接口的地址,并且以get的方式将前端回调处理函数名称告诉后端,后端在响应请求时会将回调返还,并且将数据以参数的形式传递回去;

document.domin:两个域名必须属于同一基础域名,并且所有的协议端口完全一致,否则无法跨域;例:beijing.58.com

tianjing.58.com ;

iframe、hash :父页面向子页面传输数据:将要传递的数据添加到子页面的url的hash值上,子页面通过location.hash

并添加定时器实时地动态父页面传来的数据;子页面向父页面传输数据:利用window.name的特性,及页面重新加载但当前页的name值不变,即使换了一个页面。需要三个页面配合使用。一个应用页面,一个数据页面,一个代理文件。代理文件一般是一个没有任何内容的html页面,需要和应用页面在同一域下。将数据页面的窗口换成代理页面,代理页面通过window.name获取数据页面留下的数据,应用页面再访问和它同源的代理页面获取数据,就完成了跨域;

CORS(Cross-Origin-Resource-Sharing):在服务器端设置的,不需要客户端进行操作。Cors背后的思想是使用自定义的http头部让浏览器和服务器进行沟通,从而决定请求或响应是否应该成功,还是应该失败。浏览器向服务器发送请求,如果服务器认为这个请求可以接受,就在Access-Control-Allow-Origin头部中回发相同的源信息(如果是公共资源,可以回发*);如果没有这个头部,或者有这个头部但信息源不匹配,浏览器就会驳回请求。正常情况下,浏览器会处理请求。(请求和响应都不包含cookie信息);

服务器跨域,服务器中转代理:前端向本地服务器发送请求,本地服务器代替前端再向服务器接口发送请求进行服务器间通信,本地服务器是个中转站的角色,再将响应的数据返回给前端。

window.postMessage(h5新增)

WebSocket(h5新增)

————————————————

*/

//28、写出以下代码输出值,尝试用es5和es6的方式进行改进输出循环中的i值

/*for(var i=1;i<=5;i++){

setTimeout(function timer() {

console.log(i)

},i*1000)

}*/

//6 6 6 6 6

/* for(let i=1;i<=5;i++){

setTimeout(function timer() {

console.log(i)

},i*1000)

}*/

// 1 2 3 4 5

//29、v-if和v-show的共同点和区别

/*共同点:

v-if 和 v-show 都是动态显示DOM元素。

区别:

编译过程:

v-if 是 真正 的 条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。v-show

的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性display。

编译条件:

v-if 是惰性的:如果在初始渲染时条件为假,则什么也不做。直到条件第一次变为真时,才会开始渲染条件块。v-show不管初始条件是什么,元素总是会被渲染,并且只是简单地基于

CSS 进行切换。

性能消耗:

v-if有更高的切换消耗。v-show有更高的初始渲染消耗。

应用场景:

v-if适合运行时条件很少改变时使用。v-show适合频繁切换。*/

//30、路由导航钩子(导航守卫)有哪些?

/*在项目开发中每一次路由的切换或者页面的刷新都需要判断用户是否已经登录,前端可以判断,后端也会进行判断的,我们前端最好也进行判断。

vue-router提供了导航钩子:全局前置导航钩子 beforeEach和全局后置导航钩子 afterEach,他们会在路由即将改变前和改变后进行触发。所以判断用户是否登录需要在beforeEach导航钩子中进行判断。

导航钩子有3个参数:

1、to:即将要进入的目标路由对象;

2、from:当前导航即将要离开的路由对象;

3、next :调用该方法后,才能进入下一个钩子函数(afterEach)。

next()//直接进to 所指路由

next(false) //中断当前路由

next('route') //跳转指定路由

next('error') //跳转错误路由*/

// 31、请写出如下代码的执行结果:

/* setTimeout(()=>{

console.log(1)

})

new Promise(resolve => {

resolve()

console.log(2)

}).then(()=>{

console.log(3)

Promise.resolve().then(()=>{

console.log(4)

}).then(()=>{

Promise.resolve().then(()=>{

console.log(5)

})

})

})*/

// 2 3 4 5 1

//32、统计数组arr中值等于item的元素出现的次数

// 示例

// 输入

// [1,2,4,4,3,4,3] 4

/*function sum(arr) {

return Array.from(new Set([...arr])).length

}

console.log(sum([1,2,4,4,3,4,3]))*/

//33、计算给定数组arr中所有元素的总和

// 输入描述:

// 数组中的元素均为Number类型

// 示例

// 输入

// [1,2,3,4]

// 输出

// 10

/*function count(arr,item) {

for (var i=arr.length-1; i>=0; i--) {

item += arr[i];

}

return item;

}

console.log(count([1,2,3,4],0))*/

// 34、实现一个打点计时器,要求:

//1、从start到end(包含start和end),每隔100毫秒console.log

// 一个数字,每次数字增幅为1

//2、返回的对象中需要包含一个cancel方法,用于停止定时操作

//3、第一个数需要立即输出

/* function count(start, end) {

if(start <= end){

console.log(start++);

st = setTimeout(function(){count(start, end)}, 100);

}

return {

cancel: function(){clearTimeout(st);}

}

}

count(1, 10);*/

/*function count(start, end) {

console.log(start++);

var timer = setInterval(function () {

if (start <= end) {

console.log(start++)

}

}, 100);

return {

cancel: function () {

clearInterval(timer)

}

}

}

count(1, 10);*/

//35、实现函数makeClosures,调用之后满足如下条件:

// 1、返回一个函数数组result,长度与arr相同

// 2、运行result中第i个函数,即result[i](),结果与fn(arr[i])相同

// 示例

/* [1,2,3].function(x){

return x*x

}

输出

4*/

/*function makeClosures(arr,fn) {

var result = [];

arr.forEach(function(e){

result.push(function(num){

return function(){

return fn(num);

};

}(e));

});

return result;

}*/

//36、下面代码输出多少

/*var obj={

value:1

}

function foo(o) {

o.value=2;

console.log(o.value)

}

foo(obj)

console.log(obj.value)*/

// 2 2

//36、为什么会出现浮动?什么时候需要清除浮动?

// 浮动float最开始出现的意义是为了让文字环绕图片而已,但人们发现,如果想要三个块级元素并排显示,都给它们加个float来得会比较方便。

// 37、以下JavaScript程序

/* function b() {

var result=new Array();

for(var i=0;i<10;i++){

result[i]=function () {

return i

}

}

return result;

}

console.log(b())//[f,f,f...]

// 10个

/!* function () {

return i

}*!/

console.log(b()[0]())//10*/

//38、如何上下左右居中div?

/*div {

position:absolute;

top:50%;

left:50%;

margin:-150px 0 0 -200px;

width:400px;

height:300px;

border:1px solid #008800;

}*/

//39、模拟

/*function add1(n,callback) {

setTimeout(function () {

callback(null,n+1)

},10);

}

function mul3(n,callback) {

setTimeout(function () {

callback(null,n*3)

},10)

}

var add1mul3=async.compose(mul3,add1);

add1mul3(4,function (err,result) {

// result new equals 15

})*/

</script>

</body>

</html>

在任何时代,

教育说起来都是一件高大上的事,

但却没有什么真正有价值的东西是教得会的,

没有任何一种文化模因

可以说清楚一个个体的全部问题。

在任何时代,

想要抓住人性的弱点来赚钱都非常容易,

没有一点高级。

相反,想要建设一种文化,

耐心地拆除信息壁垒,

并且能够坚持下来,

那真不是一般的不易。

在任何时代,

在一秒钟内看到本质的人,

和花半辈子看不清的人,

自然是不一样的命运。

下一篇
举报
领券