JavaScript不仅门槛低,而且是一门有趣、功能强大和非常重要的语言。各行各业的人发现自己最混乱的选择是JavaSscript编程语言。由 于有着各种各样的背景,所以不是每个人都对JavaScript及其基本原理有广泛的认识。通常来书,除非你去参加工作面试才会去思考为什么或者怎么做, 否则JavaScript只是你工作的内容。
    这个系类的目标是深入探讨JavaScript的一些概念和理论。主题来自于 Darcy Clarke的JavaScript典型面试问题列表。希望你不仅仅是为了答案而阅读完这篇文章,每一篇文章会让对过去学过的知识有一个新的理解,或者重 温你学习的东西,这有利于你用JavaScript实现所有交互。
详解事件委托
    事件委托是一种由其它元素而非事件目标元素来响应事件产生的行为的思想。用document元素来处理按钮的点击行为就是事件委托的一个例子,另一种常见情况是,用ul元素来处理其子元素li的事件。
    有多种方法来处理事件委托。标准方法来源于原生浏览器的功能。浏览器以一种特定的工作流程来处理事件,并支持事件捕获和事件冒泡。W3C关于浏览器怎么支持事件的文档:W3C DOM Level 3 Events。一些JS库和框架公开了其它方式,如发布/订阅模型(将在后文提及)。
    事件捕获和事件冒泡是事件流中的两个阶段,任何事件产生时,如点击一个按钮,将从最顶端的容器开始(一般是html的根节点)。浏览器会向下遍历DOM树 直到找到触发事件的元素,一旦浏览器找到该元素,事件流就进入事件目标阶段,该阶段完成后,浏览器会沿DOM树向上冒泡直到最顶层容器,看看是否有其它元 素需要使用同一个事件。
    下面的示例说明了这个过程。点击按钮会导致事件流识别本身在容器下面的文本,每一个元素都接收同样的点击监听代码,由于事件捕获,点击事件会首先触发HTML节点绑定的点击处理程序,然后在事件冒泡阶段的末尾返回到最顶层元素。
    大多数现代库使用冒泡监听,而在捕获阶段处理。浏览器包含一个方法来管理事件冒泡。事件处理程序可以调用stopPropagation告诉DOM事件停 止冒泡,第二个方式是调用stopImmediatePropagation,它不仅停止冒泡,也会阻止这个元素上其它监听当前事件的处理程序触发。然 而,停止传播事件时要小心,因为你不知道是否有其它上层的DOM元素可能需要知道当前事件。
    还有第三个可以控制元素如何对事件作出回应的方法。所有现代浏览器支持preventDefault方法,这个方法会阻止浏览器处理事件的默认行为。一个 常见示例就是链接,使用链接执行UI操作是一种常见的做法。然而,当我们不希望链接跟普通被激活的链接一样会在新标签页打开一个新页面,就可以使用 preventDefault方法来阻止这个默认行为。
    还有其它实现事件委托的方法可以考虑,其中值得一提的就是发布/订阅模型。发布/订阅模型也称为了广播模型,牵涉到两个参与者。通常,两个参与者在DOM 中并没有紧密的联系,而且可能是来自兄弟的容器。可以给它们共同的祖先元素设置监听处理程序,但是如果共同的祖先元素在DOM树中处于较高层次(离根节点 比较近),就会监听很多同辈元素的事件,会造成意想不到的结果;当然,也可能存在逻辑或结构原因要分开这两个元素。
    发布/订阅模型也能自定义事件。发布/订阅模型从一个元素发送消息后并向上遍历,有时也向下遍历,DOM会通知遍历路径上的所有元素事件发生了。在下面的示例中,JQuery通过trigger方法传递事件。
    使用事件委托来管理事件流有很多优点,其中最大的优点是改善性能。元素绑定的每一个监听器都会占用一些内存,如果页面上只有少数几个监听器,我们也不会注 意到它们之间的区别,然后,如果要监听一个50行5列的表格中的每个单元格,你的Web应用会开始变慢,为了使应用程序最快运行的最好方式是保持尽可能低 的内存使用。
    使用事件委托能减少监听器数量,在元素的容器上绑定事件意味着只需要一个监听器。这种方法的缺点是,父容器的侦听器可能需要检查事件来选择正确的操作,而元素本身不会是一个监听器。额外处理带来的影响远低于许多存在内存中的监听器。
    更少的监听器和更少的DOM交互也易于维护。父容器层次的监听器能处理多种不同的事件操作,这是一种简单的方法来管理相关的事件操作,这些事件通常需要执行相关功能或需要共享数据。
    如果父容器是监听器,然后要执行独立的内部操作而并不需要添加或者移除本身的监听器。元素操作在单页应用中是极其常见的,为某部分添加一个按钮这样简单的 事情也会为应用程序创建一个潜在的性能块,没有合适的事件委托,就必须手动为每一个按钮添加监听,如果每个侦听器不清理干净,它可能会导致内存泄漏。浏览 器不会清理页面,因此在单页应用中,所有从内存中清理不当的碎片都会留在内存中,这些碎片会降低程序性能。
    当在页面中添加交互时,仔细考虑一下,是否真的需要去监听元素。
