js闭包其实不难,你需要的只是了解何时使用它
究竟什么是闭包?闭包在什么场景下使用?写前端程序需要用到闭包吗?我用jQuery也能写的好好滴呀?闭包可以解决哪些问题?使用闭包会带来哪些好处?
闭包是指可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。
包含两方面:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域)
既然所有函数都是闭包,还有必要专门提这个概念吗?大多数函数被调用时(invoked),使用的作用域和他们被定义时(defined)使用的作用域是同一个作用域,这种情况下,闭包神马的,无关紧要。但是,当他们被invoked的时候,使用的作用域不同于他们定义时使用的作用域的时候,闭包就会变的非常有趣,并且开始有了很多的使用场景,这就是你之所以要掌握闭包的原因。
理解“闭包”:
- step1:掌握嵌套函数的词法作用域规则(lexical scoping rules)。只要记住一点:词法作用域的规则,即函数被执行时(executed)使用的作用域链(scope chain)是 被定义 时的scope chain,而不是执行时的scope chain,就可以很容易的理解闭包的行为了。
- step 2:掌握闭包的使用场景。
- 闭包经典使用场景一:通过循环给页面上多个dom节点绑定事件
- 闭包使用场景二:封装变量
- 闭包使用场景三:延续局部变量的寿命
深入理解 JavaScript 异步
Node.js 初体验
- Node是个啥?
- 安装Node
- npm的下载和使用
- 理解Node的模块概念:在Node中,不同的功能组件被划分成不同的模块。应用可以根据自己的需要来选择使用合适的模块。每个模块都会暴露一些公共的方法或属性。
- Node能做什么和它的优势:非阻塞;单线程;事件驱动。
- Node事件流概念:因为Node 采用的是事件驱动的模式,其中的很多模块都会产生各种不同的事件,可由模块来添加事件处理方法,所有能够产生事件的对象都是事件模块中的 EventEmitter 类的实例。
- 强大的File System 文件系统模块: Node 中的 fs 模块用来对本地文件系统进行操作。文件的I/O是由标准POSIX函数封装而成。需要使用require('fs')访问这个模块。所有的方法都提供了异步和同步两种方式。
- 学习Node的总结:
2017,我们来聊聊 Node.js
新一代 JavaScript 的开发图谱(2017)
我将会将这张地图分为几个你需要解决的问题,对于每个问题,我将会:
- 描述问题或工具需求
- 决定你需要选取哪种工具
- 讨论为什么这样选
- 给一些其他选择
问题:
- 包管理
- JavaScript风格
- 编译
- Linting
- 打包工具
- 测试
- UI 库/状态管理
- DOM 操作和动画
- 样式
JavaScript 中函数节流和函数去抖的讲解
https://segmentfault.com/a/1190000002764479
http://www.topfe.cn/javascript/395.html
函数节流:在频繁触发的情况下,需要执行的逻辑只有执行完之后,才能继续执行下一次。
函数防抖:在频繁触发的情况下,只有足够的空闲时间,才执行代码一次,如果没有执行完就清除掉,重新执行逻辑。
应用场景:高频触发以下方法
- 页面滚动监听(onscroll)
- 窗口resize事件,等到窗口变化结束后才进行业务逻辑的运行
- 鼠标键盘 mousedown/keydown 事件
- 鼠标的进入移出事件(mouseenter/mouseleave)
- DOM 元素的拖拽功能实现(mousemove)
- 输入框搜索等(keyup)
// 函数节流 var canRun = true; window.onscroll = function(){ if(!canRun){ // 判断是否已空闲,如果在执行中,则直接return return; } canRun = false; setTimeout(function(){ console.log("函数节流"); canRun = true; }, 300); };
// 函数防抖 var timer = false; window.onscroll = function(){ clearTimeout(timer); // 清除未执行的代码,重置回初始化状态 timer = setTimeout(function(){ console.log("函数防抖"); }, 300); };
如何在 Vue.js 中使用第三方库
在诸多 Vue.js 应用中, Lodash, Moment, Axios, Async等都是一些非常有用的 JavaScript 库. 但随着项目越来越复杂, 可能会采取组件化和模块化的方式来组织代码, 还可能要使应用支持不同环境下的服务端渲染. 除非你找到了一个简单而又健壮的方式来引入这些库供不同的组件和模块使用, 不然, 这些第三方库的管理会给你带来一些麻烦.
补充:ES6标准发布后,module成为标准,标准的使用是以export指令导出接口,以import引入模块,但是在我们一贯的node模块中,我们采用的是CommonJS规范,使用require引入模块,使用module.exports导出接口。在一个文件或模块中,export、import可以有多个,export default仅有一个。 require和import。
本文将介绍一些在 Vue.js 中使用第三方库的方式:
- 全局变量:在项目中添加第三方库的最简单方式是讲其作为一个全局变量, 挂载到 window 对象上。这种方式不适合于服务端渲染, 因为服务端没有 window 对象, 是 undefined, 当试图去访问属性时会报错。
- 在每个文件中引入:另一个简单的方式是在每一个需要该库的文件中导入。比较繁琐, 并且带来的问题是: 你必须记住在哪些文件引用了该库, 如果项目不再依赖这个库时, 得去找到每一个引用该库的文件并删除该库的引用. 如果构建工具没设置正确, 可能导致该库的多份拷贝被引用。
- 优雅的方式:在 Vuejs 项目中使用 JavaScript 库的一个优雅方式是讲其代理到 Vue 的原型对象上去。Object.defineProperty(Vue.prototype, '$moment', { value: moment });
CSS Grid VS Flexbox:实例对比
- 挑战 1:定位页面部分
- 挑战 2:将页面变为响应式页面
- 挑战 3:对齐标头组件
结论:
- CSS grids 适用于布局大画面。它们使页面的布局变得非常容易,甚至可以处理一些不规则和非对称的设计。
- Flexbox 非常适合对齐元素内的内容。你可以使用 Flex 来定位设计上一些较小的细节。
- 2D 布局适合使用 CSS grids(行与列)。
- Flexbox 适用于单一维度的布局(行或列)。
- 共同学习并使用它们。
优化浏览器前端
为了提升用户体验(User Experience,UX),我们希望前端提供快速加载和执行的网页。而对于提升开发者体验(Developer Experience, DX)来说,我们希望前端能够快速,简便和实用。这样的优化不仅使我们的用户和开发者满意,也会显着提高SEO排名, 因为Google的SEO排名会偏向于优化较好的页面。
优化浏览器前端的方法:首先,我们不能控制浏览器或者改变它的行为方式,但是我们可以理解它的工作原理,用来优化我们页面的加载。幸运的是,浏览器行为的基本原理相当稳定并有据可查,长时间内也不会显着改变;其次,代码,堆栈,结构和模式是我们可以控制的。他们更灵活,改变地更快,为我们提供更多的选择。
咱妈说别乱点链接之浅谈CSRF攻击
CSRF(Cross-site request forgery),它的中文名称是跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。
简单地说,CSRF就是利用了我们的登录状态或者授权状态(请注意“利用”,并没有窃取到),然后做一些损害我们自身利益的事情。
从上面这个实例可知,完成CSRF攻击流程:
- 用户登录了信任的网站A,并且保存登录状态
- 黑客找出网站A没有防御的链接,通过社会工程学伪装,诱导点击。
- 只要登录状态保持,用户主动访问目标链接,则攻击成功。
总结:CSRF能够攻击的根本原因是:服务器无法识别你的来源是否可靠。
那么防御的方法有很多:
- 比如加上验证码。但这么做很繁琐,并且影响用户体验。
- 比如转账需要二次密码验证,现在很多银行就这么搞的。
- 确认来源是否可靠(推荐)
根据验证是否可靠性思路,可以有以下几种方法:
- 验证HTTP Referer 字段:HTTP协议里面定义了一个访问来源的字段,这个字段叫Referer。
- 服务端验证请求的token一致性:实现原理:在服务端生成一个随机的token,加入到HTTP请求参数中,服务器拦截请求,查看发送的token和服务端的是否一致,若一致,则允许请求;若不一致,则拒绝请求。
- Ajax防御CSRF
【译文】了解XSS攻击
跨站点脚本(Cross-site scripting,XSS)是一种允许攻击者在另一个用户的浏览器中执行恶意脚本的脚本注入式攻击。攻击者并不直接锁定受害者。而是利用一个受害者可能会访问的存在漏洞的网站,通过这个网站间接把恶意代码呈递给受害者。对于受害者的浏览器而言,这些恶意代码看上去就是网站正常的一部分,而网站也就无意中成了攻击者的帮凶。
恶意代码是如何注入的:对于攻击者来说能够让受害者浏览器执行恶意代码的唯一方式,就是把代码注入受害者从网站下载的页面中。如果网站直接在页面中呈现用户输入的内容的话,这种攻击有可能得逞。因为攻击者可以以字符串的形式向页面插入一段受害者浏览器能够执行的代码。比如一段评论包含了"<script></script>",页面加载就中招了。
什么是恶意脚本:Javascript的执行环境受到严格限制并只有非常有限的权限访问用户的文件和操作系统,所以不算特别恶意。恶意的有Javascript有权访问一些用户的敏感信息,比如cookie;Javascript能够通过XMLHttpRequest或者其他一些机制发送带有任何内容的HTTP请求到任何地址;Javascript能够通过DOM操作方法对当前页面的HTML做任意修改。
恶意脚本的后果:攻击者有能力发动以下几类攻击,Cookie窃取;Cookie窃取;钓鱼网站(Phishing)。
非常值得注意的重要一点是,恶意代码只有在受害者的浏览器中最终得到解析之后才算得上是恶意,这只可能发生有XSS缺陷的站点上。
攻击是如何工作的:攻击者利用提交网站表单将一段恶意文本插入网站的数据库中;受害者向网站请求页面;网站从数据库中取出恶意文本把它包含进返回给受害者的页面中;受害者的浏览器执行返回页面中的恶意脚本,把自己的cookie发送给攻击者的服务器。
XSS攻击类型:虽然XSS攻击的终极目标是在受害者的浏览器中执行恶意脚本,但是实现这个目标的不同途径还是有根本上的差别的。有持续型XSS攻击:恶意文本来源于网站的数据库;反射型XSS攻击:恶意文本来源于受害者的请求;基于DOM的XSS攻击:利用客户端而不是服务端代码漏洞发动攻击。
阻止XSS攻击的方式:编码,也就是转义用户的输入,这样浏览器就会把它解读为数据而不是代码;校验,也就是对用户的输入进行过滤,这样浏览器仍然把它解读为代码但当中已不存在恶意指令了。