浅析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 相关文章推荐
JavaScript对象、属性、事件手册集合方便查询
Jul 04 Javascript
JavaScript Serializer序列化时间处理示例
Jul 31 Javascript
js实现获取当前时间是本月第几周的方法
Aug 11 Javascript
深入浅出ES6之let和const命令
Aug 25 Javascript
js 判断各种数据类型的简单方法(推荐)
Aug 29 Javascript
JS实现HTML标签转义及反转义
Apr 14 Javascript
JS实现旋转木马式图片轮播效果
Jan 18 Javascript
jquery submit()不能提交表单的解决方法
Apr 24 jQuery
微信小程序的mpvue框架快速上手指南
May 15 Javascript
ES6使用新特性Proxy实现的数据绑定功能实例
May 11 Javascript
通过实例解析js可枚举属性与不可枚举属性
Dec 02 Javascript
浅谈Web Storage API的使用
Jun 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无限分类的类
2007/01/02 PHP
php使用多个进程同时控制文件读写示例
2014/02/28 PHP
php数组键值用法实例分析
2015/02/27 PHP
php将字符串全部转换成大写或者小写的方法
2015/03/17 PHP
PHP函数func_num_args用法实例分析
2015/12/07 PHP
浅谈PHP的exec()函数无返回值排查方法(必看)
2017/03/31 PHP
PHP 应用容器化以及部署方法
2018/02/12 PHP
浅析Javascript使用include/require
2013/11/13 Javascript
使用text方法获取Html元素文本信息示例
2014/09/01 Javascript
jQuery性能优化技巧分析
2015/02/20 Javascript
JavaScript中window.open用法实例详解
2015/04/15 Javascript
Nodejs express框架一个工程中同时使用ejs模版和jade模版
2015/12/28 NodeJs
js实现搜索框关键字智能匹配代码
2020/03/26 Javascript
手机端 HTML5使用photoswipe.js仿微信朋友圈图片放大效果
2016/08/25 Javascript
javascript笔记之匿名函数和闭包
2017/02/06 Javascript
Vue表单demo v-model双向绑定问题
2018/06/29 Javascript
基于Node.js搭建hexo博客过程详解
2019/06/25 Javascript
VUE实时监听元素距离顶部高度的操作
2020/07/29 Javascript
JS删除对象中某一属性案例详解
2020/09/08 Javascript
python实现随机密码字典生成器示例
2014/04/09 Python
对于Python编程中一些重用与缩减的建议
2015/04/14 Python
Python简单操作sqlite3的方法示例
2017/03/22 Python
深入学习Python中的上下文管理器与else块
2017/08/27 Python
Python for循环中的陷阱详解
2018/07/13 Python
python使用matplotlib模块绘制多条折线图、散点图
2020/04/26 Python
Python中flatten( )函数及函数用法详解
2018/11/02 Python
详解Python正则表达式re模块
2019/03/19 Python
11个Python3字典内置方法大全与示例汇总
2019/05/13 Python
自定义django admin model表单提交的例子
2019/08/23 Python
关于Tensorflow使用CPU报错的解决方式
2020/02/05 Python
十佳青年个人事迹材料
2014/01/28 职场文书
医学求职信
2014/05/28 职场文书
师德师风建设整改措施思想汇报
2014/10/11 职场文书
2014年妇女工作总结
2014/12/06 职场文书
2015圣诞节贺卡寄语
2015/03/24 职场文书
MySQL控制流函数(-if ,elseif,else,case...when)
2022/07/07 MySQL