function的this在不同环境下的指向
-
事件调用环境
let box = document.querySelector('.box'); let box1 = document.querySelector('.box1'); box.onclick = move; box1.onclick = move; function move (){ //this是谁触发事件this指向谁 this.style.left = '100px' } console.log(this);//windows 全局环境this指向的是windows
-
全局环境
-
函数内部
-
this最终指向的是调用它的对象
-
普通函数直接调用与windows调用
-
对象中的的函数调用与windows调用
var obj ={ a: 10, b:function(){ console.log(this); } } obj.b();//对象调用指向对象
-
-
函数对象被多层函数所包含,如果函数被最外层对象调用,this指向的也只是它的上一级的对象。
- 多层对象中函数的this指向
- 对象中的函数被赋值给另一个变量
var obj ={ a: 10, b:{ fn:function(){ console.log(this); } } } window.obj.b.fn();//this 指向b对象
-
构造函数中的this指向的是实例对象
- 构造函数中的this指向
- new运算符的作用
/** * 1.调用函数 * 2.自动创建一个对象 * 3.把创建的对象绑定 * 4.如果构造函数没有返回值,隐式返回this对象 */ function fn(){ this.num = 10; console.log(this); } fn.num = 20; fn.prototype.num = 30; fn.prototype.method = function(){ console.log(this.num); } var prototype = fn.prototype;// var method = prototype.method; new fn().method();//10 空对象 相当于{}.fn().method prototype.method();//30 var obj = new fn(); method(); //undefined this 指向window对象 console.log(obj.num);
-
如果构造函数返回中return,如果return的值是对象,this指向返回的对象,如果不是对象,则this指向保持原来的实例化对象。null对象比较特殊
function fn(){ this.num = 10; return '';//10 return [];//undefined return 1;//10 return { num:20 };//20 return null;// 10 } var obj = new fn(); console.log(obj.num);
-
call、apply、bind 修改this指向 call 参数是多个 apply 参数是数组 ,bind 只是绑定没有调用还得调用
var box = document.querySelector('.obx'),a,b,c; var obj = {} fn: function(){ console.log(this);//箭头函数无法修改this 指向,此this指向window } } obj.fn.call(box,a,b,c); obj.fn.apply(box,[a,b,c]) obj.fn.bind(box)();
-
箭头函数自身没有this和arguments的,在箭头函数中实际上调用的定义的是上一层作用域this
function move(){ setTimeout(function(){ this.style.left ='100px';//this指向window },1000);// 延迟一秒 } function move(){ var _this = this; setTimeout(function(){ _this.style.left ='100px';//之前的写法 },1000);// 延迟一秒 } function move(){ setTimeout(()=>{ this.style.left ='100px';//ES6 this指向根据上下文环境 },1000);// 延迟一秒 } var obj = { fn:()=>{ console.log(this); } } obj.fn();//this 指向window ,因为obj是对象没有生成独立的作用域,故此箭头函数将this指向上一层 作用域
防抖和节流
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>title</title> <style type="text/css"> .box{ height: 200px; background: #0A8CD2; position: relative; left: 0; transition: 1s; } </style> </head> <body> <div class="box"> </div> <script type="text/javascript"> var box = document.querySelector('.box'); var testDebounce = debounce(move,1000); var testjl = jl(move,400); box.onmousemove = testjl; //box.onmousemove = testDebounce; function move(ev){ console.log(this); this.innerHTML = ev.clientX; } //move(); function move(ev){ console.log(this); this.innerHTML = ev.clientX; } function debounce(fn, wait){ let timer = null; return function(){ //接收调用者的鼠标移动事件参数 var args = arguments; //事件调用函数this执行触发事件的调用者 timer && clearTimeout(timer); timer = setTimeout(()=>{ //箭头函数有效避免this指向调用者 fn.apply(this,args); },wait); } } function jl(fn,wait){ let timmer = null; return function(){ var args = arguments; if(!timmer){ timmer = setTimeout(()=>{ // clearTimeout(timmer); timmer = null; fn.apply(this,args); },wait) } } } </script> </body> </html>
-