<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
html{
height: 500%;
}
</style>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
//面试题:什么是函数节流?什么是函数防抖
/*
函数节流:一个函数执行一次后,只有大于设定的执行周期后才会执行第二次。
- 有个需要频繁触发的函数,出于优化性能的角度,在规定时间内,只让函数触发的第一次生效,后面不生效。
*/
/*
*节流函数
* fn 要被节流的函数
* delay 规定的时间
*/
function throlle(fn,delay){
//记录上一次触发时间
var lastTime=0;
return function(){
//记录当前触发时间
var nowTime=Date.now();
if(nowTime-lastTime>delay){
//修正this指向问题
fn.call(this);
// 同步函数
lastTime=nowTime;
}
}
}
document.onscroll=throlle(function(){console.log(‘onscroll事件被触发‘+Date.now());},2000);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
html{
height: 500%;
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<script type="text/javascript">
/*
防抖函数:一个需要频繁触发的函数,在规定时间内,只让最后一次生效,前面的不生效
*/
/*
*防抖函数
* fn 要被防抖的函数
* delay 规定的时间
*/
function debounce(fn,delay){
//记录上一次触发时间
var timer=null;
return function(){
//清除上一次的延迟
clearTimeout(timer);
//重新设置延时器
timer=setTimeout(function(){
//修正this指向问题
fn.apply(this);
},delay);
}
}
document.getElementById(‘btn‘).onclick=debounce(function(){console.log(‘点击事件被触发了‘+Date.now());},1000);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
// 面试题:什么是跨域?解决跨域的办法有哪些?
/*
1.同源策略
- 浏览器安全策略
- 协议名、域名、端口号必须完全一致
2.跨域
-违背同源策略就会产生跨域
3.解决跨域
jsonp、cors、服务代理...
(前端) (后端)
*/
//创建script标签
var script=document.createElement(‘script‘);
//设置回调函数
function getDate(data){
console.log(data);
}
//设置script 的src属性,设置请求地址
script.src=‘http://localhost:3000?callback=getDate‘;
//让script生效
document.body.appendChild(script);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
/*
面试题:nodejs的事件轮询机制
*/
setTimeout(function(){
console.log(‘setTimeout()‘);
},0);
setImmediate(function(){
console.log(‘setImmediate()‘);
});
process.nextTick(function(){
console.log(‘process.nextTick()‘)
})
/*
process.nextTick()
setTimeout()
setImmediate()
nodejs的事件轮询机制:借助libuv库实现的
包括事件轮询机制,分为6个阶段
1.timers 定时器阶段
计时和执行到点的定时器回调函数
2.pending callbacks
某些操作系统(例如TCP错误类型)的回调函数
3.idle,prepare
准备工作
4.poll轮询阶段
如果轮询队列不为空,依次同步取出轮询队列中的第一个回调函数执行,直到轮询队列为空或者达到系统最大的限制
如果轮询队列为空
如果之前设置过setImmediate函数的
直接进入下一个check阶段
如果之前没有设置过setImmediate函数
在当前poll阶段等待
直到轮询队列添加回调函数,就去第一阶段执行
如果定时器到点了,也进入到下一个阶段
5.check查询阶段
执行setImmediate设置的回调函数
6.close callbacks 关闭阶段
执行close事件回调函数
process.nextTick能在任意阶段优先执行
*/
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script type="text/javascript">
/*
面试题:从一个url地址到最终页面渲染完成,发生了什么?
*/
/*
1.DNS解析:将域名地址解析为IP地址
- 浏览器DNS缓存
- 系统DNS缓存
- 路由器DNS缓存
- 网络运营商DNS缓存
- 递归搜索:blog.baidu.com
-.com域名下查找DNS解析
-.baidu域名下查找DNS解析
-blog域名下查找DNS解析
-出错了
2.TCP连接:TCP三次握手
- 第一次握手,由浏览器发起,告诉服务器我要发送请求了
- 第二次握手,由服务器发起,告诉浏览器,我准备接收了,你赶紧发送吧。
- 第三次握手,由浏览器发送,告诉服务器,我马上就发了,你准备接收吧
3.发送请求
- 请求报文:HTTP协议的通信内容
4.接受相应
- 响应报文
5.渲染页面
- 遇见HTML标记,浏览器调用HTML解析器解析成Token并构建成dom树
- 遇见style/link标记,浏览器调用css解析器,处理css标记并构建cssom树
- 遇到script标记,调用JavaScript解析器,处理script代码(绑定事件,修改dom树/cssom树)
- 根据渲染树来计算布局,计算每个节点的几何信息(布局)
- 将各个节点颜色绘制到屏幕上(渲染)
注意:这个五个步骤不一定按照顺序执行,如果dom树或cssom树被修改,可能会执行多次布局和渲染,往往实际页面中,这些步骤会多次执行。
6. 断开连接:TCP四次挥手
第一次挥手,由浏览器发起的,发送给服务器,我东西发送完了,(请求报文)你准备关闭吧。
第二次挥手,由服务器发起的,告诉浏览器,我东西接收完了(请求报文),我准备关闭了,你也准备关闭吧。
第三次挥手,由服务器发起的,告诉浏览器,我东西发送完了(响应报文),你准备关闭吧。
第四次挥手,由浏览器发起的,告诉服务器,我东西接收完了(响应报文),我准备关闭了,你也准备关闭吧。
*/
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script type="text/javascript">
/*
理解:什么是闭包?
1.密闭的容器, 类似于set,map容器
2.闭包是一个对象,存放数据的格式:key:value
形成的条件:
1.函数嵌套
2.内部函数引用外部函数的局部变量
闭包的优点:
延长外部函数局部变量的生命周期
闭包的缺点:
容易造成内存泄露
注意点:
1.合理的使用闭包
2.用完闭包要及时清除(销毁)
*/
// 简单的闭包
function fun(){
let a=1;
function b(){
console.log(a);
}
b();
}
fun();
// Global 全局的变量对象
// Local 函数里面局部的变量对象
//闭包的应用场景
function fun(){
let count=1;
return function(){
count++;
console.log(count);
}
}
var fun2=fun();
fun2(); //2
fun2(); //3
/*
说说它们的输出情况
*/
function fun(n,o){
console.log(o)
return {
fun:function(m){
return fun(m,n)
}
}
}
var a=fun(0)
a.fun(1)
a.fun(2)
a.fun(3) //underfined,0,0,0
var b=fun(0).fun(1).fun(2).fun(3)// underfined,0,1,2
var c=fun(0).fun(1)
c.fun(2)
c.fun(3)// underfined,1,1
</script>
</body>
</html>
/*
变量升级 预处理
*/
/*
js引擎在代码正式执行之前会做一个预处理的工作:
1.收集变量
2.收集函数
依据:
var 将var后边的变量定义但不赋值 var username=undefined;
function(){}
*/
console.log(username); //答案:underfined
var username=‘kobe‘;
console.log(username) //kobe
fun(); //答案:正常执行函数
function fun(){
console.log(‘fun()‘);
}
/*
作用域:作用域是在代码定义的时候产生的
//执行上下文 执行上下文对象(this)
执行上下文(excute context) EC
理解:代码执行的环境
时机(产生时):代码正式执行之前会进入到执行环境
工作:
1.创建变量对象:
1)变量
2)函数及函数的参数
3)全局:window
4)局部:抽象的但是确实存在
2.确认this的指向
1)全局:this --->window
2)局部:this --->调用其的对象
3.创建作用域链
父级作用域链+当前的变量对象
4.扩展
ECobj={
变量对象:{变量,函数,函数的形参}
scopeChain(作用域链):父级作用域链+当前的变量对象
this:{window || 调用其的对象}
}
*/
原文:https://www.cnblogs.com/Lolita-web/p/10415176.html