浅析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 相关文章推荐
(推荐一个超好的JS函数库)S.Sams Lifexperience ScriptClassLib
Apr 29 Javascript
FireBug 调试JS入门教程 如何调试JS
Dec 23 Javascript
js判断设备是否为PC并调整图片大小
Feb 12 Javascript
JavaScript调用浏览器打印功能实例分析
Jul 17 Javascript
JavaScript实现的经典文件树菜单效果
Sep 08 Javascript
利用js编写响应式侧边栏
Sep 17 Javascript
Node.js五大应用性能技巧小结(必须收藏)
Aug 09 Javascript
html中通过JS获取JSON数据并加载的方法
Nov 30 Javascript
如何开发出更好的JavaScript模块
Dec 22 Javascript
基于jQuery实现Ajax验证用户名是否可用实例
Mar 25 jQuery
js观察者模式的弹幕案例
Nov 23 Javascript
vuex页面刷新导致数据丢失的解决方案
Dec 10 Vue.js
详解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
IIS7.X配置PHP运行环境小结
2011/06/09 PHP
php中日期加减法运算实现代码
2011/12/08 PHP
javascript学习笔记(九)javascript中的原型(prototype)及原型链的继承方式
2011/04/12 Javascript
jQuery使用一个按钮控制图片的伸缩实现思路
2013/04/19 Javascript
jQuery实现带有动画效果的回到顶部和底部代码
2015/11/04 Javascript
JavaScript脚本库编写的方法
2015/12/09 Javascript
jQuery中通过ajax的get()函数读取页面的方法
2016/02/29 Javascript
基于Bootstrap+jQuery.validate实现表单验证
2016/05/30 Javascript
Javascript中apply、call、bind的巧妙使用
2016/08/18 Javascript
JavaScript ES6中CLASS的使用详解
2016/11/22 Javascript
nodejs连接mongodb数据库实现增删改查
2016/12/01 NodeJs
Json按某个键的值进行排序
2016/12/22 Javascript
js仿京东轮播效果 选项卡套选项卡使用
2017/01/12 Javascript
你应该知道的几类npm依赖包管理详解
2017/10/06 Javascript
Vue组件间通信 Vuex的用法解析
2019/08/05 Javascript
微信小程序实现简单的select下拉框
2020/11/23 Javascript
[40:05]LGD vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
详解python使用递归、尾递归、循环三种方式实现斐波那契数列
2018/01/16 Python
linux下python使用sendmail发送邮件
2018/05/22 Python
Python下调用Linux的Shell命令的方法
2018/06/12 Python
python脚本之一键移动自定格式文件方法实例
2019/09/02 Python
centos+nginx+uwsgi+Django实现IP+port访问服务器
2019/11/15 Python
实现Python与STM32通信方式
2019/12/18 Python
Python如何爬取b站热门视频并导入Excel
2020/08/10 Python
手把手教你将Flask应用封装成Docker服务的实现
2020/08/19 Python
python爬取豆瓣电影排行榜(requests)的示例代码
2021/02/18 Python
台湾东南旅游社网站:东南旅游
2019/02/11 全球购物
九年级家长会邀请函
2014/01/15 职场文书
《找不到快乐的波斯猫》教学反思
2014/02/24 职场文书
2015年上半年计生工作总结
2015/03/30 职场文书
普通员工辞职信范文
2015/05/12 职场文书
聚众斗殴罪辩护词
2015/05/21 职场文书
小学语文新课改心得体会
2016/01/22 职场文书
年会邀请函的格式及范文五篇
2019/11/02 职场文书
Nginx tp3.2.3 404问题解决方案
2021/03/31 Servers
Spring this调用当前类方法无法拦截的示例代码
2022/03/20 Java/Android