this在JavaScript中是怎么工作的
    this 关键字在JavaScript中的一种常用方法是指代码当前上下文。
  • 如果this没有被设置,则默认指向全局对象,其通常是window
  • 如果一个函数中运行了一个内联函数,比如一个事件监听器,则this指向内联函数的源代码。例如,当设置一个按钮的单击处理程序,this将引用匿名函数内的按钮。
  • 如果函数是一个对象的构造函数,this指向新对象。
  • 如果函数被定义在一个对象上,然后调用对象时,this指向该对象。
    在异步编程中,this可以很容易改变过程中一个功能操作。保持处理程序上下文的一个小技巧是将其设置到闭包内的一个变量,当在上下文改变的地方调用一个函数时,如setTimeout,你仍然可以通过该变量引用需要的对象。
 
 
操作this的另一种方式是通过call、apply和bind。三种方法都被用于调用一个函数,并能指定this的上下文,你可以让代码使用你规定的对
象,而不是依靠浏览器去计算出this指向什么。Call、apply和bind本身是相当复杂的,应该有自己的文档记录,我们会把这当做未来待解决问题
的一部分。下面是一个改变this指向方法的示例:
    事件委托和this是现代JavaScript中重要的功能,理解它们的工作原理是成功开发产品的关键,并且可以肯定的是,这是应聘JavaScript工程师必须要了解的。

