浅析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 相关文章推荐
jquery判断RadioButtonList和RadioButton中是否有选中项示例
Sep 29 Javascript
点击标签切换和自动切换DIV选项卡
Aug 10 Javascript
JavaScript实现获取dom中class的方法
Feb 09 Javascript
JS判断是否长按某一键的方法
Mar 02 Javascript
基于JavaScript实现鼠标箭头移动图片跟着移动
Aug 30 Javascript
JS正则表达式之非捕获分组用法实例分析
Dec 28 Javascript
jquery操作ul的一些操作笔记整理(干货)
Aug 31 jQuery
jQuery动态移除与增加onclick属性的方法详解
Jun 07 jQuery
微信小程序将字符串生成二维码图片的操作方法
Jul 17 Javascript
详解关于Vue2.0路由开启keep-alive时需要注意的地方
Sep 18 Javascript
JavaScript面试中常考的字符串操作方法大全(包含ES6)
May 10 Javascript
解决vue bus.$emit触发第一次$on监听不到问题
Jul 28 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
正则表达式语法
2006/10/09 Javascript
PHP教程 变量定义
2009/10/23 PHP
PHP has encountered an Access Violation 错误的解决方法
2010/01/17 PHP
收集的二十一个实用便利的PHP函数代码
2010/04/22 PHP
php的memcache类分享(memcache队列)
2014/03/26 PHP
PHP基于简单递归函数求一个数阶乘的方法示例
2017/04/26 PHP
javascript一元操作符(递增、递减)使用示例
2013/08/07 Javascript
AngularJS+Node.js实现在线聊天室
2015/08/28 Javascript
原生js实现图片轮播特效
2015/12/18 Javascript
JavaScript电子时钟倒计时
2016/01/09 Javascript
JavaScript的Backbone.js框架的一些使用建议整理
2016/02/14 Javascript
jQuery学习笔记之回调函数
2016/08/15 Javascript
详解angular中如何监控dom渲染完毕
2017/01/03 Javascript
详解nodejs中exports和module.exports的区别
2017/02/17 NodeJs
关于Vue背景图打包之后访问路径错误问题的解决
2017/11/03 Javascript
vue-cli的build的文件夹下没有dev-server.js文件配置mock数据的方法
2019/04/17 Javascript
koa+jwt实现token验证与刷新功能
2019/05/30 Javascript
vue+element-ui表格封装tag标签使用插槽
2020/06/18 Javascript
[49:58]完美世界DOTA2联赛PWL S3 Magma vs DLG 第一场 12.18
2020/12/19 DOTA
网站渗透常用Python小脚本查询同ip网站
2017/05/08 Python
Python实现复杂对象转JSON的方法示例
2017/06/22 Python
python实现简单图片物体标注工具
2019/03/18 Python
python卸载后再次安装遇到的问题解决
2019/07/10 Python
python做接口测试的必要性
2019/11/20 Python
python中os.remove()用法及注意事项
2021/01/31 Python
详解解决jupyter不能使用pytorch的问题
2021/02/18 Python
全球精选男装和家居用品:Article
2020/04/13 全球购物
在Ajax应用中信息是如何在浏览器和服务器之间传递的
2016/05/31 面试题
银行批评与自我批评
2014/02/10 职场文书
含预算的公司户外活动方案
2014/08/16 职场文书
员工辞职信范文
2015/03/02 职场文书
年度考核表个人总结
2015/03/06 职场文书
自荐信模板大全
2015/03/27 职场文书
工作时间调整通知
2015/04/24 职场文书
师范生见习总结范文
2015/06/23 职场文书
学校学习型党组织建设心得体会
2019/06/21 职场文书