JavaScript中的this指向问题对于web前端入行不深的人来讲是个比较复杂的问题。特写此文章来记录今天遇到的关于匿名函数中this指向问题的思考和感悟。前端
今天在研究函数防抖场景时看到以下代码:web
function debounce(fn, delay) { var timer; // 维护一个 timer return function () { var _this = this; // 取debounce执行做用域的this var args = arguments; if (timer) { clearTimeout(timer); } timer = setTimeout(function () { fn.apply(_this, args); // 用apply指向调用debounce的对象,至关于_this.fn(args); }, delay); }; }
其中有一段代码是 var _this = this
这段代码出如今由return返回的匿名函数中,这个时候我就有些懵逼了,由于根据我匮乏的js知识,这里的this应该是指向全局做用域才对,为何能像注释那样指向debounce执行时的做用域呢?感受以下所写是否更加合理呢?(事实证实这么写确定是不对的)闭包
function debounce(fn, delay) { var timer var _this = this return function() { ... } }
因而我打算用代码来实测这里的 debounce执行做用域中的this到底指的是什么,它会变化吗?仍是根据个人理解只要是像相似的匿名函数其中的this都是指向全局的呢?app
因而我写下以下代码(关键部分):
body部分新增一个button标签函数
`<button>我是button</button>`
script标签内部代码以下:this
//函数防抖 function debounce(fn, delay) { var timer; // 维护一个 timer return function () { var _this = this; // 取debounce执行做用域的this var args = arguments; if (timer) { clearTimeout(timer); } timer = setTimeout(function () { fn.apply(_this, args); // 用apply指向调用debounce的对象,至关于_this.fn(args); }, delay); }; } var btn = document.getElementsByTagName('button')[0] btn.onclick= debounce(function() { console.log(this) }, 1000)
点击按钮,看看控制台输出this究竟是谁,按照我以前的理解输出的this应该是window全局对象才对spa
出乎意料,这里的this输出的是button元素,因而我再在上述脚本中新增一个事件绑定:code
window.onclick = debounce(function() { console.log(this) }, 1000)
点击页面空白处输入以下:
此次输出的就是window了! 看来这里的this实际是跟debounce函数所返回函数的实际调用者有关,第一次控制台输出的是button元素,由于是经过button元素来调用该返回函数,第二次调用者就是widnow,举这段btn.onclick = dobounce(function() {console.log(this)}, 1000)
代码的例子:对象
btn.onclick = function() { var _this = this; // 取debounce执行做用域的this var args = arguments; if (timer) { clearTimeout(timer); } //由于闭包的存在timer仍是取的debounce中的timer timer = setTimeout(function () { fn.apply(_this, args); // 用apply指向调用debounce的对象,至关于_this.fn(args); }, delay); }
那么这里的this指向的就是button元素了,为何呢,emmm写了太多了,打算专门再写一篇总结来延伸this的指向问题,今天的总结到此结束!blog