1. DOCTYPE 作用,标准模式与兼容模式(怪异模式)的区别?
声明位于位于HTML文档中的第一行,处于 标签之前。告知浏览器的解析器用什么文档标准解析这个文档。DOCTYPE不存在或格式不正确会导致文档以兼容模式呈现。
标准模式的排版 和JS运作模式都是以该浏览器支持的最高标准运行。在兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作。
2. HTML5 为什么只需要写 ?
HTML5 不基于 SGML,因此不需要对DTD进行引用,但是需要doctype来规范浏览器的行为(让浏览器按照它们应该的方式来运行)。
而HTML4.01基于SGML,所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型。
SGML是标准通用标记语言,简单的说,就是比HTML,XML更老的标准,这两者都是由SGML发展而来的。但是,HTML5不是的。
DTD:文档类型定义(Document Type Definition)
3. 行内元素有哪些?块级元素有哪些? 空(void)元素有那些?
(1)行内元素:a span img input select textarea button label
(2)块级元素:div ul ol li dl dt dd h1~h6 p pre form table tr td th thead tbody tfoot
(3)常见的空元素:br hr img input link meta
dl定义一个列表,dt定义标题,dd定义内容
4. 页面导入样式时,使用link和@import有什么区别?
(1)link属于XHTML标签,除了加载CSS外,还能用于定义RSS, 定义rel连接属性等作用;而@import是CSS提供的,只能用于加载CSS;
(2)页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载;
(3)import是CSS2.1 提出的,只在IE5以上才能被识别,而link是XHTML标签,无兼容问题;
(4)link支持使用js控制DOM去改变样式,而@import不支持;
通过文档对象获取所有样式表对象:
document.styleSheets
通过元素获取样式表对象:
IE: element.styleSheet
非IE: element.sheet
操作样式表中的样式:
获取样式表对象: var sheet = document.styleSheets[0]
获取规则列表: var rules = sheet.cssRules || sheet.rules //IE使用sheet.rules
获取第一条规则: var rule = rules[0]
获取样式: var style = rule.style
修改样式: style.backgroundColor = ‘red’
5. 浏览器内核的理解?
主要分成两部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎。
渲染引擎:负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入CSS等),以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。
JS引擎则:解析和执行javascript来实现网页的动态效果。
最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎。
6. 常见的浏览器内核有哪些?
Trident内核:IE,MaxThon,TT,The World,360,搜狗浏览器等。[又称MSHTML]
Gecko内核:Netscape6及以上版本,FF,MozillaSuite/SeaMonkey等
Presto内核:Opera7及以上。 [Opera内核原为:Presto,现为:Blink;]
Webkit内核:Safari,Chrome等。 [ Chrome的:Blink(WebKit的分支)]
Webkit是苹果公司基于KHTML开发的。他包括Webcore和JavaScriptCore(SquirrelFish,V8)两个引擎。
小程序内核:
在iOS 上,小程序的 javascript 代码是运行在 JavaScriptCore 中
在Android 上,小程序的 javascript 代码是通过 X5 内核来解析
在开发工具上, 小程序的 javascript 代码是运行在 nwjs(chrome内核) 中
X5内核和chrome内核都是基于webkit内核,可以认为它们是webkit内核的一个分支。
X5内核是腾讯基于优秀开源Webkit深度优化的浏览器渲染引擎,搭载在最新一代的手机QQ浏览器上,更快,更便捷。
7. html5有哪些新特性、移除了那些元素?
绘画 canvas;用于媒体播放的 video 和 audio 元素;
本地离线存储 localStorage 和sessionStorage ;
语意化的标签元素,如 article、footer、header、nav、section;
表单控件:date、time、email、url、search;
新的技术webworker, websocket, Geolocation;
移除的元素:
纯表现的元素:basefont,big,center,font, s,strike,tt,u;
对可用性产生负面影响的元素:frame,frameset,noframes;
8. 如何处理HTML5新标签的浏览器兼容问题?如何区分 HTML 和 HTML5?
(1)IE8/IE7/IE6支持通过document.createElement方法产生的标签,可以利用这一特性让这些浏览器支持HTML5新标签,浏览器支持新标签后,还需要添加标签默认的样式。
(2)可以直接使用成熟的框架、比如html5shim;
区分HTML5: DOCTYPE声明或新增的标签元素
9. 简述一下你对HTML语义化的理解?
内容结构化,结构清晰,代码容易阅读,便于维护,有利于SEO。
10. 对Web Workers的理解?
作用:解决因javascript进程的长时间执行导致用户界面的阻塞。
注意事项:
var worker = new Worker('test.js'); // 创建一个WebWorker对象
worker.onmessage = function (event) { // 处理消息
var data = event.data // 保存来自Worker的数据
self.close() // 停止工作,与terminate方法一致
}
worker.postMessage(data); // 发送消息
worker.terminate(); // 停止Worker的工作
11. 对Web Sockets的理解?
作用:实现全双工和双向通信。(全双工:数据在两个方向上传输,A -> B B -> A瞬间同步)
建立的连接会使用HTTP升级,从HTTP协议交换为Web Socket协议,即使用标准的HTTP服务器无法实现Web Socket,只有专门支持这种协议的专门服务器才能正常工作。
不受同源策略的限制。只能通过连接发送纯文本数据。因此发送的数据必须进行序列化,从服务端接受的数据也需要解析。
// 创建一个WebSocket对象
var socket = new WebSocket("ws://www.example.com/server.php");
socket.onmessage = function (event) { // 处理数据
var data = event.data
}
socket.send(JSON.stringify(message));
socket.close(); // 此时的socket.readyState = 2,关闭后值变为3。
WebSocket的状态(readyState):
事件:
open: 在成功建立连接时触发。
error: 在发生错误时触发。
close: 在连接关闭时触发。
12. HTML5的离线存储的使用以及工作原理?
在用户没有与因特网连接时,可以正常访问站点或应用,在用户与因特网连接时,更新用户机器上的缓存文件。
原理:HTML5的离线存储是基于一个新建的.appcache文件的缓存机制(不是存储技术),通过这个文件上的解析清单离线存储资源,这些资源就会像cookie一样被存储了下来。当网络处于离线状态下时,浏览器会通过被离线存储的数据进行页面展示。
// CACHE MANIFEST - 列出的文件将在首次下载后进行缓存
// NETWORK - 列出的文件需要与服务器连接,且不会被缓存
// FALLBACK - 当页面无法访问时的回退页面(比如 404 页面)
CACHE MANIFEST
#comment
CACHE:
js/app.js
css/style.css
NETWORK:
resourse/logo.png
FALLBACK:
404.html
// 使用
// 推荐使用.appcache作为文件的扩展名,也可使用.manifest。
13. 浏览器如何对HTML5的离线储存资源进行管理和加载?
在线的情况下,浏览器发现html头部有manifest属性,它会请求manifest文件,如果是第一次访问app,那么浏览器就会根据manifest文件的内容下载相应的资源并且进行离线存储。如果已经访问过app并且资源已经离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的manifest文件与旧的manifest文件,如果文件没有发生改变,就不做任何操作,如果文件改变了,那么就会重新下载文件中的资源并进行离线存储。
离线的情况下,浏览器就直接使用离线存储的资源。
14. cookies,sessionStorage 和 localStorage 的区别?
15. H5如何禁用表单的自动完成功能?
设置autocomplete属性值为off。(默认为on)
16. 如何实现浏览器内多个标签页之间的通信?
方法一: 使用localStorage。
// 页面一
// 页面二
方法二:使用cookie + setInterval。
将要传递的信息存储在cookie中,每隔一定时间读取cookie信息,即可随时获取要传递的信息。
// 页面一
// 页面二
方法三:使用WebSocket
方法四:使用SharedWorker
共享工作线程允许多个页面共享使用,每个页面都是链接到该共享工作线程的某个端口号上。页面通过该端口与共享工作线程进行通信。
SharedWorker可以被多个window共同使用,但必须保证这些标签页都是同源的(相同的协议,主机和端口号)。
17. 页面可见性(Page Visibility API) 可以有哪些用途?
API:
document.hidden: 表示当前页面可见还是不可见(boolean)。
document.visibilityState: 返回当前页面的可见状态(四种)。
即:hidden、visible、prerender(预渲染)、preview(预览)
18. 如何在页面上实现一个圆形的可点击区域?
(1)map+area或者svg。
// map + area
// svg
(2)border-radius。
(3)纯js实现:通过点击的位置判断其是否在圆上。
document.onclick=function(e){
var r=50;//圆的半径
var x1=100,y1=100,x2= e.clientX;y2= e.clientY;
//计算鼠标点的位置与圆心的距离
var len=Math.abs(Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2)));
if(len<=50){
console.log("内")
}else{
console.log("外")
}
}
19. 盒子模型的理解?
附:在调试时所看到的宽高包含了border、padding以及元素的宽高。不包含margin。
20. CSS选择符有哪些?哪些属性可以继承?
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。
css选择器学习地址:http://www.runoob.com/cssref/css-selectors.html
21. 实现div元素的垂直水平居中
// 方法一
div {
position: absolute;
top: 0;
left: 0;
right:0;
bottom: 0;
width: 200px;
height: 200px;
margin: auto;
}
// 方法二
div {
position: absolute;
left: 50%;
top: 50%;
margin-left: -100px;
margin-top: -100px;
width: 200px;
height: 200px;
}
// 方法三
div {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 200px;
height: 200px;
}
// 方法四
.container {
display: flex;
}
div {
width: 200px;
height: 200px;
margin: auto;
}
// 方法五
.container {
display: flex;
justify-content: center;
align-items: center;
}
div {
width: 200px;
height: 200px;
}
22. position定位
23. 用CSS创建一个三角形的原理?
把上、左、右三条边隐藏掉(颜色设为 transparent)
#demo {
width: 0;
height: 0;
border-width: 20px;
border-style: solid;
border-color: transparent transparent red transparent;
}
24. 满屏的"品"字布局设计?
附: html、body元素均为块级元素(display:block)。
head、style、meta元素表现为display: none。
li元素表现为display: list-item(作为列表显示)。
25. 实现css多列等高的效果?
父元素设置overflow: hidden,子元素设置padding-bottom、margin-bottom正负相抵,此时父容器的高度为没有设定padding-bottom时的高度,当其中任一列高度增加,则父容器的高度会被撑到里面最高那列的高度,其他比这列矮的列会用padding-bottom补偿这部分高度差。
自适应高度
内容内容内容内容内容内容内容内容内容内容内容内容内容
26. CSS中
demo
产生原因: 浏览器会把inline元素间的空白字符(空格、换行、Tab等)渲染成一个空格。
解决方法:
27. img元素底部出现空白的原因及解决办法?
原因:受vertical-align的影响,元素默认的对齐方式为基线对齐,即vertical-align: baseline; 而空白的间隔即为baseline和bottom之间的距离。
解决办法:
设置line-height: 0生效的原因:line-height值为两个基线之间的距离,其值为0表明baseline和bottom之间的距离为0,故生效。而line-height的默认值为normal,一般认为其值为1或1.2,受font-size的影响,因此设置font-size: 0也可生效。
vertical-align只能作用于inline以及table-cell元素。设置display: block后vertical-align失效。
28. line-height设置为数值和百分比值的区别?
数值:
根据父元素的font-size值计算line-height的值,子元素继承line-height的数值,根据自身的font-size再次计算line-height的值。
百分比值:
根据父元素的font-size值计算line-height的值,子元素继承计算后的line-height值。
行间距
行间距
29. 什么是 FOUC?你如何来避免 FOUC?
FOUC:Flash Of Unstyled Content ,无样式内容闪烁。
产生原因: 使用@import导入css文件。
页面加载时会加载DOM,最后再导入引入的css文件,导致页面的内容一段时间可能没有样式。
解决方法: 使用 link 标签引入css文件。
30. css包含块的理解?
包含块(Containing Block)与框模型类似,可以理解为一个矩形,这个矩形的作用是为它里面包含的元素提供一个参考,元素的尺寸和位置的计算往往是由该元素所在的包含块决定的。
包含块简单说就是定位参考框,或者定位坐标参考系,元素一旦定义了定位显示(相对、绝对、固定)都具有包含块性质,它所包含的定位元素都将以该包含块为坐标系进行定位和调整。
包含块的定义:
(1) 祖先是块级元素,containing block 由祖先的 padding edge(padding+content区域) 形成。
(2) 祖先是内联元素,containing block 取决于祖先的 direction 属性。
①direction 是 ltr,祖先产生的第一个盒子的上、左内容边界是 containing block 的上方和左方,祖先的最后一个盒子的下、右内容边界是 containing block 的下方和右方。
②direction 是 rtl,祖先产生的第一个盒子的上、右内容边界是 containing block 的上方和右方,祖先的最后一个盒子的下、左内容边界是 containing block 的下方和左方。
(3) 没有祖先,根元素盒子的内容边界为containing block。
31. visibility: collapse的作用?
当在表格元素中使用时,可删除一行或一列,表现形式等同于display: none;如果用在其他的元素上则表现为visibility: hidden。
32. position、float、display特性的相互作用?
33. 对 BFC 和 IFC 的理解?
BFC用法见:https://segmentfault.com/a/1190000009545742
BFC:决定一个元素如何定位以及与其它元素之间的相互作用。
形成BFC的条件:
BFC布局规则:
IFC布局规则:
34. 为什么需要清除浮动以及清除浮动的方式?
浮动的元素会导致父元素高度塌陷,影响后面的布局。
清除浮动的方法:
.clearfix::after,.clearfix::before{
content: "";
height:0;
line-height: 0;
display: block;
visibility: hidden;
clear: both;
}
35. 什么是外边距合并?
两个垂直外边距相遇时会合并成一个外边距,合并后的外边距的高度等于两个外边距高度中的最大者。
36. 对zoom: 1的理解?
zoom可以用来解决IE下外边距重叠,清除浮动,触发ie的haslayout属性。
zoom的值用来表示当前元素扩大或缩小多少,设置后会使当前元素重新计算高度和宽度。
37. 媒体查询的了解?
@media 可以针对不同的屏幕尺寸设置不同的样式,用于设计响应式页面。
附:@media中的 max-width 和 min-width 的区别:
max-width 表明页面的 width <= max-width 时生效,min-width 表示页面的 width >= min-width 时生效。
38. css匹配规则?
从上到下,从右到左。
从右到左的优势:如果是从左到右,会一个节点一个节点的往下找,没有找到需要回溯到上一个节点,损失性能。而从右到左在开始时就会过滤到许多节点,更加的高效。
39. CSS 优化、提高性能的方法?
(1) 将样式写在单独的css文件中。
优点:
1. 内容和样式分离,便于管理和维护。
2. 减少页面体积。
3. css文件可以被缓存。
(2) 不使用@import。
(3) 选择器层级越少越好。
简洁的选择器可以减少css文件大小,提高页面的加载性能,浏览器解析时更加高效。
(4) 精简页面的样式文件,去掉不用的样式。
(5) 利用CSS继承减少代码量。
40. 浏览器是怎样解析CSS选择器的?
从上到下,从右到左
从右到左的优势:如果是从左到右,从当前节点一个一个向下找,如果没找到则需要回溯,损失性能。而从右到左则只需向上寻找,过滤了很多节点,提升了性能。
41. 如何使Chrome支持小于12px 的文字?
font-size : 12px;
-webkit-transform : scale(0.84,0.84) ;
*font-size:10px; // IE
// IE 和 Firefox允许设置的字体小于12px
42. IOS下设置overflow: scroll时滑动卡顿?
// 设置
-webkit-overflow-scrolling: touch; // 启用了硬件加速特性,所以滑动很流畅
43. 高度自适应的div中有两个div,一个高度200px,希望另一个填满剩下的高度?
方法一:使用flex布局
.container {
background-color: silver;
width: 400px;
height: 600px;
display: flex;
flex-direction: column;
// 实际上使得flex在纵向起作用,若div1设置flex: 2, div2设置flex: 1,则div1占高度的2/3,div2占高度的1/3。
}
.container div:nth-of-type(1) {
width: 200px;
height: 200px;
background-color: red;
}
.container div:nth-of-type(2) {
width: 200px;
flex: 1;
background-color: pink;
}
方法二:使用calc函数
.container {
background-color: silver;
width: 400px;
height: 600px;
}
.container div:nth-of-type(1) {
width: 200px;
height: 200px;
background-color: red;
}
.container div:nth-of-type(2) {
width: 200px;
height: calc(100% - 200px);
background-color: pink;
}
方法三:使用绝对定位
.container {
position: relative;
background-color: silver;
width: 400px;
height: 600px;
}
.container div:nth-of-type(1) {
width: 200px;
height: 200px;
background-color: red;
}
.container div:nth-of-type(2) {
position: absolute;
top: 200px;
bottom: 0;
width: 200px;
background-color: pink;
}
44. js有哪些内置对象?
数据封装类对象:Object、Array、Boolean、Number 和 String
其他对象:Function、Arguments、Math、Date、RegExp、Error
45. 原型和原型链?
每个对象内部都有一个属性,即prototype属性,称为原型属性,当我们访问一个对象的属性时,如果对象内部没有这个属性,那么他会去它的原型上找这个属性,这个原型内部又有自己的prototype属性,如果没找到就会一直找下去,构成一个原型链。
var obj = new Object();
obj.__proto__ // obj对象的原型
obj.__proto__ === Object.prototype // true
Object.prototype.constructor === Object // true
Object.prototype对于Object来说是它的原型属性,而对于创建的实例来说是它的原型对象,其内部封装了许多属性和方法,为创建的所有实例所共享。
46. Javascript作用域链?
在当前作用域访问某个变量或方法时,如果当前作用域没有,则会去它的上层作用域中寻找,直至全局作用域,形成作用域链。
47. this的理解?
this总是指向函数的调用者,this不是在函数定义时确定的,而是在函数执行的时候确定的。
在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this是指向全局对象Window。
48. eval函数的理解?
参数:接受一个字符串,如果不是直接返回,不做处理。
特点:
详细用法见:https://www.cnblogs.com/zichi/p/5202825.html
49. DOM对象和BOM对象的理解?
BOM对象的顶级对象是window对象,DOM对象的顶级对象是document对象,document对象是window对象的一个属性。
即 window.document === document
BOM对象中的navigator、location、screen、history对象均是window对象的一个属性。
50. null 和 undefined的区别?
(1) null表示一个空对象,undefined表示一个变量声明未赋值。
(2) null转化为数值时为0,undefined转化为数值为NaN。
(3) null是原型链的终点。
Object.prototype.__proto__ === null // ture
Object.getPrototypeOf(Object.prototype) === null // true
值为undefined的情况:
51. [“1”, “2”, “3”].map(parseInt) 的结果?
分析:传入parseInt相当于传入parseInt指向的函数,接受两个参数为str(字符串类型)和radix(进制),表示用指定进制解析str,如parseInt(“11”, 2)返回3。
map函数默认传入element,index,array。因此运算类似于:
parseInt("1", 0) // 1
parseInt("2", 1) // NaN
parseInt("3", 2) // NaN
运算结果为:[1, NaN, NaN]
52. 使用JS方式将两个数的值互换?
// 方法一:
var temp;
temp = x;
x = y;
y = temp;
// 方法二:
x = x + y;
y = x - y;
x = x - y;
// 方法三:(使用位运算符异或,原理:x ^ x = 0)
x = x ^ y
y = x ^ y
x = x ^ y
53. IE与火狐的事件机制有什么区别? 如何阻止冒泡?
IE8及更早版本只支持是事件冒泡,Firefox支持两种事件机制,事件捕获和事件冒泡。
阻止冒泡:
非IE:e.stopPropagation() (即能阻止事件捕获也能阻止事件冒泡)
IE:e.cancelBubble = true
附:
事件流分为三个阶段:事件捕获、目标阶段、冒泡阶段。
事件的目标阶段通过addEventListener中的第三个参数设置其在捕获阶段触发还是在冒泡阶段触发,默认为false在冒泡阶段触发。IE中的attachEvent只支持冒泡事件。
54. "use strict"的使用及优点?
“use strict”:启用严格模式。
优点:消除了代码的不安全,提高了编译器效率,提升了运行速度。
附:
with作用:将代码的作用域设置到一个特定的作用域中。
缺点:js解释器会检查with块中的变量是否属于with包含的对象,降低了with语句的执行效率。
55. 判断某个变量的类型?
使用Object.prototype.toString.call()
例:
var arr = [];
Object.prototype.toString.call(arr); // "[object Array]"
var num = 10;
Object.prototype.toString.call(num); // "[object Number]"
56. JavaScript中查找属性时,不会去原型上查找的函数是?
hasOwnProperty()
57. 解释下列代码?
[].forEach.call($$("*"),function(a){a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)})
运行效果:在Chrome浏览器的控制台中输入这段代码,会发现不同HTML层都被使用不同的颜色添加了一个高亮的边框。
$$('*') 等价于 document.querySelectorAll("*"),获取当前页面的所有元素节点,返回一个NodeList对象。
~ :按位取反:先把二进制的编码加上一位,再取反。
~~ 替代了Math.floor,运算效率更高。
详见:https://my.oschina.net/l3ve/blog/330358
58. 如何解决跨域问题?
jsonp、postMessage、 document.domain、webSocket、window.name
详见:https://blog.csdn.net/Joyhen/article/details/21631833?utm_source=blogxgwz0
59. 异步加载JS的方式?
(1) defer,只支持IE。
(2) async。
(3) 创建script,插入到DOM中,加载完毕后callBack。
function addScriptTag(src){
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function(){
addScriptTag("js/index.js");
}
60. documen.write和 innerHTML的区别?
document.write能重绘整个页面,innerHTML重绘页面的一部分。
61. innerHTML 和 innerText 的理解?
innerHTML:获取值时返回所有的子节点(包括元素、注释和文本节点)。
innerText:获取值时返回子节点中所有文本拼接后的值,会解析转义后的字符。
innerHTML:设置值时,如果为字符串直接写入,如果为HTML字符串,浏览器会将此字符串解析为相应的DOM树(会对字符转义)。因此再获取值时和设置的值有所不同:
innerText:设置值时,如果为HTML字符串,会将其转义,使用innerHTML获取的值为转义后的值,再次使用innerText获取的值即为设置的值,因为其会对转义后的字符再次转义。
div.innerHTML = "hello & world
";
console.log(div.innerHTML) // hello & world
111&
附:并不是所有的元素都支持innerHTML属性,如head,style,html就不支持。
过滤掉所有的HTML标签的方法:div.innerText = div.innerText。
62. DOM操作?
(1) 创建节点
文本节点:document.createTextNode()
元素节点:document.createElement()
文档片段:document.createDocumentFragment()
注释节点:document.createComment()
(2)添加、插入、替换、复制节点
appendChild()
insertBefore()
replaceChild()
cloneNode() // true深复制,false为浅复制,只复制节点本身
(3)获取元素节点
document.getElementById()
document.getElementsByTagName()
document.getElementsByName()
document.getElementsByClassName()
document.querySelector()
document.querySelectorAll()
(4)其它属性
childNodes
parentNode
firstChild
lastChild
previousSibling
nextSibling
63. call和apply的区别?
作用:都是将函数绑定到另一个对象上运行。
区别:apply传递的是参数数组而call传递的是参数列表,即参数需要一个一个列举出来。
64. 内存泄漏可能的情况?
function fn() {
s = "hello"
}
// 等价于
function fn () {
window.s = "hello"
}
// 解决办法:启用严格模式,"use strict";
65. JavaScript实现千位分隔符?
function commafy(num) {
return num && num
.toString()
.replace(/(\d)(?=(\d{3})+\.)/g, function($0, $1) {
return $1 + ",";
});
}
console.log(commafy(1234567.90)); //1,234,567.90
66. 如何检测浏览器版本?
使用navigator.userAgent
67. What is a Polyfill?
兼容旧版浏览器,检查浏览器是否支持某个标准 API,如果不支持,就使用旧的技术对浏览器做兼容处理,使新标准的 API能够在旧的浏览器上使用。
68. IE 与其他浏览器不一样的特性?
// 兼容性写法:
// 阻止默认行为
if (event && event.preventDefault) {
event.preventDefault();
} else {
window.event.returnValue = false;
}
// 阻止事件冒泡
if (event && event.stopPropggation) {
event.stopPropagation();
} else {
window.event.cancelBubble = true;
}
69. 前端性能优化的方法?
70. 什么是置换元素?
置换元素:浏览器根据元素的标签和属性来决定元素显示的内容,一般来说,置换元素都是空元素,如input、textarea、select、img。
71. 浏览器线程有哪些?
GUI渲染线程与JavaScript引擎为互斥的关系,当JavaScript引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到引擎线程空闲时立即被执行。
详见:http://www.imweb.io/topic/58e3bfa845e5c13468f567d5
72. 待续。。。?
React部分:
1. 调用this.setState做了什么?
React中的setState有两种模式,分别是普通模式和批量更新模式,普通模式下,当调用setState时React会将setState中的对象与当前组件的状态合并,重新构建虚拟DOM并将当前的DOM树和上一次的DOM树进行对比,通过diff算法计算出相应的更新策略,然后只更新变化的那部分。批量更新模式则是先把setState中的对象存入一个更新队列中,稍后会将队列中新的状态合并到state中,再重新触发render。
附:调用setState时一定会触发重新渲染,即使新的state和旧的state相同,此时如果不希望重新渲染可以通过shouldComponentUpdate(nextProps, nextState)控制,return true表示重新渲染,return false表示不渲染,并且必须有return语句。
2. React中元素和组件的区别?
元素:React元素不是真实的DOM元素,只是普通的JS对象。
// React元素
const element = I'm element
组件:React组件是由元素构成的,组件可能是个类也可能是个函数。
3. React中什么时候使用类组件,什么时候使用函数式组件?
组件具有状态( state )或生命周期方法时使用类组件。否则,使用函数式组件。
附:函数式组件只有props,没有state,有state的称为有状态组件,无state称为无状态组件。状态会带来管理的复杂性,所以应尽量多写无状态组件,少写有状态组件,即多使用函数式组件。
4. refs的理解?
可以refs来直接访问DOM元素或组件实例。
import React from 'react'
export default class Input extends React.Component {
constructor(props) {
super(props);
this.focusTextInput = this.focusTextInput.bind(this);
}
focusTextInput() {
this.input.focus();
}
render() {
return (
this.input = input} />
);
}
}
5. React的受控组件和非受控组件的区别?
6. 哪些生命周期函数中不能调用setState?
附:componentDidUpdate中调用setState需要加判断条件,否则也会造成死循环。
7. React应该在哪个生命周期中请求数据?
应该在componentDidMount中请求数据,不提倡在componentWillMount中请求数据,原因:未来的React可能为了提高性能多次触发componentWillMount,这样就会使得数据请求多次。
附:在componentWillMount中直接调用this.setState并不会重新触发render,而是将当前的setState中的对象与组件状态合并,只会触发一个render方法。而不是先触发一个render,调用setState再触发一次render。如果想要再次触发render,可以将setState置于setTimeout中。
只有在render和componentDidUpdate中才能获取到更新后的state。
8. 组件更新时生命周期函数的调用顺序?
componentWillReceiveProps -> shouldComponentUpdate -> componentWillUpdate -> render -> componentDidUpdate
即:组件收到新的props(props中的数据并不一定真正发生变化)-> 决定是否需要继续执行更新过程 -> 组件代表的虚拟DOM即将更新 -> 组件重新计算出新的虚拟DOM -> 虚拟DOM对应的真实DOM更新到真实DOM树中。
9. render次数和浏览器界面更新次数一致吗?
不一致,如下:
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
bgColor: "red"
}
}
render() {
var {bgColor} = this.state
return (
Test
);
}
componentDidMount() {
this.setState({
bgColor: "yellow"
})
}
}
浏览器渲染页面时并不会从红色变为黄色,而是直接显示为黄色。
原因:虽然render方法被调用了两次,但这并不会导致浏览器界面更新两次,实际上,两次DOM的修改会合并成一次浏览器界面的更新。虽然JS的执行和DOM的渲染分别由浏览器不同的线程完成,但JS的执行会阻塞DOM的渲染,而上面的两次render是在一个JS事件周期内执行的,所以在两次render结束前,浏览器不会更新界面。
10. 为什么要使用 React.Children.map(props.children,() => {} ) 而不是 props.children.map( () => {} )?
原因:props.children时返回的可能是一个对象(只有一个子元素)也可能是一个数组(有多个子元素)。如果返回的是一个对象调用map方法时就会报错。
11. react性能优化是哪个周期函数?
shouldComponentUpdate 这个方法用来判断是否需要调用render方法重新描绘dom。因为dom的描绘非常消耗性能。
12. diff算法的理解?
把树形结构按照层级分解,只比较同级元素。
给列表结构的每个单元添加唯一的key属性,方便比较。
React 只会匹配相同 class 的 component(这里面的class指的是组件的名字)。
合并操作,调用 component 的 setState 方法的时候,React 将其标记为 dirty.到每一个事件循环结束, React 检查所有标记 dirty 的 component 重新绘制。
附:React的diff算法复杂度由 O(n^3) 变为 O(n) 。
React的diff算法给树进行编号,只需要比较同一级的,故复杂度为O(n)。
传统的diff算法:需要将两个树的节点,两两比较,这就有n*n的复杂度了。 然后还需要编辑树,编辑的树可能发生在任何节点,需要对树进行再一次遍历操作,因此复杂度为n。加起来就是n^3了。
13. React性能优化?
(1)重写shouldComponentUpdate来避免不必要的dom操作。
(2)使用 production 版本的react.js。
(3)使用key来帮助React识别列表中所有子组件的最小变化。
(4)给函数绑定this时在constructor构造函数中绑定,不要在React元素或组件上绑定this。
class App extends React.Component {
constructor(props) {
super(props)
this.handleClick = this.handleClick.bind(this)
}
handleClick () {
...
}
render () {
return (
{/* 此处的this.handleClick()的括号不能省略*/}
)
}
}
// 第一种,构造函数每一次渲染的时候只会执行一遍;
// 第二种,在每次render()的时候都会重新执行一遍函数;
// 第三种,每一次render()的时候,都会生成一个新的箭头函数,即使两个箭头函数的内容是一样的。
14. 待续。。。?