开篇语
突然有一种感觉,每次学习一个知识点就像是谈一场恋爱:从首次邂逅,到彼此理解,所有都那么的合乎恋爱的过程!
如果这个知识点再有点”淘气“的话,那几乎是让人欲仙欲死而又不可自拔!因为你永远不晓得它还有多少面纱等着你揭开,当你自认为对它曾经足够理解的时候,冷不防就是一个盲点迎面砸来。
它几乎就像一个”宝藏女孩“,你要时刻做好迎接”惊喜“的筹备!
可能正是因为这种新鲜感,我能力始终放弃一种相似亢奋的状态吧。当然,这只是针对常识而言,看待情感我还是很激进很专一的 <(~︶~)>
这两天,我就在和定时器谈恋爱,哦不,是在学习定时器(~▽~)~*,可没想到,又给陷进去了……
这不,上一篇文章写完定时器的返回值后,刚感觉本人对它曾经理解的清清楚楚明明白白了,够我夸耀一阵子了,谁成想,喘口气的功夫,它又给我整出了幺蛾子。
惑起
写完上篇文章后,我就推敲着外面的实现代码还能够优化一下,于是给改成了上面这个样子:
<form action=""class="example-form">
<div>
<label for="name">
名称
</label>
<input class="input-ele" type="text" name="name" id="name" placeholder="please input your name"
autocomplete="off">
</div>
<div style="margin-top:50px;">
<label for="res">
输出
</label>
<textarea class="input-ele" type="multipart" name="res" id="res" readonly
placeholder="这里是每一次输出的后果"></textarea>
</div>
</form>
<script>
window.onload = function () {const resEle = document.querySelector("#res");
function changeOutputVal() {resEle.value += `\n${ this.value}`;
}
function throttle(fun, delay) {
let last, deferTimer
return function () {let now = Date.now();
if (last && now < last + delay) {clearTimeout(deferTimer);
deferTimer = setTimeout(function () {
last = now;
fun.apply(this);
}, delay)
} else {
last = now;
fun.apply(this);
}
}
}
const inputEle = document.querySelector("#name");
inputEle.addEventListener("input", throttle(changeOutputVal, 1000));
}
</script>
我的批改根据是:
- throttle 办法返回的是一个匿名函数,这个函数正好充当 input 事件的回调函数
- input 事件回调函数中的 this 指向的是 inputEle
- 匿名函数中将 this 绑定给了 fun 参数,而理论应用中传入的是 changeOutputVal 办法
- 所以 changeOutputVal 办法中的 this 指的就是 inputEle,所以在它外面能够通过
this.value
获取到 inputEle 的值
看,这逻辑多谨严,几乎有条有理啊 \(~︶~)/
按理说,是没问题的吧,后果却出问题了。欲知详情,请看大屏幕:
这个 undefined 是什么鬼?!从哪冒出来的?难道我的延时器没用对?
解惑
面对我的质疑,setTimeout 名正言顺地说:人家回调函数中的 this 原本就是指向 window 对象的嘛,你也没早问啊!
那么,问题来了:为什么延时器中的 this 指向的是 window 呢?setTimeout 本人也解释不分明了。
得,看来前人诚不我欺也——本人入手,饥寒交迫!
凡事不决找 MDN,相对靠谱!咱们来看看 MDN 怎么说:
由
setTimeout()
调用的代码运行在与所在函数齐全拆散的执行环境上。这会导致,这些代码中蕴含的this
关键字在非严格模式会指向window
(或全局)对象,严格模式下为 undefined,这和所冀望的this
的值是不一样的。
看到这个解释,我才明确:this 指向 window 对象,原来是因为 执行环境 的不同导致的。
在下面的代码中,因为 window 对象没有 value 这个属性,所以 window.value = undefined
。
感觉本人在业余的方向上又迈进了一小步,容我小小地嘚瑟一下!
改错
既然晓得问题出在哪,那就好办了,咱们只须要将 setTimeout 回到函数外部的 this 指向扭转一下就好,这里有以下计划。
应用变量援用内部 this
要害代码如下:
window.onload = function () {
// some code here
const that = this;
deferTimer = setTimeout(function () {
last = now;
fun.apply(that);
}, delay)
// some code here
}
应用箭头函数
利用箭头函数不会扭转 this 的指向的个性,革新如下:
window.onload = function () {
// some code here
deferTimer = setTimeout(() => {
last = now;
fun.apply(this);
}, delay)
// some code here
}
结束语
知错能改,善莫大焉!
写到这里,我竟然领会到了今人那种”朝闻道,夕死可矣“的满足感。
在编程这条路上,可能遍布荆棘,但只有咱们勤耕不辍,总能开拓出属于本人的坎坷不平!
这鸡汤太美味,我先干为敬,你们随便!b(~▽~)d
~
~
~ 本文完,感激浏览!
~
学习乏味的常识,结识乏味的敌人,塑造乏味的灵魂!
我是〖编程三昧〗的作者 隐逸王,我的公众号是『编程三昧』,欢送关注,心愿大家多多指教!
你来,怀揣冀望,我有墨香相迎!你归,无论得失,唯以余韵相赠!
常识与技能并重,内力和外功兼修,实践和实际两手都要抓、两手都要硬!