共计 13560 个字符,预计需要花费 34 分钟才能阅读完成。
如需获取完整版 229 页 PDF 面试题,请间接滑到文末。
1. 如何确定 this 指向
如果要判断一个运行中函数的 this 绑定,就须要找到这个函数的间接调用地位。找到之后就能够程序利用上面这四条规定来判断 this 的绑定对象。
- 由 new 调用?绑定到新创建的对象。
- 由 call 或者 apply(或者 bind)调用?绑定到指定的对象。
- 由上下文对象调用?绑定到那个上下文对象。
- 默认:在严格模式下绑定到 undefined,否则绑定到全局对象。
肯定要留神,有些调用可能在无心中应用默认绑定规定。如果想“更平安”地疏忽 this 绑定,你能够应用一个 DMZ 对象,比方 ø = Object.create(null),以爱护全局对象。
ES6 中的箭头函数并不会应用四条规范的绑定规定,而是依据以后的词法作用域来决定 this,具体来说,箭头函数会继承外层函数调用的 this 绑定(无论 this 绑定到什么)。这其实和 ES6 之前代码中的 self = this 机制一样
参考资料:
- 你不晓得的 JavaScript
2.== 和 === 的区别是什么
==
是形象相等运算符,而 ===
是严格相等运算符。==
运算符是在进行必要的类型转换后,再比拟。===
运算符不会进行类型转换,所以如果两个值不是雷同的类型,会间接返回 false
。应用==
时,可能产生一些特地的事件,例如:
1 == '1'; // true
1 == [1]; // true
1 == true; // true
0 == ''; // true
0 == '0'; // true
0 == false; // true
如果你对 ==
和===
的概念不是特地理解,倡议大多数状况下应用===
3. 箭头函数和一般函数有什么区别
- 函数体内的
this
对象,就是定义时所在的对象,而不是应用时所在的对象,用call
apply
bind
也不能扭转this
指向 - 不能够当作构造函数,也就是说,不能够应用
new
命令,否则会抛出一个谬误。 - 不能够应用
arguments
对象,该对象在函数体内不存在。如果要用,能够用rest
参数代替。 - 不能够应用
yield
命令,因而箭头函数不能用作Generator
函数。 - 箭头函数没有原型对象
prototype
4. 白屏工夫
白屏工夫是指浏览器从输出网址,到浏览器开始显示内容的工夫。
Performance 接口能够获取到以后页面中与性能相干的信息, 该类型的对象能够通过调用只读属性 Window.performance
来取得。
performance.timing.navigationStart
是一个返回代表一个时刻的 unsigned long long 型只读属性,为紧接着在雷同的浏览环境下卸载前一个文档完结之时的 Unix 毫秒工夫戳。如果没有上一个文档,则它的值相当于 PerformanceTiming.fetchStart。
所以将以下脚本放在 </head>
后面就能获取白屏工夫。
<script>
new Date() - performance.timing.navigationStart
</script>
参考资料:
- PerformanceTiming.navigationStart
5. 当你在浏览器输出一个地址后产生了什么
当···时产生了什么?
6. 页面大量图片,如何优化加载,优化用户体验
- 图片懒加载。在页面的未可视区域增加一个滚动事件,判断图片地位与浏览器顶端的间隔与页面的间隔,如果前者小于后者,优先加载。
- 如果为幻灯片、相册等,能够应用图片预加载技术,将以后展现图片的前一张和后一张优先下载。
- 如果图片为 css 图片,能够应用 CSSsprite,SVGsprite 等技术。
- 如果图片过大,能够应用非凡编码的图片,加载时会先加载一张压缩的特地厉害的缩略图,以进步用户体验。
- 如果图片展现区域小于图片的实在大小,应在服务器端依据业务须要先进行图片压缩,图片压缩后大小与展现统一。
7.js 网络申请性能优化之防抖与节流
防抖(debounce)
在函数须要频繁触发时,只有当有足够闲暇的工夫时,才执行一次。就如同在百度搜寻时,每次输出之后都有联想词弹出,这个控制联想词的办法就不可能是输入框内容一扭转就触发的,他肯定是当你完结输出一段时间之后才会触发。
节流(thorttle)
预约一个函数只有在大于等于执行周期时才执行,周期内调用不执行。就如同你在淘宝抢购某一件限量热卖商品时,你一直点刷新点购买,可是总有一段时间你点上是没有成果,这里就用到了节流,就是怕点的太快导致系统呈现 bug。
区别
在产生继续触发事件时,防抖设置事件提早并在闲暇工夫去触发事件,而节流则是隔肯定的工夫触发一次。
一个简略的防抖示例
let timer
input.on('input', () => {clearTimeout(timer)
// 进行输出 500 毫秒后开始搜寻
timer = setTimeout(() => {// 搜寻}, 500)
})
一个简略的节流示例
let isClick = false
button.on('click', () => {if (isClick) return
isClick = true
// 其余代码。。。// 每 10 秒只容许点击一次
setTimeout(() => {isClick = false}, 10000)
})
参考资料:
- js 网络申请性能优化之防抖与节流
8. 如何做到批改 url 参数页面不刷新
HTML5 引入了 history.pushState()
和 history.replaceState()
办法,它们别离能够增加和批改历史记录条目。
let stateObj = {foo: "bar",};
history.pushState(stateObj, "page 2", "bar.html");
复制代码
假如以后页面为 foo.html
,执行上述代码后会变为 bar.html
,点击浏览器后退,会变为 foo.html
,但浏览器并不会刷新。pushState()
须要三个参数: 一个状态对象, 一个题目 (目前被疏忽), 和 (可选的) 一个 URL. 让咱们来解释下这三个参数具体内容:
- 状态对象 — 状态对象
state
是一个 JavaScript 对象,通过pushState ()
创立新的历史记录条目。无论什么时候用户导航到新的状态,popstate
事件就会被触发,且该事件的state
属性蕴含该历史记录条目状态对象的正本。
状态对象能够是能被序列化的任何货色。起因在于 Firefox 将状态对象保留在用户的磁盘上,以便在用户重启浏览器时应用,咱们规定了状态对象在序列化示意后有 640k 的大小限度。如果你给 pushState()
办法传了一个序列化后大于 640k 的状态对象,该办法会抛出异样。如果你须要更大的空间,倡议应用 sessionStorage
以及 localStorage
.
- 题目 — Firefox 目前疏忽这个参数,但将来可能会用到。传递一个空字符串在这里是平安的,而在未来这是不平安的。二选一的话,你能够为跳转的
state
传递一个短题目。 - URL — 该参数定义了新的历史 URL 记录。留神,调用
pushState()
后浏览器并不会立刻加载这个 URL,但可能会在稍后某些状况下加载这个 URL,比方在用户从新关上浏览器时。新 URL 不必须为绝对路径。如果新 URL 是相对路径,那么它将被作为绝对于以后 URL 解决。新 URL 必须与以后 URL 同源,否则pushState()
会抛出一个异样。该参数是可选的,缺省为以后 URL。
参考资料:
- History API
9. 请用 js 去除字符串空格
去除所有空格
str.replace(/\s/g, '')
去除两边空格
str.replace(/^\s+|\s+$/g, '')
// 原生办法
str.trim()
10. 创建对象有几种办法
- 字面量
const obj = {a: 1}
- 构造函数
function Obj(val) {this.a = val}
const obj = new Obj(1)
- Object.create
const obj = Object.create({a: 1})
11.null 和 undefined 的区别
null
示意一个对象是“没有值”的值,也就是值为“空”
undefined
示意一个变量申明了没有初始化(赋值)
undefined
和 null
在 if 语句中,都会被主动转为 false
undefined
不是一个无效的 JSON,而 null
是
undefined
的类型 (typeof) 是 undefined
null
的类型 (typeof) 是 object
Javascript 将未赋值的变量默认值设为 undefined
Javascript 从来不会将变量设为 null
。它是用来让程序员表明某个用 var 申明的变量时没有值的
12. 异步求和
要求
假如有一台本地机器,无奈做加减乘除运算,因而无奈执行 a + b、a+ = 1 这样的 JS 代码,而后咱们提供一个服务器端的 HTTP API,能够传两个数字类型的参数,响应后果是这两个参数的和,这个 HTTP API 的 JS SDK(在本地机器上运行)的应用办法如下:
asyncAdd(3, 5, (err, result) => {console.log(result); // 8
});
模仿实现:
function asyncAdd(a, b, cb) {setTimeout(() => {cb(null, a + b);
}, Math.floor(Math.random()*100))
}
当初要求在本地机器上实现一个 sum 函数,反对以下用法:
(async () => {const result1 = await sum(1, 4, 6, 9, 1, 4);
const result2 = await sum(3, 4, 9, 2, 5, 3, 2, 1, 7);
const result3 = await sum(1, 6, 0, 5);
console.log([result1, result2, result3]); // [25, 36, 12]
})();
要求 sum 能在最短的工夫里返回以上后果
实现
function asyncAdd(a, b, cb) {setTimeout(() => {cb(null, a + b);
}, Math.floor(Math.random()*100))
}
function sum(...args) {const result = []
function _sum(resolve, reject) {new Promise((r, j) => {let a = args.pop()
let b = args.pop()
a = a !== undefined? a : 0
b = b !== undefined? b : 0 // 如果拜访的元素超出了数组范畴,则转为 0
asyncAdd(a, b, (err, res) => {if (err) j(err)
r(res)
})
if (args.length) {_sum(resolve, reject)
}
})
.then(val => {result.push(val)
setTimeout(() => {if (args.length <= 0) {resolve(sum(...result))
}
}, 100)
})
}
return new Promise((resolve, reject) => {if (!args || !args.length) resolve(0)
if (args.length == 1) resolve(args[0])
_sum(resolve, reject)
})
}
(async () => {const result1 = await sum(1, 4, 6, 9, 1, 4)
const result2 = await sum(3, 4, 9, 2, 5, 3, 2, 1, 7)
const result3 = await sum(1, 6, 0, 5)
console.log([result1, result2, result3]) // [25, 36, 12]
})()
13.CommonJS,ES module 是什么,有什么区别?
它们都是一种模块标准,例如 Node 应用的就是 CommonJS 标准。ES module 则是语言规范上的模块标准。
区别:
- CommonJS 模块应用
require()
和module.exports
,ES6 模块应用import
和export
。 - CommonJS 模块输入的是一个值的浅拷贝,ES6 模块输入的是值的援用。
- CommonJS 模块是运行时加载,ES6 模块是编译时输入接口。
- CommonJS 模块的
require()
是同步加载模块,ES6 模块的import
命令是异步加载,有一个独立的模块依赖的解析阶段。 - ES6 模块之中,顶层的 this 指向 undefined;CommonJS 模块的顶层 this 指向以后模块,
- 对于循环加载的解决办法不同
第 3 个差别是因为 CommonJS 加载的是一个对象(即 module.exports
属性),该对象只有在脚本运行完才会生成。
而 ES6 模块不是对象,它的对外接口只是一种动态定义,在代码动态解析阶段就会生成。
参考资料:
- Module 的加载实现
14.preload 和 prefetch
preload
preload
是 <link>
标签 rel
属性的属性值,同时须要配合 as
属性应用。
as
指定将要预加载的内容的类型,使得浏览器可能:
- 更准确地优化资源加载优先级。
- 匹配将来的加载需要,在适当的状况下,反复利用同一资源。
- 为资源利用正确的内容安全策略。
- 为资源设置正确的 Accept 申请头。
看一下这个示例:
<link rel="preload" href="https://cdn.jsdelivr.net/npm/vue/dist/vue.js" as="script">
这种做法将把 <link>
标签塞入一个预加载器中。
这个预加载器在不阻塞页面 onload 事件的状况下,去加载资源。
咱们能够通过以下两个示例来作一个比照:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
console.time('load')
</script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/2.1.10/chart/bar.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
</head>
<body>
<script>
window.onload = () => {console.timeEnd('load') // load: 1449.759033203125ms
}
</script>
</body>
</html>
下面这个示例从加载到触发 onload 事件须要大略 1400 ms 的工夫。再看一下应用 preload 预加载的工夫:
<link rel="preload" href="https://cdn.jsdelivr.net/npm/vue/dist/vue.js" as="script">
<link rel="preload" href="https://cdn.bootcdn.net/ajax/libs/echarts/2.1.10/chart/bar.js" as="script">
<link rel="preload" href="https://unpkg.com/element-ui/lib/index.js" as="script">
<link rel="preload" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" as="style">
window.onload = () => {console.timeEnd('load') // load: 10.8818359375ms
}
用 preload 来加载资源,只须要 10 ms 就触发了 onload 事件。
阐明同样是下载文件,应用 preload 不会阻塞 onload 事件。
prefetch
prefetch
和 preload
不同,应用 prefetch
属性指定的资源将在浏览器闲暇工夫下下载。
在资源的申请头如果发现有上面这个属性,就代表它是通过 prefetch
加载的:
purpose: prefetch
另外,闲暇工夫是如何确定、如何获取的,目前还没有相干 API。
15.preload 和 defer 的区别
preload 和 defer 的相同点是异步下载。那它们的不同点是什么呢?
preload 下载的资源只有在遇到同样的 script 标签时,才会执行对应的脚本。例如上面预加载的 vue.js
:
<link rel="preload" as="script" href="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">
只有在遇到上面的标签时,才会执行加载的 vue.js
:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
defer 则是异步下载资源,在所有元素解析实现后,触发 DOMContentLoaded 事件前执行。
16.window.onload 和 DOMContentLoaded 的区别
当整个页面及所有依赖资源如样式表和图片都已实现加载时,将触发 load 事件。
它与 DOMContentLoaded 不同,当纯 HTML 被齐全加载以及解析时,DOMContentLoaded 事件会被触发,而不用期待样式表,图片或者子框架实现加载。
- load
- DOMContentLoaded 事件
17.Object 与 Map 的区别
- Object 只能抉择字符、数值、符号作为 key,Map 则能够应用任何类型的数据作为 key。
- Map 实例会保护键值对的插入程序,因而能够依据插入程序执行迭代操作。Chrome Opera 中应用 for-in 语句遍历 Object 属性时会遵循一个法则:它们会先提取所有 key 的 parseFloat 值为非负整数的属性,而后依据数字程序对属性排序首先遍历进去,而后依照对象定义的程序遍历余下的所有属性。其它浏览器则齐全依照对象定义的程序遍历属性。
抉择 Object 还是 Map
对于少数 Web 开发工作来说,抉择 Object 还是 Map 只是集体偏好问题,影响不大。不过,对于在乎内存和性能的开发者来说,对象和映射之间的确存在显著的差异。
1. 内存占用
Object 和 Map 的工程级实现在不同浏览器间存在显著差别,但存储单个键 / 值对所占用的内存数量都会随键的数量线性减少。批量增加或删除键 / 值对则取决于各浏览器对该类型内存调配的工程实现。
不同浏览器的状况不同,但给定固定大小的内存,Map 大概能够比 Object 多存储 50% 的键 / 值对。
2. 插入性能
向 Object 和 Map 中插入新键 / 值对的耗费大抵相当,不过插入 Map 在所有浏览器中个别会略微快一点儿。对这两个类型来说,插入速度并不会随着键 / 值对数量而线性减少。
如果代码波及大量插入操作,那么显然 Map 的性能更佳。
3. 查找速度
与插入不同,从大型 Object 和 Map 中查找键 / 值对的性能差别极小,但如果只蕴含大量键 / 值对,则 Object 有时候速度更快。在把 Object 当成数组应用的状况下(比方应用间断整数作为属性),浏览器引擎能够进行优化,在内存中应用更高效的布局。
这对 Map 来说是不可能的。对这两个类型而言,查找速度不会随着键 / 值对数量减少而线性减少。如果代码波及大量查找操作,那么某些状况下可能抉择 Object 更好一些。
4. 删除性能
应用 delete 删除 Object 属性的性能始终以来饱受诟病,目前在很多浏览器中依然如此。为此,呈现了一些伪删除对象属性的操作,包含把属性值设置为 undefined 或 null。但很多时候,这都是一 种厌恶的或不合适的折中。
而对大多数浏览器引擎来说,Map 的 delete() 操作都比插入和查找更快。如果代码波及大量删除操作,那么毫无疑问应该抉择 Map。
参考资料:
- JavaScript 高级程序设计(第 4 版)
- js 可能保障 object 属性的输入程序吗?
18. 为什么 WeakMap 和 WeakSet 的键只能应用对象?
是为了保障只有通过键对象的援用来获得值。
const m = new WeakMap()
m.set({}, 100) // 因为 {} 没有在其余中央援用,所以在垃圾回收时,这个值也会被回收。const a = {}
m.set(a, 100) // 如果应用这种形式,则不会被回收。因为 {} 有 a 变量在援用它。a = null // 将 a 置为空后,m 里的值 100 在垃圾回收时将会被回收。
如果容许原始值,那就没方法辨别初始化时应用的字符串字面量和初始化之后应用的一个相等的字符串了。
所以这句话的意思很明确:
const a = {} // 在创建对象时,调配了一块内存,并把这块内存的地址传给 a
m.set(a, 100) // 执行 set 操作时,实际上是将 a 指向的内存地址和 100 关联起来
const a = 'abc' // 因为根本数据类型在传递时,传递的是值,而不是援用。m.set(a, 100) // 所以执行 set 操作时,实际上是将新的 'abc' 和 100 关联起来,而不是原来 a 变量指向的那个。// 那这样就会有问题,m 里存储的永远是没有被援用的键,随时都会被回收。
参考资料:
- JavaScript 高级程序设计(第 4 版)
HTML
19.HTML5 语义化
什么是语义化?就是用正当、正确的标签来展现内容,比方 h1~h6 定义题目。
益处
- 易于用户浏览,款式失落的时候能让页面出现清晰的构造。
- 有利于 SEO,搜索引擎依据标签来确定上下文和各个关键字的权重。
- 不便其余设施解析,如盲人阅读器依据语义渲染网页
- 有利于开发和保护,语义化更具可读性,代码更好保护,与 CSS3 关系更谐和。
20. 为什么最好把 CSS 的 <link>
标签放在 <head></head>
之间?为什么最好把 JS 的 <script>
标签恰好放在 </body>
之前,有例外情况吗?
把 <link>
放在 <head>
中
这种做法能够让页面逐渐出现,进步了用户体验。将样式表放在文档底部左近,会使许多浏览器(包含 Internet Explorer)不能逐渐出现页面。一些浏览器会阻止渲染,以防止在页面款式发生变化时,从新绘制页面中的元素。这种做法能够避免出现给用户空白的页面或没有款式的内容。
把 <script>
标签恰好放在 </body>
之前
脚本在下载和执行期间会阻止 HTML 解析。把 <script>
标签放在底部,保障 HTML 首先实现解析,将页面尽早出现给用户。
如果肯定要放在 <head>
中,能够让 <script>
标签应用 defer
属性。
21. 什么是渐进式渲染(progressive rendering)?
渐进式渲染是用于进步网页性能(尤其是进步用户感知的加载速度),以尽快出现页面的技术。
在以前互联网带宽较小的期间,这种技术更为广泛。现在,挪动终端的流行,而挪动网络往往不稳固,渐进式渲染在古代前端开发中依然有用武之地。
一些举例:
- 图片懒加载——页面上的图片不会一次性全副加载。当用户滚动页面到图片局部时,JavaScript 将加载并显示图像。
- 确定显示内容的优先级(分档次渲染)——为了尽快将页面出现给用户,页面只蕴含根本的最大量的 CSS、脚本和内容,而后能够应用提早加载脚本或监听
DOMContentLoaded
/load
事件加载其余资源和内容。 - 异步加载 HTML 片段——当页面通过后盾渲染时,把 HTML 拆分,通过异步申请,分块发送给浏览器。更多相干细节能够在这里找到。
22.. viewport
Viewport:字面意思为视图窗口,在挪动 web 开发中应用。示意将设施浏览器宽度虚构成一个特定的值(或计算得出),这样利于挪动 web 站点跨设施显示成果基本一致。挪动版的 Safari 浏览器最新引进了 viewport 这个 meta tag,让网页开发者来管制 viewport 的大小和缩放,其余手机浏览器也根本反对。
在挪动端浏览器当中,存在着两种视口,一种是可见视口(也就是咱们说的设施大小),另一种是视窗视口(网页的宽度是多少)。举个例子:如果咱们的屏幕是 320 像素 * 480 像素的大小(iPhone4),假如在浏览器中,320 像素的屏幕宽度可能展现 980 像素宽度的内容。那么 320 像素的宽度就是可见视口的宽度,而可能显示的 980 像素的宽度就是视窗视口的宽度。
为了显示更多的内容,大多数的浏览器会把本人的视窗视口扩充,繁难的了解,就是让本来 320 像素的屏幕宽度可能容下 980 像素甚至更宽的内容(将网页等比例放大)。
Viewport 属性值
- width 设置 layout viewport 的宽度,为一个正整数,或字符串 ”width-device”
- initial-scale 设置页面的初始缩放值,为一个数字,能够带小数
- minimum-scale 容许用户的最小缩放值,为一个数字,能够带小数
- maximum-scale 容许用户的最大缩放值,为一个数字,能够带小数
- height 设置 layout viewport 的高度,这个属性对咱们并不重要,很少应用
- user-scalable 是否容许用户进行缩放,值为 ”no” 或 ”yes”, no 代表不容许,yes 代表容许这些属性能够同时应用,也能够独自应用或混合应用,多个属性同时应用时用逗号隔开就行了。
23.Reflow 和 Repaint
Reflow
当波及到 DOM 节点的布局属性发生变化时,就会从新计算该属性,浏览器会从新描述相应的元素,此过程叫 Reflow(回流或重排)。
Repaint
当影响 DOM 元素可见性的属性发生变化 (如 color) 时, 浏览器会从新描述相应的元素, 此过程称为 Repaint(重绘)。因而重排必然会引起重绘。
引起 Repaint 和 Reflow 的一些操作
- 调整窗口大小
- 字体大小
- 样式表变动
- 元素内容变动,尤其是输出控件
- CSS 伪类激活,在用户交互过程中产生
- DOM 操作,DOM 元素增删、批改
- width, clientWidth, scrollTop 等布局宽高的计算
Repaint 和 Reflow 是不可避免的,只能说对性能的影响减到最小,给出上面几条倡议:
- 防止逐条更改款式。倡议集中批改款式,例如操作 className。
- 防止频繁操作 DOM。创立一个 documentFragment 或 div,在它下面利用所有 DOM 操作,最初增加到文档里。设置 display:none 的元素上操作,最初显示进去。
- 防止频繁读取元素几何属性(例如 scrollTop)。相对定位具备简单动画的元素。
- 相对定位使它脱离文档流,防止引起父元素及后续元素大量的回流
参考资料:
- 缩小页面重排与重绘(Reflow & Repaint)
- 页面重构应留神的 repaint 和 reflow
24. img 中的 alt 和元素的 title 属性作用
- img 的 alt 属性
如果无奈显示图像,浏览器将显示 alt 指定的内容
- 元素 title 属性
在鼠标移到元素上时显示 title 的内容
25.href 和 src 区别
href
href 标识超文本援用,用在 link 和 a 等元素上,href 是援用和页面关联,是在以后元素和援用资源之间建立联系
若在文档中增加 href,浏览器会辨认该文档为 CSS 文件,就会并行下载资源并且不会进行对以后文档的解决。这也是为什么倡议应用 link 形式加载 CSS,而不是应用 @import 形式。
src
src 示意援用资源,替换以后元素,用在 img,script,iframe 上,src 是页面内容不可短少的一部分。
当浏览器解析到 src,会暂停其余资源的下载和解决(图片不会暂停其余资源下载和解决),直到将该资源加载、编译、执行结束,图片和框架等也如此,相似于将所指向资源利用到以后内容。这也是为什么倡议把 js 脚本放在底部而不是头部的起因。
参考资料:
- 前端面试题 -url、href、src
25. 浏览器的渲染过程
- 解析 HTML 生成 DOM 树。
- 解析 CSS 生成 CSSOM 规定树。
- 将 DOM 树与 CSSOM 规定树合并在一起生成渲染树。
- 遍历渲染树开始布局,计算每个节点的地位大小信息。
- 调用 GPU 绘制,合成图层。
- 将渲染树每个节点绘制到屏幕。
26. 为何会呈现浏览器兼容问题
- 同一产品,版本越老 bug 越多
- 同一产品,版本越新,性能越多
- 不同产品,不同规范,不同实现形式
解决兼容问题的思路
- 要不要做
- 产品的角度(产品的受众、受众的浏览器比例、成果优先还是基本功能优先)
- 老本的角度 (有无必要做某件事)
2. 做到什么水平
- 让哪些浏览器反对哪些成果
3.. 如何做
- 依据兼容需要抉择技术框架 / 库(jquery)
- 依据兼容需要抉择兼容工具(html5shiv.js、respond.js、css reset、normalize.css、Modernizr)
- 条件正文、CSS Hack、js 能力检测做一些修补
- 渐进加强(progressive enhancement): 针对低版本浏览器进行构建页面,保障最根本的性能,而后再针对高级浏览器进行成果、交互等改良和追加性能达到更好的用户体验
- 优雅降级 (graceful degradation): 一开始就构建残缺的性能,而后再针对低版本浏览器进行兼容。
参考资料:
- 为何会呈现浏览器兼容性问题?如何解决?
27.doctype 有什么用
doctype 是一种规范通用标记语言的文档类型申明,目标是通知规范通用标记语言解析器要应用什么样的文档类型定义(DTD)来解析文档。
申明是用来批示 web 浏览器对于页面应用哪个 HTML 版本进行编写的指令。申明必须是 HTML 文档的第一行,位于 html 标签之前。
浏览器自身分为两种模式,一种是规范模式,一种是怪异模式。
浏览器通过 doctype 来辨别这两种模式,doctype 在 html 中的作用就是触发浏览器的规范模式,如果 html 中省略了 doctype,浏览器就会进入到 Quirks 模式的怪异状态。
在这种模式下,有些款式会和规范模式存在差别。
而 html 规范和 dom 标准值规定了规范模式下的行为,没有对怪异模式做出规定,因而不同浏览器在怪异模式下的解决也是不同的,所以肯定要在 html 结尾应用 doctype。
28. 行内元素和块级元素有哪些
行内元素
一个行内元素只占据它对应标签的边框所蕴含的空间
个别状况下,行内元素只能蕴含数据和其余行内元素
b, big, i, small, tt
abbr, acronym, cite, code, dfn, em, kbd, strong, samp, var
a, bdo, br, img, map, object, q, script, span, sub, sup
button, input, label, select, textarea
块级元素
占据一整行,高度、行高、内边距和外边距都能够扭转,能够包容块级标签和其余行内标签
header,form,ul,ol,table,article,div,hr,aside,figure,canvas,video,audio,footer
29. 行内元素、块级元素区别
行内元素:和其余元素都在一行上,高度、行高及外边距和内边距都不可扭转(边距高低方向不可扭转,左右方向能够扭转),文字图片的宽度不可扭转,只能包容文本或者其余行内元素;其中 img 是行元素
块级元素:总是在新行上开始,高度、行高及外边距和内边距都可管制,能够包容内敛元素和其余元素;行元素转换为块级元素形式:display:block;
30. iframe 框架有那些优缺点
长处:
- iframe 可能一成不变的把嵌入的网页展示进去。
- 如果有多个网页援用 iframe,那么你只须要批改 iframe 的内容,就能够实现调用的每一个页面内容的更改,方便快捷。
- 网页如果为了对立格调,头部和版本都是一样的,就能够写成一个页面,用 iframe 来嵌套,能够减少代码的可重用。
- 如果遇到加载迟缓的第三方内容如图标和广告,这些问题能够由 iframe 来解决。
毛病:
- 搜索引擎的爬虫程序无奈解读这种页面
- 框架结构中呈现各种滚动条
- 应用框架结构时,保障设置正确的导航链接。
- iframe 页面会减少服务器的 http 申请
31. label 标签有什么作用
label
标签通常是写在表单内,它关联一个控件,应用 label
能够实现点击文字选取对应的控件。
<input type="checkbox" id="test">
<label for="test" >test</label>
32.HTML5 的 form 如何敞开主动实现性能
将不想要主动实现的 form
或 input
设置为 autocomplete=off
33. DOM 和 BOM 有什么区别
DOM
Document Object Model,文档对象模型
DOM 是为了操作文档呈现的 API,document 是其的一个对象
DOM 和文档无关,这里的文档指的是网页,也就是 html 文档。DOM 和浏览器无关,他关注的是网页自身的内容。
BOM
Browser Object Model,浏览器对象模型
BOM 是为了操作浏览器呈现的 API,window 是其的一个对象
我平时始终有整顿面试题的习惯,有随时跳出舒服圈的筹备,人不知; 鬼不觉整顿了 229 页了,在这里分享给大家,有须要的点击这里收费支付题目 + 解析 PDF
篇幅无限,仅展现局部内容
如果你须要这份完整版的面试题 + 解析,【点击我】就能够了。
心愿大家明年的金三银四面试顺利,拿下本人心仪的 offer!