浅析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的jquery实例代码另附去除js方法
Apr 30 Javascript
Javascript添加监听与删除监听用法详解
Dec 19 Javascript
js事件源window.event.srcElement兼容性写法(详解)
Nov 25 Javascript
js鼠标经过tab选项卡时实现切换延迟
Mar 24 Javascript
Bootstrap实现基于carousel.js框架的轮播图效果
May 02 Javascript
javascript编写简易计算器
May 06 Javascript
解决vue页面DOM操作不生效的问题
Mar 17 Javascript
浅谈Webpack打包优化技巧
Jun 12 Javascript
vue实现动态添加数据滚动条自动滚动到底部的示例代码
Jul 06 Javascript
js for终止循环 跳出多层循环
Oct 04 Javascript
JS函数内部属性之arguments和this实例解析
Oct 07 Javascript
JS实现旋转木马轮播图
Jan 01 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
smarty的保留变量问题
2008/10/23 PHP
PHP笔记之:基于面向对象设计的详解
2013/05/14 PHP
深入理解用mysql_fetch_row()以数组的形式返回查询结果
2013/06/05 PHP
探讨如何在PHP开启gzip页面压缩实例
2013/06/09 PHP
PHP开发制作一个简单的活动日程表Calendar
2016/06/20 PHP
TNC vs IO BO3 第一场2.13
2021/03/10 DOTA
JavaScript中的私有成员
2006/09/18 Javascript
JavaScript 拾漏补遗
2009/12/27 Javascript
用JS做的简单的可折叠的两级树形菜单
2013/09/21 Javascript
jQuery javaScript捕获回车事件(示例代码)
2013/11/07 Javascript
jquery和ajax的关系详细介绍
2013/11/29 Javascript
jQuery中:gt选择器用法实例
2014/12/29 Javascript
KnockoutJS 3.X API 第四章之数据控制流if绑定和ifnot绑定
2016/10/10 Javascript
基于Vue实现timepicker
2017/04/25 Javascript
web页面和微信小程序页面实现瀑布流效果
2018/09/26 Javascript
微信小程序实现canvas分享朋友圈海报
2020/06/21 Javascript
vue动画—通过钩子函数实现半场动画操作
2020/08/09 Javascript
python按照多个字符对字符串进行分割的方法
2015/03/17 Python
Python浅拷贝与深拷贝用法实例
2015/05/09 Python
python抓取文件夹的所有文件
2018/02/27 Python
Python内置函数reversed()用法分析
2018/03/20 Python
pycharm debug功能实现跳到循环末尾的方法
2018/11/29 Python
Python面向对象之类和实例用法分析
2019/06/08 Python
python爬虫爬取幽默笑话网站
2019/10/24 Python
naturalizer加拿大官网:美国娜然女鞋
2017/04/04 全球购物
戴森英国官网:Dyson英国
2019/05/07 全球购物
小学毕业感言50字
2014/02/16 职场文书
班级安全教育实施方案
2014/02/23 职场文书
企业安全生产演讲稿
2014/05/09 职场文书
《蜜蜂引路》教学反思
2016/02/22 职场文书
汽车销售合同文本
2019/08/08 职场文书
tensorflow中的数据类型dtype用法说明
2021/05/26 Python
解决SpringCloud Feign传对象参数调用失败的问题
2021/06/23 Java/Android
Html5同时支持多端sdk的小技巧
2021/11/17 HTML / CSS
分享7个 Python 实战项目练习
2022/03/03 Python
vue-cli3.0修改打包后的文件名和文件地址,打包后本地运行报错解决
2022/04/06 Vue.js