浅析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 相关文章推荐
addEventListener()第三个参数useCapture (Boolean)详细解析
Nov 07 Javascript
Js Jquery创建一个弹出层可加载一个页面
May 08 Javascript
js删除Array数组中指定元素的两种方法
Aug 03 Javascript
HTML页面定时跳转方法解析(2种任选)
Dec 22 Javascript
js实现多张图片延迟加载效果
Jul 17 Javascript
详解使用Vue Router导航钩子与Vuex来实现后退状态保存
Sep 11 Javascript
帝国cms首页列表页实现点赞功能
Oct 30 Javascript
JS脚本实现网页自动秒杀点击
Jan 11 Javascript
js 索引下标之li集合绑定点击事件
Jan 12 Javascript
js获取html页面代码中图片地址的实现代码
Mar 05 Javascript
Webpack devServer中的 proxy 实现跨域的解决
Jun 15 Javascript
javascript实现左右缓动动画函数
Nov 25 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
QQ登录 PHP OAuth示例代码
2011/07/20 PHP
php实现给一张图片加上水印效果
2016/01/02 PHP
(转载)JavaScript中匿名函数,函数直接量和闭包
2007/05/08 Javascript
很酷的javascript loading效果代码
2008/06/18 Javascript
JS array 数组详解
2009/03/22 Javascript
从父页面读取和操作iframe中内容方法
2009/07/25 Javascript
IE6下JS动态设置图片src地址问题
2010/01/08 Javascript
jquery和javascript的区别(常用方法比较)
2013/07/04 Javascript
原生javascript实现分享到朋友圈功能 支持ios和android
2016/05/11 Javascript
jQuery使用中可能被XSS攻击的一些危险环节提醒
2016/05/24 Javascript
Vue中建立全局引用或者全局命令的方法
2017/08/21 Javascript
轻松玩转BootstrapTable(后端使用SpringMVC+Hibernate)
2017/09/06 Javascript
vue 中directive功能的简单实现
2018/01/05 Javascript
基于axios封装fetch方法及调用实例
2018/02/05 Javascript
vue2.0 路由模式mode=&quot;history&quot;的作用
2018/10/18 Javascript
jQuery实现的卷帘门滑入滑出效果【案例】
2019/02/18 jQuery
JavaScript表格隔行变色和Tab标签页特效示例【附jQuery版】
2019/07/11 jQuery
使用layui实现树形结构的方法
2019/09/20 Javascript
[01:01:43]EG vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
videocapture库制作python视频高速传输程序
2013/12/23 Python
Python enumerate索引迭代代码解析
2018/01/19 Python
python命令行工具Click快速掌握
2019/07/04 Python
使用python turtle画高达
2020/01/19 Python
Staples加拿大官方网站:办公用品一站式采购
2016/09/25 全球购物
Sunglasses Shop丹麦:欧洲第一的太阳镜在线销售网站
2017/10/22 全球购物
英国第一摩托车和摩托车越野配件商店:GhostBikes
2019/03/10 全球购物
新电JAVA笔试题目
2014/08/31 面试题
Linux上比较文件的命令都有哪些
2012/02/24 面试题
信用社实习人员自我鉴定
2013/09/20 职场文书
大学生毕业求职简历的自我评价
2013/10/24 职场文书
财务部副经理岗位职责
2014/03/14 职场文书
幼儿教师寄语集锦
2014/04/03 职场文书
社团活动总结怎么写
2014/06/30 职场文书
法英专业大学生职业生涯规划范文:衡外情,量己力!
2014/09/23 职场文书
2019年图书室自查报告范本
2019/10/12 职场文书
vue实现简单数据双向绑定
2021/04/28 Vue.js