浅析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跨页面保存变量做菜单的方法
Jan 17 Javascript
JQuery Ajax 跨域访问的解决方案
Mar 12 Javascript
Js数组排序函数sort()介绍
Jun 08 Javascript
javascript处理a标签超链接默认事件的方法
Jun 29 Javascript
快速掌握WordPress中加载JavaScript脚本的方法
Dec 17 Javascript
在Linux系统中搭建Node.js开发环境的简单步骤讲解
Jan 26 Javascript
Javascript中的arguments对象
Jun 20 Javascript
KnockoutJS 3.X API 第四章之数据控制流with绑定
Oct 10 Javascript
vue 通过下拉框组件学习vue中的父子通讯
Dec 19 Javascript
详解ES6 Promise对象then方法链式调用
Oct 20 Javascript
vue生命周期的探索
Apr 03 Javascript
elementUI Tree 树形控件的官方使用文档
Apr 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
咖啡界又出新概念,无需咖啡豆的分子咖啡
2021/03/03 咖啡文化
从康盛产品(discuz)提取出来的模板类
2011/06/28 PHP
php实现四舍五入的方法小结
2015/03/03 PHP
php使用MySQL保存session会话的方法
2015/06/18 PHP
php 获取文件行数的方法总结
2016/10/11 PHP
PHP实现合并两个排序链表的方法
2018/01/19 PHP
Javascript实例教程(19) 使用HoTMetal(2)
2006/12/23 Javascript
javascript获取url上某个参数的方法
2013/11/08 Javascript
javascript复制粘贴与clipboardData的使用
2014/10/16 Javascript
解决Vue 浏览器后退无法触发beforeRouteLeave的问题
2017/12/24 Javascript
JavaScript学习笔记之数组基本操作示例
2019/01/09 Javascript
Vue中遍历数组的新方法实例详解
2019/07/21 Javascript
JavaScript canvas基于数组生成柱状图代码实例
2020/03/06 Javascript
vue-iview动态新增和删除的方法
2020/06/17 Javascript
[01:02:53]DOTA2上海特级锦标赛主赛事日 - 5 总决赛Liquid VS Secret第二局
2016/03/06 DOTA
python3音乐播放器简单实现代码
2020/04/20 Python
Python中的几种矩阵乘法(小结)
2019/07/10 Python
python实现windows倒计时锁屏功能
2019/07/30 Python
python使用celery实现异步任务执行的例子
2019/08/28 Python
flask 使用 flask_apscheduler 做定时循环任务的实现
2019/12/10 Python
简单了解为什么python函数后有多个括号
2019/12/19 Python
python百行代码自制电脑端网速悬浮窗的实现
2020/05/12 Python
如何使用python的ctypes调用医保中心的dll动态库下载医保中心的账单
2020/05/24 Python
Python基于内置函数type创建新类型
2020/10/22 Python
css3实例教程 一款纯css3实现的环形导航菜单
2014/10/20 HTML / CSS
Paul’s Boutique官网:英国时尚手袋品牌
2018/03/31 全球购物
杭州时比特电子有限公司SQL
2013/08/22 面试题
销售总监岗位职责
2014/01/04 职场文书
学校门卫管理制度
2014/01/30 职场文书
售后服务经理岗位职责范本
2014/02/22 职场文书
《孔子游春》教学反思
2014/02/25 职场文书
2014大学生批评与自我批评思想汇报
2014/09/21 职场文书
postgreSQL数据库基础知识介绍
2022/04/12 PostgreSQL
Elasticsearch 配置详解
2022/04/19 Java/Android
apache ftpserver搭建ftp服务器
2022/05/20 Servers
移除Selenium中window.navigator.webdriver值
2022/06/10 Python