浅析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 遍历json数组的实现代码
Sep 22 Javascript
js之onload事件的一点使用心得
Aug 14 Javascript
Query中click(),bind(),live(),delegate()的区别
Nov 19 Javascript
jQuery中toggle()函数的使用实例
Apr 17 Javascript
javascript实现淡蓝色的鼠标拖动选择框实例
May 09 Javascript
jQuery实现摸拟alert提示框
May 22 Javascript
原生js的数组除重复简单实例
May 24 Javascript
利用jquery实现瀑布流3种案例
Sep 18 Javascript
javascript实现简易计算器
Feb 01 Javascript
Linux使用Node.js建立访问静态网页的服务实例详解
Mar 21 Javascript
vue.js实现刷新当前页面的方法教程
Jul 05 Javascript
angular4自定义表单控件[(ngModel)]的实现
Nov 23 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使用ob_flush不能每隔一秒输出原理分析
2015/06/02 PHP
php采集中国代理服务器网的方法
2015/06/16 PHP
php实现搜索一维数组元素并删除二维数组对应元素的方法
2015/07/06 PHP
分享微信扫码支付开发遇到问题及解决方案-附Ecshop微信支付插件
2015/08/23 PHP
PHP基于socket实现的简单客户端和服务端通讯功能示例
2017/07/10 PHP
PHP弱类型语言中类型判断操作实例详解
2017/08/10 PHP
确保Laravel网站不会被嵌入到其他站点中的方法
2019/10/18 PHP
PHP正则之正向预查与反向预查讲解与实例
2020/04/06 PHP
元素的内联事件处理函数的特殊作用域在各浏览器中存在差异
2011/01/12 Javascript
用Javascript实现Windows任务管理器的代码
2012/03/27 Javascript
在Node.js中实现文件复制的方法和实例
2014/06/05 Javascript
javascript从image转换为base64位编码的String
2014/07/29 Javascript
2014年最火的Node.JS后端框架推荐
2014/10/27 Javascript
javascript实现俄罗斯方块游戏的思路和方法
2015/04/27 Javascript
js实现使用鼠标拖拽切换图片的方法
2015/05/04 Javascript
JavaScript中停止执行setInterval和setTimeout事件的方法
2015/05/14 Javascript
JS实现鼠标滑过折叠与展开菜单效果代码
2015/09/06 Javascript
快速学习JavaScript的6个思维技巧
2015/10/13 Javascript
AngularJS表达式讲解及示例代码
2016/08/16 Javascript
如何制作幻灯片(代码分享)
2017/01/06 Javascript
JS中Attr的用法详解
2017/10/09 Javascript
详解Vue组件之间通信的七种方式
2019/04/14 Javascript
vue组件创建的三种方式小结
2020/02/03 Javascript
node+vue实现文件上传功能
2020/05/28 Javascript
Python 时间操作例子和时间格式化参数小结
2014/04/24 Python
Go语言基于Socket编写服务器端与客户端通信的实例
2016/02/19 Python
Python实现将一个大文件按段落分隔为多个小文件的简单操作方法
2017/04/17 Python
python中Pycharm 输出中文或打印中文乱码现象的解决办法
2017/06/16 Python
使用Eclipse如何开发python脚本
2018/04/11 Python
基于HTML5 audio元素播放声音jQuery小插件
2011/05/11 HTML / CSS
美国糖果店:Sugarfina
2019/02/21 全球购物
自我评价怎么写正确呢?
2013/12/02 职场文书
抗洪抢险事迹材料
2014/05/06 职场文书
单位委托书范本(3篇)
2014/09/18 职场文书
2019最新激励员工口号大全!
2019/06/28 职场文书
Python实现批量将文件复制到新的目录中再修改名称
2022/04/12 Python