JavaScript面试问题:事件委托和this的更多相关文章

  1. JavaScript中的事件委托机制跟深浅拷贝

    今天聊下JavaScript中的事件委托跟深浅拷贝 事件委托 首先呢,介绍一下事件绑定 //方法一:通过onclick <button onclick="clickEvent()&qu ...

  2. js实例分析JavaScript中的事件委托和事件绑定

    我们在学习JavaScript中,难免都会去网上查一些资料.也许偶尔就会遇到“事件委托”(也有的称我“事件代理”,这里不评论谁是谁非.以下全部称为“事件委托”),尤其是在查JavaScript的事件处 ...

  3. javascript中的事件委托

    这几天看到一个面试题,大概就是,让你给1000个li都添加一个click事件,应该怎么添加?大多数人第一开始的感觉可能就是,每个li上边都添加一个呗,那要是这样的话,估计面试的时候就会GG了,这里就是 ...

  4. JavaScript中的事件委托(转至大佬)

    转至:https://www.cnblogs.com/liugang-vip/p/5616484.html 起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没 ...

  5. 简单说 JavaScript中的事件委托(下)

    说明 上次我们说了一些,关于 JavaScript中事件委托的 基础知识,这次我们继续来看. 解释 先来一段代码 <!doctype html> <html lang="e ...

  6. javascript举例介绍事件委托的典型使用场景

    在了解什么是DOM事件以及给DOM事件绑定监听器的几种方法后,我们来谈谈事件委托. 1. e.target 和 e.currentTarget 当我们给目标元素target 绑定一个事件监听器targ ...

  7. javascript事件委托和jquery事件委托

    元旦过后,新年第一篇. 初衷:很多的面试都会涉及到事件委托,前前后后也看过好多博文,写的都很不错,写的各有千秋,自己思前想后,为了以后自己的查看,也同时为现在找工作的前端小伙伴提供一个看似更全方位的解 ...

  8. Javascript事件模型系列(二)事件的捕获-冒泡机制及事件委托机制

    一.事件的捕获与冒泡 由W3C规定的DOM2标准中,一次事件的完整过程包括三步:捕获→执行目标元素的监听函数→冒泡,在捕获和冒泡阶段,会依次检查途径的每个节点,如果该节点注册了相应的监听函数,则执行监 ...

  9. JS 中的事件绑定、事件监听、事件委托

    事件绑定 要想让 JavaScript 对用户的操作作出响应,首先要对 DOM 元素绑定事件处理函数.所谓事件处理函数,就是处理用户操作的函数,不同的操作对应不同的名称. 在JavaScript中,有 ...

  10. 表格(table) 插件:支持当前行增行、删除。使用事件委托

    最近做一个项目,需要对表格进行增行和删行. 研究了一下jquery操作dom的方法和事件委托原理,下面是我编写的例子,源码传上,欢迎高手指点. 功能: 支持在指定行下面增行: 支持删行指定行: 增行. ...

随机推荐

  1. AVCaptureSession 照相时获取 AVCaptureVideoPreviewLayer尺寸

    http://stackoverflow.com/questions/14153878/avcapturesession-preset-photo-and-avcapturevideopreviewl ...

  2. map的两种取值方式

    public class MapUtil{ public static void iteratorMap1(Map m) { Set set=m.keySet();//用接口实例接口 Iterator ...

  3. Javascript继承实现

    S1:js中一切皆对象,想想如果要实现对父对象属性和方法的继承,最初我们会怎样子来实现呢,考虑到原型的概念,最初我是这样来实现继承的 function Parent(){ this.name='123 ...

  4. mysql5.5主从配置

    mysql主从同步# 一:mysql数据库的主从 mysql数据库5.5之后的版本和5.5以前的版本数据库主从存在差异,这里是针对数据库5.5之后的配置. 1.主库编辑my.cnf(linux的my. ...

  5. MySQL安装详解(V5.5 For Windows)

    前言 这几年一直在用MySQL,并且是Windows+.Net+MySQL的搭配,用MyISAM引擎支持过单表每天千万以上的数据递增,TB级的数据MySQL游刃有余.最近在做一个较大并发的项目,尝试了 ...

  6. codeforces GYM 100114 J. Computer Network tarjan 树的直径 缩点

    J. Computer Network Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Des ...

  7. delphi 取得汉字的第一个字母

    功能说明://取得汉字的第一个字母 function GetPYIndexChar( hzchar:string):char;begin  caseWORD(hzchar[1])shl8+WORD(h ...

  8. 为TListBox添加水平滚动条

    为TListBox添加水平滚动条 实例说明 TListBox组件是一个较为常用的列表组件,在默认情况下该组件是没有水平滚动条的,所以文字过长会显示不完全,在文字较短的情况下还可以,但是如果一行的文字很 ...

  9. [Ramada] Build a Functional Pipeline with Ramda.js

    We'll learn how to take advantage of Ramda's automatic function currying and data-last argument orde ...

  10. 关于dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent的分发机制浅析

    虽说这个问题不是很难...动动手就能看出答案...但是似乎不太容易理解...几次尝试把这个问题说明白....但是好像感觉说不明白....(顿时想起了那句话----说不明白就是自己还不明白! 我怎么可能 ...