1.typeof 于 instanceof 区别
typeof
对于基本类型,除了null
都可以显示正确的类型typeof
对于对象,除了函数都会显示object
- 对于
null
来说,虽然它是基本类型,但是会显示object
,这是⼀个存在 很久了的Bug
instanceof
可以正确的判断对象的类型,因为内部机制是通过判断对象的 原型链中是不是能找到类型的prototype
// 我们也可以试着实现⼀下 instanceof
function instanceof(left, right) {
// 获得类型的原型
let prototype = right.prototype
// 获得对象的原型
left = left.__proto__
// 判断对象的类型是否等于类型的原型
while (true) {
if (left === null)
return false
if (prototype === left)
return true
left = left.__proto__
}
}
2.判断⻚⾯是否加载完成
Load
事件触发代表⻚⾯中的DOM
,CSS
,JS
,图⽚已经全部加载完毕。DOMContentLoaded
事件触发代表初始的HTML
被完全加载和解析,不需要等待
CSS
,JS
,图⽚加载
3.如何解决跨域
因为浏览器出于安全考虑,有同源策略。也就是说,如果协议、域名或者端⼝ 有⼀个不同就是跨域,
Ajax
请求会失败。
我们可以通过以下⼏种常⽤⽅法解决跨域的问题:
JSONP
JSONP
的原理很简单,就是利⽤<script>
标签没有跨域限制的漏洞。通过<script>
标签指向⼀个需要访问的地址并提供⼀个回调函数来接收数据当需 要通讯时
<script src="http://domain/api?param1=a¶m2=b&callback=jsonp"></script> <script>
function jsonp(data) {
console.log(data) }
</script>
JSONP
使⽤简单且兼容性不错,但是只限于get
请求
- 在开发中可能会遇到多个
JSONP
请求的回调函数名是相同的,这时候就需要⾃⼰封装⼀ 个JSONP
,以下是简单实现
function jsonp(url, jsonpCallback, success) {
let script = document.createElement("script");
script.src = url;
script.async = true;
script.type = "text/javascript";
window[jsonpCallback] = function(data) {
success && success(data);
};
document.body.appendChild(script);
}
jsonp(
"http://xxx",
"callback",
function(value) {
console.log(value);
}
);
CORS:
ORS
需要浏览器和后端同时⽀持。IE 8
和 9 需要通过XDomainRequest
来实现。- 浏览器会⾃动进⾏
CORS
通信,实现CORS
通信的关键是后端。只要后端实现了
CORS
,就实现了跨域。 - 服务端设置
Access-Control-Allow-Origin
就可以开启CORS
。 该属性表示哪些域名 可以访问资源,如果设置通配符则表示所有⽹站都可以访问资源。
4.事件代理
如果⼀个节点中的⼦节点是动态⽣成的,那么⼦节点需要注册事件的话应该注 册在⽗节点上
<ul id="ul">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
let ul = document.querySelector('#ul')
ul.addEventListener('click', (event) => {
console.log(event.target);
})
</script>
- 事件代理的⽅式相对于直接给⽬标注册事件来说,有以下优点
- 节省内存
- 不需要给⼦节点注销事件
5.优化webpack打包速度
- 减少⽂件搜索范围
- ⽐如通过别名
loader
的test
,include
&exclude
Webpack4
默认压缩并⾏Happypack
并发调⽤babel
也可以缓存编译
6.Babel 原理
- 本质就是编译器,当代码转为字符串⽣成
AST
,对AST
进⾏转变最后再⽣成新的代码 - 分为三步:词法分析⽣成
Token
,语法分析⽣成AST
,遍历AST
,根据插件变换相应 的节点,最后把AST
转换为代码
7.如何实现⼀个插件
- 调⽤插件 apply 函数传⼊ compiler 对象
- 通过 compiler 对象监听事件
⽐如你想实现⼀个编译结束退出命令的插件
apply (compiler) {
const afterEmit = (compilation, cb) => {
cb()
setTimeout(function () {
process.exit(0)
}, 1000)
}
compiler.plugin('after-emit', afterEmit)
}
}
module.exports = BuildEndPlugin