web前端开发面试题汇总
- 浏览器:IE,Chrome,FireFox,Safari,Opera。
- 内核:Trident,Gecko,Presto,Webkit。 2.行内元素和块级元素
- 行内元素:水平排列,不能包含块级页面;width/height无效,margin/padding无效
- 块级元素:各占据一行,垂直方向排列。从新行开始结束接着一个断行。
- 兼 容 性:
display:inline-block;display:inline;zoom:1;
3. 清除浮动有哪些方式?比较好的方式是哪一种?浮动的意义:初衷是用于让文字环绕图片,float可以自动包裹元素,float可导致高度坍塌--
当标签里元素只有样子没有实际高度时会坍塌,浮动会脱离文档流,产生自己的块级上下文。- 本级尾部加标签:结尾处加空标签(div,br...)并clear :both;
- 本级定义父级
- 伪类:after和zoom
- 高度:height
- overflow:hidden/auto
- display:table
- 浮动并定义宽度
比较好的是第3种方式,简洁方便。
- 属性:box-sizing: content-box|border-box|inherit;
- 作用:
- content-box:宽高度分别对应到元素的content,内边距和边框在宽高之外渲染(默认)。
- border-box:宽高度分别对应到元素的border,任何内边距和边框都将在已设定的宽高内渲染。
总结:x-box=>元素宽高对应到x
- 告知浏览器的解析器用什么文档标准解析这个文档。
DOCTYPE不存在或格式不正确会导致文档以兼容模式呈现。 - 标准模式的渲染引擎都是以该浏览器支持的最高标准运行。
在兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作。
< Doctype html>
?
7. 页面导入样式时,使用link和@import有什么区别?如果浏览器基于SGML,需要对DTD引用;H5不基于它,HTML4.01基于它
doctype用于规范浏览器行为,H5需要引入它以受控
- 语法的角度:
link属于XHTML标签,除了加载CSS外,还能用于定义RSS, 定义rel连接属性等作用;
而@import是CSS提供的语法,只能用于加载CSS; - 浏览器解析的角度
页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载(标准浏览器);
- 兼容性问题
import是CSS2.1 提出的,只在IE5以上才能被识别,而link是XHTML标签,无兼容问题。
总之,link要优于@import,由此决定了它的适应性更广,加载性更快,兼容性更强。
8.浏览器内核- 内核分类
浏览器 | 内核 |
---|---|
Chrome,Safari | WebKit |
Opera | Presto=>Blink |
FF | Gecko |
IE | Trident |
-
内核分类
渲染引擎和JS引擎
- 渲染引擎
负责取得网页的内容(HTML、XML、图像...)+整理讯息(CSS...)+计算网页的显示方式,
然后输出(显示器/打印机)。
浏览器的内核决定其渲染的效果。
适用范围:所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。
- JS引擎则
解析和执行js的引擎。
起初js引擎并不独立于渲染引擎,随着web技术的发展逐渐独立出来(chrome的V8引擎)
- 渲染引擎
HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。
- 绘画 :canvas,svg;
- 媒体元素: video 和 audio 元素;
- 存储:本地离线存储 localStorage ,sessionStorage 的数据在浏览器关闭后自动删除;
- 语义化标签:article、footer、header、nav、section,main,aside;
- 表单控件:calendar、date、time、email、url、search,upload;
- 新的技术webworker, websocket, Geolocation;
- hack:IE8/IE7/IE6支持通过document.createElement方法产生的标签, 可以利用这一特性让这些浏览器支持HTML5新标签,
浏览器支持新标签后,还需要添加标签默认的样式。 也可以直接使用成熟的框架、比如html5shim,
语义化标签的理解:用正确的标签做正确的事情。
- 语义化:html语义化让页面的内容结构化,结构更清晰,便于对浏览器、搜索引擎解析;
- 利于SEO:即使在没有样式CSS情况下也以一种文档格式显示,并且是容易阅读的;
搜索引擎的爬虫也依赖于HTML标记来确定上下文和各个关键字的权重;
离线储存
方式 | 数据源 | 信息量 | 接口 | 存储空间独立性 |
---|---|---|---|---|
cookie | B+S | 小 | 小 | 依赖 |
sessionStorage | B | 大 | 多 | 独立 |
localStorage | B | 大 | 多 | 独立 |
problem | describe | hack |
---|---|---|
png24位的图片 | iE6浏览器上出现背景 | 做成PNG8 |
margin/padding | 不同浏览器显示不同 | {margin:0;padding:0;} |
IE6双边距bug | xx | 百度 |
getAttribute() | Firefox下,只能使用getAttribute()获取自定义属性;IE都行 | 统一通过getAttribute()获取自定义属性 |
even对象 | IE下,有x,y属性,但是没有pageX,pageY属性;Firefox下反之 | (条件注释)缺点是在IE浏览器下可能会增加额外的HTTP请求数。 |
Chrome | 中文界面下默认会将小于 12px 的文本强制按照 12px 显示 | 通过加入 CSS 属性 -webkit-text-size-adjust: none; |
L-V-H-A | 超链接访问过后hover样式就不出现了 被点击访问过的超链接样式不在具有hover和active了 | 改变CSS属性的排列顺序a:link {} a:visited {} a:hover {} a:active {} |
第二部分CSS 1.盒模型
- 分类:标准盒模型和IE盒模型;区别:content 是否包含 border 和 pading(IE包含);
盒模型: content,padding,margin ,border
选择符
1.id选择器( # myid)
2.类选择器(.myclassname)
3.标签选择器(div, h1, p)
4.相邻选择器(h1 + p)
5.子选择器(ul > li)
6.后代选择器(li a)
7.通配符选择器( * )
8.属性选择器(a[rel = "external"])
9.伪类选择器(a: hover, li: nth - child)
可继承性
- 可继承属性
font-size font-family color,ul,li,dd,dt;
- 不可继承的属性
border padding margin width height
优先级
- 就近原则:同权重情况下样式定义最近者为准,载入样式以最后载入的定位为准;
- 优先级算法: !important > id > class > tag
3. CSS3新增伪类
p:first-of-type 选择属于其父元素的首个 <p> 元素的每个 <p> 元素。
p:last-of-type 选择属于其父元素的最后 <p> 元素的每个 <p> 元素。
p:only-of-type 选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。
p:only-child 选择属于其父元素的唯一子元素的每个 <p> 元素。
p:nth-child(2) 选择属于其父元素的第二个子元素的每个 <p> 元素。
:enabled :disabled 控制表单控件的禁用状态。
:checked 单选框或复选框被选中。
- 水平居中
div{width:200px; margin:0 auto; }
- 垂直居中
div{ background: red; width: 100px; height: 200px; position: absolute; top: 50%; left: 50%; margin-left: -50px; margin-top: -100px; /*transform: translate(-50%,-50%);*/ }
display:block|inline-block|list-item|none
position
- absolute :生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位。
- fixed :(老IE不支持)生成绝对定位的元素,相对于浏览器窗口进行定位。
- relative:生成相对定位的元素,相对于其正常位置进行定位。
- static :默认值。没有定位,元素出现在正常的流中, (忽略 top, bottom, left, right z-index 声明)
- inherit: 规定从父元素继承 position 属性的值。 6. CSS3新特性
- CSS3实现圆角(border-radius:8px),
- 阴影(box-shadow:10px),
- 对文字加特效(text-shadow、)
- 线性渐变(gradient)
- 旋转(transform)
- ransform:rotate(9deg) scale(0.85,0.90) translate(0px,-30px)
- skew(-9deg,0deg);//旋转,缩放,定位,倾斜
- 增加了更多的CSS选择器 多背景 rgba
JavaScript
事件代理/事件委托(delegation)
当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件
委托给父节点来触发处理函数。这主要得益于浏览器的事件冒泡机制。
function(client, clientMethod) { return function() { return clientMethod.apply(client, arguments); } } var agentMethod = delegate (client, clientMethod); agentMethod();
简单实例
var resources = document.querySelector('#resources'), log = document.querySelector('#log'); resources.addEventListener('mouseover', showtarget, false); function showtarget(ev) { var target = ev.target; if (target.tagName === 'A') { log.innerHTML = 'A link, with the href:' + target.href; } if (target.tagName === 'LI') { log.innerHTML = 'A list item'; } if (target.tagName === 'UL') { log.innerHTML = 'The list itself'; }} //方便之处 document.getElementById("parent-list").addEventListener("click", function(e) { if(e.target && e.target.nodeName == "LI") { console.log("List item ", e.target.id.replace("post-"), " was clicked!"); } });
this对象使用场景
- 作为函数调用,this 绑定全局对象,浏览器环境全局对象为 window 。
- 内部函数的 this 也绑定全局对象
(应该绑定到其外层函数对应的对象上,这是 JavaScript的缺陷,用that替换) - 作为构造函数使用,this 绑定到新创建的对象。
- 作为对象方法使用,this 绑定到该对象。
- 使用apply或call调用 this 将会被显式设置为函数调用的第一个参数。
原型继承原理
每个函数都有一个原型对象的属性(F.prototype),每个函数都可以是一个构造函数。
即通过new关键字可以创建任意函数的一个实例。
原型继承原理:JS中是没有类的,所有继承属于基于原型的继承。在调用某个对象的属性或方法
时,js引擎会优先在该对象自身上查找该属性或方法,如果没有便去该对象的构造函数中去查找,
如此逐级递归查找,直到原型链的最顶层。
hash表
哈希表是根据key-value键值对而直接访问对象在内存的存储位置的数据结构。即,它是
通过把键值通过一个函数计算,映射到表中的一个位置来访问记录,这加快了查找速度。这个映射
称为散列函数,存放记录的数组为散列表。null和undefined
- undefined:js数据类型之一,undeclared是js的一种语法错误类型。
JS宿主对象和原生对象
- 宿主对象:COM=DOM and BOM ,C++写的对象;原生对象:Object,Function,Array,String,Boolean,Number
Date,RegExp,Error,Math,Promise等。
数组去重
`
//方法一,遍历数组法
function beUnique(arrs){
var newArr = [];//临时数组
arrs.forEach(function(arr){
if(newArr.indexOf(arr)===-1){
newArr.push(arr);
}
});//forEach便利对于伪数组处理效果更好,for循环则把伪数组的空元素处理成undefined
return newArr;
}
//笨方法,排序+对比前后是否相等
function beUnique(arrs){
arrs.sort();
var newArr=[];
//forEach||for-in便利失效
for(var i,i=0;i<arrs.length;i++ ){
if(arrs[i+1]==arrs[i]){
newArr.push(arrs[i]);
}
}
return newArr;
}
//ES6语法糖
Array.from(new Set(arr));
//对象键值对法
function unique2(array){
var n = {}, r = [], len = array.length, val, type;
for (var i = 0; i < array.length; i++) {
val = array[i];
type = typeof val;
if (!n[val]) {
n[val] = [type];
r.push(val);
} else if (n[val].indexOf(type) < 0) {
n[val].push(type);
r.push(val);
}
}
return r;
//结合call/apply,效率更高
function unique1() {
var newArray = [];
this.forEach(function (index) {
if (newArray.indexOf(index) == -1) {
newArray.push(index); } });
return newArray;
}
unique1.apply(arr);
//对象键值对法
Array.prototype.unique3 = function () {
// 构建一个新数组存放结果
var newArray = [];
// 创建一个空对象
var object = {}; // for循环时,每次取出一个元素与对象进行对比
// 如果这个元素不重复,则将它存放到结果数中
// 同时把这个元素的内容作为对象的一个属性,并赋值为1,
// 存入到第2步建立的对象中
for (var i = 0; i < this.length; i++){
// 检测在object对象中是否包含遍历到的元素的值
if(!object[typeof(this[i]) + this[i]]) {
// 如果不包含,将存入对象的元素的值推入到结果数组中
newArray.push(this[i]);
// 如果不包含,存入object对象中该属性名的值设置为1
object[typeof(this[i]) + this[i]] = 1;
} }
return newArray;
}
`
数组求和
var arr=[1,2,3,4]; var sum=0; //forEach arr.forEach(function(item){ sum+=item; }); //map arr.map(function(item){ sum+=item }); //reduce arr.reduce(function(pre,cur){ return pre+cur })
eval
把对应的字符串解析成JS代码并运行;
应该避免使用eval------不安全,非常耗性能(2次,一次解析成js语句,一次执行)。
由JSON字符串转换为JSON对象的时候可以用eval,var obj =eval(‘(‘+ str +’)’)。
DOM怎样添加、移除、移动、复制、创建和查找节点
- 创建新节点
- 创建一个DOM片段 createDocumentFragment()
- 创建一个具体的元素 createElement()
- 创建一个文本节点createTextNode()
- 添加、移除、替换、插入 appendChild() removeChild() replaceChild() insertBefore()
- 在已有的子节点前插入一个新的子节点:???
- 查找
- 通过标签名称 : getElementsByTagName()
- 通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的) :getElementsByName()
- 通过元素Id,唯一性:getElementById()
null和undefined的区别?
null是一个表示”无”的对象,转为数值时为0;
undefined是一个表示”无”的原始值,转为数值时为NaN。
undefined:
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。
null:
(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。
new操作符具体干了什么呢?
(1)创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
(2)属性和方法被加入到 this 引用的对象中。
(3)新创建的对象由 this 所引用,并且最后隐式的返回 this 。
JSON 的了解?
JSON(JavaScript Object Notation) 是一种
轻量级的数据交换格式
它是基于JavaScript的一个子集。数据格式简单, 易于读写, 占用带宽小。 格式:采用键值对,例如:{‘age’:’12’, ‘name’:’back’}
call() 和 apply() 的区别和作用?
apply()函数有两个参数:第一个参数是上下文,第二个参数是参数组成的数组。
如果上下文是null,则使用全局对象代替。 如:function.apply(this,[1,2,3]);
call()的第一个参数是上下文,后续是实例传入的参数序列。 如:function.call(this,1,2,3);
第三部分:其他
1.HTTP状态码知道哪些?
state code | describe | mark |
---|---|---|
100 | Continue | 一般在发送post请求时已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息 |
200 | OK | 正常返回信息 |
201 | Created | 请求成功并且服务器创建了新的资源 |
202 | Accepted | 服务器已接受请求,但尚未处理 301 Moved Permanently 请求的网页已永久移动到新位置。 |
302 | Found | 临时性重定向 |
303 | See Other | 临时性重定向,且总是使用 GET 请求新的 URI。 |
304 | Not Modified | 自从上次请求后,请求的网页未修改过。 |
400 | Bad Request | 服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。 |
401 | Unauthorized | 请求未授权。 |
403 | Forbidden | 禁止访问 |
404 | Not Found | 找不到如何与 URI 相匹配的资源。 |
500 | Internal Server Error | 最常见的服务器端错误 |
503 | Service Unavailable | 服务器端暂时无法处理请求(可能是过载或维护) |
2. 性能优化
- 减少http请求次数:CSS Sprites, JS、CSS源码压缩、图片大小控制合适;
网页Gzip,CDN托管,data缓存 ,图片服务器。 - 前端模板 :JS+数据,减少由于HTML标签导致的带宽浪费,前端用变量保存AJAX请求结果,
每次操作本地变量,不用请求,减少请求次数 - 用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能。
- 当需要设置的样式很多时设置className而不是直接操作style。
- 少用全局变量、缓存DOM节点查找的结果。减少IO读取操作。
- 避免使用CSS Expression(css表达式)又称Dynamic properties(动态属性)。
- 图片预加载,将样式表放在顶部,将脚本放在底部 加上时间戳。
3. 优雅降级和渐进增强
- 优雅降级
Web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,
则代码会检查以确认它们是否能正常工作。由于IE独特的盒模型布局问题,
针对不同版本的IE的hack实践过优雅降级了,为那些无法支持功能的浏览器增加候选方案,
使之在旧式浏览器上以某种形式降级体验却不至于完全失效。 -
渐进增强
从被所有浏览器支持的基本功能开始,逐步地添加那些只有新式浏览器才支持的功能,
向页面增加无害于基础浏览器的额外样式和功能的。当浏览器支持时,它们会自动地呈现出来并发挥作用。 - 内存泄漏
内存泄漏:任何对象在您不再拥有或需要它之后仍然存在。
垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。
如果一个对象的引用计数为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,
那么该对象的内存即可回收。
setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)。
- 线程与进程的区别
一个程序至少有一个进程,一个进程至少有一个线程。 线程的划分尺度小于进程,使得多线程程序的并发性高。 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
共同学习,写下你的评论
评论加载中...
作者其他优质文章