浅析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 相关文章推荐
图片连续滚动代码[兼容IE/firefox]
Jun 11 Javascript
通过隐藏option实现select的联动效果
Nov 10 Javascript
JavaScript NaN和Infinity特殊值 [译]
Sep 20 Javascript
DWZ table的原生分页浅谈
Mar 01 Javascript
JQuery中DOM事件冒泡实例分析
Jun 13 Javascript
JavaScript 最佳实践:帮你提升代码质量
Dec 03 Javascript
微信小程序 跳转传递数据的实例
Jul 06 Javascript
JavaScript实现简单生成随机颜色的方法
Sep 21 Javascript
JavaScript 正则命名分组【推荐】
Jun 07 Javascript
详解vue中的computed的this指向问题
Dec 05 Javascript
vue 解决在微信内置浏览器中调用支付宝支付的情况
Nov 09 Javascript
深入浅析React中diff算法
May 19 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之数组学习
2011/05/29 PHP
Zend Framework实现Zend_View集成Smarty模板系统的方法
2016/03/05 PHP
php接口技术实例详解
2016/12/07 PHP
php利用云片网实现短信验证码功能的示例代码
2017/11/18 PHP
php设计模式之职责链模式定义与用法经典示例
2019/09/19 PHP
PHP-FPM 设置多pool及配置文件重写操作示例
2019/10/02 PHP
High Performance JavaScript(高性能JavaScript)读书笔记分析
2011/05/05 Javascript
js Math 对象的方法
2013/09/01 Javascript
深入分析原生JavaScript事件
2014/12/29 Javascript
js实现文本框只允许输入数字并限制数字大小的方法
2015/08/19 Javascript
jQuery实现伪分页的方法分享
2016/02/17 Javascript
jQuery实现选项联动轮播效果【附实例】
2016/04/19 Javascript
js删除Array数组中指定元素的两种方法
2016/08/03 Javascript
详解微信小程序的 request 封装示例
2018/08/21 Javascript
3分钟读懂移动端rem使用方法(推荐)
2019/05/06 Javascript
Vue.js中provide/inject实现响应式数据更新的方法示例
2019/10/16 Javascript
js DOM的事件常见操作实例详解
2019/12/16 Javascript
JavaScript常用工具函数库汇总
2020/09/17 Javascript
[03:39]2015国际邀请赛主赛事首日精彩回顾
2015/08/05 DOTA
[02:56]DOTA2上海特锦赛小组赛解说FreeAgain采访花絮
2016/02/27 DOTA
python操作sqlite的CRUD实例分析
2015/05/08 Python
Django使用中间件解决前后端同源策略问题
2019/09/02 Python
Python StringIO如何在内存中读写str
2020/01/07 Python
python中数据库like模糊查询方式
2020/03/02 Python
python GUI库图形界面开发之PyQt5滚动条控件QScrollBar详细使用方法与实例
2020/03/06 Python
Python socket连接中的粘包、精确传输问题实例分析
2020/03/24 Python
电气自动化大学生求职信
2013/10/16 职场文书
校园歌咏比赛主持词
2014/03/18 职场文书
文艺晚会主持词
2014/03/24 职场文书
2014年妇产科工作总结
2014/12/08 职场文书
预备党员介绍人意见
2015/06/01 职场文书
教你如何使用Python实现二叉树结构及三种遍历
2021/06/18 Python
css中z-index: 0和z-index: auto的区别
2021/08/23 HTML / CSS
Python中第三方库Faker的使用详解
2022/04/02 Python
python微信智能AI机器人实现多种支付方式
2022/04/12 Python
一文了解Java动态代理的原理及实现
2022/07/07 Java/Android