window.addEventListener(‘resize’, myEfficientFn);
防抖函数确实不错,但是也存在问题,譬如图片的懒加载,我希望在下滑过程中图片不断的被加载出来,而不是只有当我停止下滑时候,图片才被加载出来。又或者下滑时候的数据的 ajax 请求加载也是同理。
这个时候,我们希望即使页面在不断被滚动,但是滚动 handler 也可以以一定的频率被触发(譬如 250ms 触发一次),这类场景,就要用到另一种技巧,称为节流函数(throttling)。
节流函数,只允许一个函数在 X 毫秒内执行一次。
与防抖相比,节流函数最主要的不同在于它保证在 X 毫秒内至少执行一次我们希望触发的事件 handler。
与防抖相比,节流函数多了一个 mustRun 属性,代表 mustRun 毫秒内,必然会触发一次 handler ,同样是利用定时器,看看简单的示例:
// 简单的节流函数
function throttle(func, wait, mustRun) {
var timeout,
startTime = new Date();
return function() {
var context = this,
args = arguments,
curTime = new Date();
clearTimeout(timeout);
// 如果达到了规定的触发时间间隔,触发 handler
if(curTime - startTime >= mustRun){
func.apply(context,args);
startTime = curTime;
// 没达到触发间隔,重新设定定时器
}else{
timeout = setTimeout(func, wait);
}
};
};
// 实际想绑定在 scroll 事件上的 handler
function realFunc(){
console.log(“Success”);
}
// 采用了节流函数
window.addEventListener(‘scroll’,throttle(realFunc,500,1000));
上面简单的节流函数的例子可以拿到浏览器下试一下,大概功能就是如果在一段时间内 scroll 触发的间隔一直短于 500ms ,那么能保证事件我们希望调用的 handler 至少在 1000ms 内会触发一次。
一个模块是能实现特定功能的文件,有了模块就可以方便的使用别人的代码,想要什么功能就能加载什么模块。
Commonjs:开始于服务器端的模块化,同步定义的模块化,每个模块都是一个单独的作用域,模块输出,modules.exports,模块加载require()引入模块。
AMD:中文名异步模块定义的意思。
requireJS实现了AMD规范,主要用于解决下述两个问题。
1.多个文件有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器
2.加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应的时间越长。
语法:requireJS定义了一个函数define,它是全局变量,用来定义模块。
requireJS的例子:
//定义模块
define([‘dependency’], function(){
var name = ‘Byron’;
function printName(){
console.log(name);
}
return {
printName: printName
};
});
//加载模块
require([‘myModule’], function (my){
my.printName();
}
requirejs定义了一个函数define,它是全局变量,用来定义模块:
define(id?dependencies?,factory)
在页面上使用模块加载函数:
require([dependencies],factory);
总结AMD规范:require()函数在加载依赖函数的时候是异步加载的,这样浏览器不会失去响应,它指定的回调函数,只有前面的模块加载成功,才会去执行。
因为网页在加载js的时候会停止渲染,因此我们可以通过异步的方式去加载js,而如果需要依赖某些,也是异步去依赖,依赖后再执行某些方法。
由于篇幅有限,只能分享部分面试题,更多面试题及答案可以【点击我】阅读下载哦~无偿分享给大家,算是一个感恩回馈吧
事件代理( Event Delegation ),又称之为事件委托。是 JavaScript 中常用的绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好处是可以提高性能
可以大量节省内存占用,减少事件注册,比如在 table 上代理所有 td 的 click 事件就非常棒
可以实现当新增子对象时无需再次对其绑定
W3C 中定义事件的发生经历三个阶段:捕获阶段( capturing )、目标阶段
( targetin )、冒泡阶段( bubbling )
冒泡型事件:当你使用事件冒泡时,子级元素先触发,父级元素后触发
捕获型事件:当你使用事件捕获时,父级元素先触发,子级元素后触发
DOM 事件流:同时支持两种事件模型:捕获型事件和冒泡型事件
阻止冒泡:在 W3c 中,使用 stopPropagation() 方法;在IE下设置 cancelBubble =true
阻止捕获:阻止事件的默认行为,例如 click - a 后的跳转。在 W3c 中,使用preventDefault() 方法,在 IE 下设置 window.event.returnValue = false
创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型
属性和方法被加入到 this 引用的对象中
新创建的对象由 this 所引用,并且最后隐式的返回 this
Ajax 的原理简单来说是在用户和服务器之间加了—个中间层( AJAX 引擎),通过XmlHttpRequest 对象来向服务器发异步请求,从服务器获得数据,然后用 javascript来操作 DOM 而更新页面。使用户操作与服务器响应异步化。这其中最关键的一步就是从服务器获得请求数据
Ajax 的过程只涉及 JavaScript 、 XMLHttpRequest 和 DOM 。 XMLHttpRequest 是ajax的核心机制
function deepClone(obj){
var newObj= obj instanceof Array ? []:{};
for(var item in obj){
var temple= typeof obj[item] == ‘object’ ? deepClone(obj[item]):obj[item];
newObj[item] = temple;
}
return newObj;
}
ES5的常用的对象克隆的一种方式。注意数组是对象,但是跟对象又有一定区别,所以我们一开始判断了一些类型,决定newObj是对象还是数组~
var myNewAjax=function(url){
return new Promise(function(resolve,reject){
var xhr = new XMLHttpRequest();
xhr.open(‘get’,url);
xhr.send(data);
xhr.onreadystatechange=function(){
if(xhr.status200&&readyState4){
var json=JSON.parse(xhr.responseText);
resolve(json)
}else if(xhr.readyState==4&&xhr.status!=200){
reject(‘error’);
}
}
})
}
function ones(func){
var tag=true;
return function(){
if(tag==true){
func.apply(null,arguments);
tag=false;
}
return undefined
}
}
我们假设这里有一个user对象,
(1)在ES5中可以通过Object.defineProperty来实现已有属性的监听
Object.defineProperty(user,‘name’,{
set:function(key,value){
}
})
缺点:如果id不在user对象中,则不能监听id的变化
(2)在ES6中可以通过Proxy来实现
var user = new Proxy({},{
set:function(target,key,value,receiver){
}
})
这样即使有属性在user中不存在,通过user.id来定义也同样可以这样监听这个属性的变化哦~
(1)while循环的方式
function sleep(ms){
var start=Date.now(),expire=start+ms;
while(Date.now()<expire);
console.log(‘1111’);
return;
}
执行sleep(1000)之后,休眠了1000ms之后输出了1111。上述循环的方式缺点很明显,容易造成死循环。
(2)通过promise来实现
function sleep(ms){
var temple=new Promise(
(resolve)=>{
console.log(111);setTimeout(resolve,ms)
});
return temple
}
sleep(500).then(function(){
//console.log(222)
})
//先输出了111,延迟500ms后输出222
(3)通过async封装
function sleep(ms){
return new Promise((resolve)=>setTimeout(resolve,ms));
}
async function test(){
var temple=await sleep(1000);
console.log(1111)
return temple
}
test();
//延迟1000ms输出了1111
(4).通过generate来实现
function* sleep(ms){
yield new Promise(function(resolve,reject){
console.log(111);
setTimeout(resolve,ms);
})
}
sleep(500).next().value.then(function(){console.log(2222)})
20.Function.proto(getPrototypeOf)是什么?
获取一个对象的原型,在chrome中可以通过_proto_的形式,或者在ES6中可以通过Object.getPrototypeOf的形式。
那么Function.proto是什么么?也就是说Function由什么对象继承而来,我们来做如下判别。
Function.proto==Object.prototype //false
Function.proto==Function.prototype//true
我们发现Function的原型也是Function。
由于篇幅有限,只能分享部分面试题,更多面试题及答案可以【点击我】阅读下载哦~无偿分享给大家,算是一个感恩回馈吧
首先了解下浏览器的同源策略 同源策略 /SOP(Same origin policy) 是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到 XSS 、 CSFR 等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源
- 通过jsonp跨域
var script = document.createElement(‘script’);
script.type = ‘text/javascript’;
// 传参并指定回调执行函数为onBack
script.src = ‘http://www…:8080/login?user=admin&callback=onBack’;
document.head.appendChild(script);
// 回调执行函数
function onBack(res) {
alert(JSON.stringify(res));
}
- document.domain + iframe跨域
//父窗口:(http://www.domain.com/a.html)
//子窗口:(http://child.domain.com/b.html)
document.domain = ‘domain.com’;
// 获取父窗口中变量
alert('get js data from parent —> ’ + window.parent.user);
-
nginx代理跨域
-
nodejs中间件代理跨域
-
后端在头部信息里面设置安全域名
Object 是 JavaScript 中所有对象的父对象
数据封装类对象: Object 、 Array 、 Boolean 、 Number 和 String
其他对象: Function 、 Arguments 、 Math 、 Date 、 RegExp 、 Error
对象字面量: var obj = {};
构造函数: var obj = new Object();
Object.create(): var obj = Object.create(Object.prototype);
-
jquery 源码封装在一个匿名函数的自执行环境中,有助于防止变量的全局污染,然后通过传入 window 对象参数,可以使 window 对象作为局部变量使用,好处是当 jquery 中访问 window 对象的时候,就不用将作用域链退回到顶层作用域了,从而可以更快的访问window对象。同样,传入 undefined 参数,可以缩短查找 undefined 时的作用域链
-
jquery 将一些原型属性和方法封装在了 jquery.prototype 中,为了缩短名称,又赋值给了 jquery.fn ,这是很形象的写法
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
最后
如果你已经下定决心要转行做编程行业,在最开始的时候就要对自己的学习有一个基本的规划,还要对这个行业的技术需求有一个基本的了解。有一个已就业为目的的学习目标,然后为之努力,坚持到底。如果你有幸看到这篇文章,希望对你有所帮助,祝你转行成功。
CodeChina开源项目:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中…(img-gONwUBG1-1711995152632)]
[外链图片转存中…(img-cdC4NcfP-1711995152633)]
[外链图片转存中…(img-R8kDILsb-1711995152633)]
[外链图片转存中…(img-tNUqjbQR-1711995152634)]
[外链图片转存中…(img-WGWWxCXS-1711995152634)]
[外链图片转存中…(img-PqE2zR8s-1711995152635)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-EPKVfOLT-1711995152635)]
最后
如果你已经下定决心要转行做编程行业,在最开始的时候就要对自己的学习有一个基本的规划,还要对这个行业的技术需求有一个基本的了解。有一个已就业为目的的学习目标,然后为之努力,坚持到底。如果你有幸看到这篇文章,希望对你有所帮助,祝你转行成功。