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


Posted in Javascript onJanuary 20, 2021

今天聊下JavaScript中的事件委托跟深浅拷贝

一、事件委托

首先呢,介绍一下事件绑定

//方法一:通过onclick
<button onclick="clickEvent()">点击</button>

<script>
function clickEvent(){
   alert("点击事件");
}
</script>

//方法二:通过addEventListener
<button id="btn_button">点击</button>

<script>
var btn = document.getElementById("btn_button");
btn.addEventListener("click", function () {
  alert("点击");
}, false);
</script>

说下其中的区别
onclick只能绑定一个事件,而addEventListener可以同时绑定多个事件

[function method1() {
  console.log("method1");
}
function method2() {
  console.log("method2");
}
function method3() {
  console.log("method3");
}
var btn = document.getElementById("btn_button");
btn.addEventListener("click", method1, false);//第三个参数是默认值,默认是冒泡,如果设置为true则是捕获
btn.addEventListener("click", method2, false);
btn.addEventListener("click", method3, false);
//最终会按顺序执行:method1 -> method2 -> method3 
btn.removeEventListener("click", method1, false);//用于移除事件


btn.onclick = method1;
btn.onclick = method2;
btn.onclick = method3;
//最终只会执行method3
btn.onclick = null;//用于移除事件

事件冒泡

<ul id="container" style="display: inline-block;">
  <li id="title1">123456</li>
  <li id="title2">qwert</li>
  <li id="title3">
    <ul>
      <li id="title3inner">title3里面的文本</li>
    </ul>
  </li>
</ul>

<script>
  var container = document.getElementById("container");
  var title1 = document.getElementById("title1");
  var title2 = document.getElementById("title2");
  var title3 = document.getElementById("title3");
  var title3inner = document.getElementById("title3inner");

  container.onclick = function (e) {
    alert("container");
  }
  title1.onclick = function (e) {
    alert("title1");
  }
  title2.onclick = function (e) {
    alert("title2");
  }
  title3.onclick = function (e) {
    alert("title3");
  }
  title3inner.onclick = function (e) {
    alert("title3inner");
  }
</script>

点击 “title3里面的文本” 会触发 3 次事件,分别 弹出
“title3inner” -> “title3” -> “container”

事件捕获

至于事件冒泡倒过来即是事件捕获,即:点击 “title3里面的文本” 会触发 3 次事件,分别 弹出
“container” -> “title3” -> “title3inner”

事件冒泡的升华

事件委托的使用

<ul id="container" style="display: inline-block;">
  <li id="title1">123456</li>
  <li id="title2">qwert</li>
  <li id="title3">QWE123</li>
</ul>

<script>
var container = document.getElementById("container");
container.onclick = function (e) {
  //console.log(e);
  if (e.target.id = "title1") {
    alert(e.target.innerText);
  }
  else if (e.target.id = "title2") {
    alert(e.target.innerText);
  }
  else if (e.target.id = "title3") {
    alert(e.target.innerText);
  }
}
</script>

至于优势嘛,便是只需注册一个点击事件,然后通过target来判断点击的具体元素。而currentTarget指的是注册事件的元素。
target是你实际中点击的元素
currentTarget是绑定事件的元素
如果不用事件委托的话,在一个列表上,每条数据后,添加一个按钮,然后给每个按钮注册一个事件,每个元素绑定一个事件,那么多的按钮,肯定会对前端性能有所影响。这时候委托肯定是最好的选择了,毕竟委托只需注册一个事件。

思考

理论上,使用事件委托确实是一种优化,只需注册一个事件,然后通过事件冒泡来实现相应的功能。
至于在Vue项目中,到底用不用事件委托呢?这里好像有个争议。
有人说在Vue中,已经帮你做过了,也有人说并没有,我没看过源码,咱也不知道。

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

总之,我是这么做的,每个按钮都绑定一个事件,然后阻止冒泡。实际中,我个人不太会考虑事件委托,感觉不是太必要的,毕竟事件并没有那么多。

二、深浅拷贝

至于深浅拷贝这块的知识,我便长话短说了,一阵见血,见血封喉!

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

let a = 3;
let b = a;
a = 4;
console.log(a);//4
console.log(b);//3
console.log(a === b);//这便是深拷贝,a和b完全是不同的变量,各自保存一个值。

let arr = [1, 2, 3, 4, 5];
let brr = arr;
arr[1] = 8;
console.log(arr[1]);//8
console.log(brr[1]);//8  为什么呢? 这便是浅拷贝,数组类型是引用类型,arr跟brr变量只是保存的引用地址,他们共同指向[1,2,3,4,5]这个数组
console.log(arr === brr);//true

实际中,如果要实现深拷贝,怎么做呢?
方法主要是一个通过递归来赋值,还有一个通过JSON.stringify与JSON.parse这两个方法来实现。
在这里使用第二种方法,毕竟最是简单,简单、暴力,也往往是最有效的解决办法。

let arr = [1, 2, 3, 4, 5];
let brr = JSON.parse(JSON.stringify(arr));
arr[1] = 8;
console.log(brr[1]);//2,这便实现了所谓的深拷贝

三、总结

正如面试官的所说,虽然以上的知识在实际工作中并不一定会用到,但你还是要知道的!还是要知道!!还是要知道的!!!

到此这篇关于浅析JavaScript中的事件委托机制跟深浅拷贝的文章就介绍到这了,更多相关js事件委托深浅拷贝内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
HTML 自动伸缩的表格Table js实现
Apr 01 Javascript
jQuery随便控制任意div隐藏的方法
Jun 28 Javascript
jquery 合并内容相同的单元格(示例代码)
Dec 13 Javascript
js与C#进行时间戳转换
Nov 14 Javascript
javascript比较两个日期相差天数的方法
Jul 23 Javascript
jquery实现图片水平滚动效果代码分享
Aug 26 Javascript
jQuery获取父元素及父节点的方法小结
Apr 14 Javascript
AngularGauge 属性解析详解
Sep 06 Javascript
jQuery插件echarts实现的多柱子柱状图效果示例【附demo源码下载】
Mar 04 Javascript
jQuery滚动插件scrollable.js用法分析
May 25 jQuery
JavaScript实现树的遍历算法示例【广度优先与深度优先】
Oct 26 Javascript
浅谈Vue数据响应
Nov 05 Javascript
详解vue之自行实现派发与广播(dispatch与broadcast)
Jan 19 #Vue.js
js实现电灯开关效果
Jan 19 #Javascript
jquery实现穿梭框功能
Jan 19 #jQuery
jQuery实现穿梭框效果
Jan 19 #jQuery
element el-table表格的二次封装实现(附表格高度自适应)
Jan 19 #Javascript
JS实现纸牌发牌动画
Jan 19 #Javascript
微信小程序canvas实现签名功能
Jan 19 #Javascript
You might like
php一些公用函数的集合
2008/03/27 PHP
PHP判断文件是否存在、是否可读、目录是否存在的代码
2012/10/03 PHP
php pdo操作数据库示例
2017/03/10 PHP
js列举css中所有图标的实现代码
2011/07/04 Javascript
jquery 卷帘效果实现代码(不同方向)
2013/02/05 Javascript
chrome浏览器不支持onmouseleave事件的解决技巧
2013/05/31 Javascript
JS控制伪元素的方法汇总
2016/04/06 Javascript
jQuery模拟完美实现经典FLASH导航动画效果【附demo源码下载】
2016/11/09 Javascript
jquery实现简单的瀑布流布局
2016/12/11 Javascript
微信小程序 radio单选框组件详解及实例代码
2017/01/10 Javascript
vue实现ToDoList简单实例
2017/02/07 Javascript
Angular.JS中指令ng-if的注意事项小结
2017/06/21 Javascript
基于JS实现仿京东搜索栏随滑动透明度渐变效果
2017/07/10 Javascript
JS设计模式之访问者模式定义与用法分析
2018/02/05 Javascript
jQuery实现的简单图片轮播效果完整示例
2018/02/08 jQuery
React全家桶环境搭建过程详解
2018/05/18 Javascript
Vue中component标签解决项目组件化操作
2020/09/04 Javascript
[02:48]DOTA2英雄基础教程 拉席克
2013/12/12 DOTA
[04:29]【TI9采访】OG.N0tail在胜者组决赛后接受采访
2019/08/25 DOTA
[38:39]完美世界DOTA2联赛循环赛 IO vs GXR BO2第二场 11.04
2020/11/05 DOTA
深入理解Django的自定义过滤器
2017/10/17 Python
浅谈python 线程池threadpool之实现
2017/11/17 Python
Ubuntu下升级 python3.7.1流程备忘(推荐)
2018/12/10 Python
python列表使用实现名字管理系统
2019/01/30 Python
python实现按行分割文件
2019/07/22 Python
pytorch方法测试详解——归一化(BatchNorm2d)
2020/01/15 Python
基于tensorflow指定GPU运行及GPU资源分配的几种方式小结
2020/02/03 Python
Python tkinter实现简单加法计算器代码实例
2020/05/13 Python
python判断字符串以什么结尾的实例方法
2020/09/18 Python
大一自我鉴定范文
2013/10/04 职场文书
大学生村官承诺书
2014/03/28 职场文书
党员干部民主生活会议批评与自我批评材料
2014/09/20 职场文书
李强优秀员工观后感
2015/06/16 职场文书
幼儿园开学温馨提示
2015/07/15 职场文书
怎样写工作总结啊!
2019/06/18 职场文书
springboot+WebMagic+MyBatis爬虫框架的使用
2021/08/07 Java/Android