一行代码实现数组去重?
[...new Set([1,2,3,1,'a',1,'a'])]
怎么判断两个对象相等?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
obj={
a:1,
b:2
}
obj2={
a:1,
b:2
}
obj3={
a:1,
b:'2'
}


JSON.stringify(obj)==JSON.stringify(obj2);//true
JSON.stringify(obj)==JSON.stringify(obj3);//false

CommonJS 中的 require/exports 和 ES6 中的 import/export 区别?

CommonJS 模块的重要特性是加载时执行,即脚本代码在 require 的时候,就会全部执行。一旦出现某个模块被”循环加载”,就只输出已经执行的部分,还未执行的部分不会输出。
ES6 模块是动态引用,如果使用 import 从一个模块加载变量,那些变量不会被缓存,而是成为一个指向被加载模块的引用,需要开发者自己保证,真正取值的时候能够取到值。
import/export 最终都是编译为 require/exports 来执行的。
CommonJS 规范规定,每个模块内部,module 变量代表当前模块。这个变量是一个对象,它的 exports 属性(即 module.exports )是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。
export 命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。

浏览器缓存
浏览器缓存分为强缓存和协商缓存。当客户端请求某个资源时,获取缓存的流程如下:

先根据这个资源的一些 http header 判断它是否命中强缓存,如果命中,则直接从本地获取缓存资源,不会发请求到服务器;
当强缓存没有命中时,客户端会发送请求到服务器,服务器通过另一些request header验证这个资源是否命中协商缓存,称为http再验证,如果命中,服务器将请求返回,但不返回资源,而是告诉客户端直接从缓存中获取,客户端收到返回后就会从缓存中获取资源;
强缓存和协商缓存共同之处在于,如果命中缓存,服务器都不会返回资源;
区别是,强缓存不对发送请求到服务器,但协商缓存会。
当协商缓存也没命中时,服务器就会将资源发送回客户端。
当 ctrl+f5 强制刷新网页时,直接从服务器加载,跳过强缓存和协商缓存;
当 f5 刷新网页时,跳过强缓存,但是会检查协商缓存;

强缓存

Expires(该字段是 http1.0 时的规范,值为一个绝对时间的 GMT 格式的时间字符串,代表缓存资源的过期时间)
Cache-Control:max-age(该字段是 http1.1 的规范,强缓存利用其 max-age 值来判断缓存资源的最大生命周期,它的值单位为秒)

协商缓存

Last-Modified(值为资源最后更新时间,随服务器response返回)
If-Modified-Since(通过比较两个时间来判断资源在两次请求期间是否有过修改,如果没有修改,则命中协商缓存)
ETag(表示资源内容的唯一标识,随服务器response返回)
If-None-Match(服务器通过比较请求头部的If-None-Match与当前资源的ETag是否一致来判断资源是否在两次请求之间有过修改,如果没有修改,则命中协商缓存)

页面渲染的完整流程是怎样的?

图片里的 alt 属性是做什么的?

查看答案
如果用户看不到图像,alt 属性可以提供替代信息。alt 属性应该用于描述,而那些仅仅是装饰目的图像,可以为空

小贴士
装饰性的图像应该有一个空的 alt 属性
web 爬虫可以通过 alt 属性理解图像的信息,因此认为它对于搜索引擎优化(SEO)非常重要
在 alt 末尾加 . 可以提高访问性

不采用缓存的目的是什么,你如何实现它?

查看答案
浏览器有一个临时的存储网站文件的缓存,所以他们不需要在切换或重新加载同一个页面时再次重新下载。服务器设置发送头信息告诉浏览器在给定的一段时间内使用存储文件。这极大加快了网站的速度和节省了带宽

然而,当开发人员网站更新时,因为用户的缓存依然指向旧的文件,这会造成问题。如果缓存的 CSS 和 JavaScript 文件引用的元素不再存在,已移除或已重命名时,它会保留原有功能或破坏网站

禁用缓存是一个强制浏览器下载新文件的过程。通过命名来区分于旧文件

一个常用的强制浏览器重新下载文件的技术是在文件的结尾处增加一个查询字符串

src=”js/script.js” => src=”js/script.js?v=2”
浏览器认为这是一个不同的文件但是避免了修改文件名的必要

一个页面里是否可以包含多个
元素,
元素呢?

查看答案
都可以。W3C 文档声明这些标签代表离它们最近祖先区域的页眉(

)和页脚(
)。因此,不只是可以在页面的 里包含页眉和页脚,而且每一个
元素都可以包含

小贴士
W3C 推荐你想用多少就用多少,但是每一个页面的区域只能有一个,即,body,section 等等

<script> 标签的 defer 和 async 是什么?

查看答案
如果两个属性都没有的话,脚本将同步下载和执行,并且会阻塞 document 解析,直到脚本执行完成(默认行为)。脚本下载和执行按它们书写的顺序进行

defer 属性在 document 解析的过程中下载脚本,但是在 document 解析完成之前执行,等价于执行了一个内置的事件监听器 DOMContentLoaded。defer 脚本顺序执行

async 属性在 document 解析过程中下载脚本,但是会暂停解析器,直到脚本解析执行完成。async 不一定按顺序执行

注意:两个属性必须在脚本拥有 src 属性时才起作用(即,在内联脚本不起作用)


小贴士
请用 中放置一个 defer,允许浏览器在页面还在解析过程中下载脚本,因此把脚本放到 body 之前是更好的选择
如果脚本之间相互依赖,请用 defer.
如果脚本是独立的,请用 async.
如果 DOM 必须加载完并且内容还未放置到 DOMContentLoaded 监听器中时,请用 defer

相比 HTML,XHTML 有哪些不同?

查看答案
有一些关键区别:

一个 XHTML 元素必须要有一个 XHTML
属性值必须用引号包裹
禁止属性简写(例如,checked=”checked” 不能简写为 checked)
元素必须正确的被嵌套
元素必须闭合
特殊字符必须被转义
小贴士
任何被标签都是自闭合
标签和属性区分大小写,通常小写

你能说出 @media 属性的四种类型吗?

查看答案
all,适用于所有媒体设备
print,仅适用于打印机
screen,仅适用于屏幕设备(台式电脑、平板电脑、移动设备等)
speech,仅适用于屏幕阅读器

如何统计网页里出现多少种html标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 获取所有标签
var doms = document.getElementsByTagName("*")

#去重
var obj = {}
var ret = []
for (var j = 0; j < doms.length; i++) {
var name = doms[j].nodeName
if(!obj[name]) {
ret.push(name)
obj[name] = true
}
}
console.log(ret.length);

# ES6方法
const names = [...document.getElementsByTagName("*")].map(v=>v.nodeName)

console.log(new Set(names).size);

手写bind call

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Function.prototype.call = function(context) {
context = context || window
context.fn = this
const args = [...arguments].slice(1)
const result = context.fn(...args)
delete context.fn
return result
}

Function.prototype.bind = function(context) {
const _this = this
const args = [...arguments].slice(1)
// 返回一个高阶函数
return function F() {
if(this instanceof F) {
return new _this(...args, ...arguments)
}
return _this.apply(context, args.concat(...arguments))
}
}

如何提升渲染性能
服务端渲染
为什么要进行服务端渲染

JS
回收机制
String、Array类型的方法使用
原型与原型链
构造函数模型/原型模型
闭包/递归
BOM
操作BOM结构
事件冒泡/捕获
AJAX请求