浅析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 跨域访问问题解决方法(笔记)
Jun 08 Javascript
基于JQuery的Select选择框的华丽变身
Aug 23 Javascript
js中的replace方法使用介绍
Oct 28 Javascript
jquery单行文字向上滚动效果的实现代码
Sep 05 Javascript
js实现input密码框提示信息的方法(附html5实现方法)
Jan 14 Javascript
Bootstrap选项卡与Masonry插件的完美结合
Jul 06 Javascript
JavaScript数据类型学习笔记分享
Sep 01 Javascript
详解Jquery Easyui的验证扩展
Jan 09 Javascript
Javascript中 toFixed四舍六入方法
Aug 21 Javascript
微信小程序签到功能
Oct 31 Javascript
js操作table中tr的顺序实现上移下移一行的效果
Nov 22 Javascript
JS大坑之19位数的Number型精度丢失问题详解
Apr 22 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实现文件编码批量转换
2014/03/10 PHP
smarty高级特性之对象的使用方法
2015/12/25 PHP
Yii2使用swiftmailer发送邮件的方法
2016/05/03 PHP
JavaScript 无符号右移运算符
2009/04/17 Javascript
给文字加上着重号的JS代码
2013/11/12 Javascript
JS两种定义方式的区别、内部原理
2013/11/21 Javascript
本人自用的global.js库源码分享
2015/02/28 Javascript
在JavaScript应用中实现延迟加载的方法
2015/06/25 Javascript
js数组去重的方法汇总
2015/07/29 Javascript
后端接收不到AngularJs中$http.post发送的数据原因分析及解决办法
2016/07/05 Javascript
BootStrap fileinput.js文件上传组件实例代码
2017/02/20 Javascript
jQuery异步提交表单实例
2017/05/30 jQuery
mui框架 页面无法滚动的解决方法(推荐)
2018/01/25 Javascript
JavaScript变量声明var,let.const及区别浅析
2018/04/23 Javascript
记一次webpack3升级webpack4的踩坑经历
2018/06/12 Javascript
javascript实现小型区块链功能
2019/04/03 Javascript
vue+element创建动态的form表单及动态生成表格的行和列
2019/05/20 Javascript
ES6 Generator函数的应用实例分析
2019/06/26 Javascript
[00:43]TI7不朽珍藏III——幽鬼不朽展示
2017/07/15 DOTA
Python实现CET查分的方法
2015/03/10 Python
简单介绍Python中的readline()方法的使用
2015/05/24 Python
qpython3 读取安卓lastpass Cookies
2016/06/19 Python
python爬虫_微信公众号推送信息爬取的实例
2017/10/23 Python
简单了解Python中的几种函数
2017/11/03 Python
解决Python列表字符不区分大小写的问题
2019/12/19 Python
python 读写文件包含多种编码格式的解决方式
2019/12/20 Python
使用Python项目生成所有依赖包的清单方式
2020/07/13 Python
五分钟学会怎么用Pygame做一个简单的贪吃蛇
2021/01/06 Python
TIME时代杂志台湾总代理:台时亚洲
2018/10/22 全球购物
Monki官网:斯堪的纳维亚的独立时尚品牌
2020/11/09 全球购物
教育系毕业生中文求职信范文
2013/10/06 职场文书
自我介绍演讲稿
2014/01/15 职场文书
行政主管岗位职责
2015/02/03 职场文书
写给同学的新学期寄语
2015/02/27 职场文书
欢迎新生标语2015
2015/07/16 职场文书
Vue操作Storage本地化存储
2022/04/29 Vue.js