this的指向

167 阅读2分钟

透彻认识function中的this在不同调用环境下的指向

事件调用环境 谁触发事件,函数里的this就指向谁

例:

<div class="box"></div>
var box=document.querySelector('.box');
box.onclick=move;
function move(){
  this.style.left=100+'px';
}

全局环境

  • 指向window(浏览器运行的环境)
console.log(this);
  • 在单独的js文件中,全局的this指向的是导出的对象(node运行的环境下) this.js
console.log(this===module.exports); // true

终端运行命令
node this.js

函数内部

this最终指向的是调用它的对象
  • 普通函数直接调用与window调用
move(); // 非严格模式下指向的是window,严格模式下是undefined

// 严格模式下,调用
window.move();  // window 
  • 对象的函数直接调用与window调用
var obj={
    a:10,
    b:function(){
        console.log(this)
    }
    
}

obj.b(); // 指向obj
window.obj.b(); // 指向obj


函数被多层对象所包裹,如果函数被最外层对象调用,this指向的也只是它上一层的对象

例:

var obj={
    a:10,
    b:{
        fn:function(){
            console.log(this);
        }
    }
    
}

window.obj.b.fn; // 指向b


var abc=obj.b.fn;
abc(); // 指向的是window,this最终指向的是调用它的对象
  • 多层对象中的函数this的指向
  • 对象中的函数被赋值给另一个变量
构造函数中的this指向的是实例对象

function fn(){
    this.num=10;
    console.log(this);
}

var obj=new fn();
console.log(obj.num) // 10

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  ,new fn={}即{}.method();
prototype.method() //30    prototype={}

method() //undefined  method指向window 




/*
* 1.调用函数
* 2.自动创建一个对象
* 3.把创建出来的对象和this进行绑定
* 4.如果构造函数没有返回值,隐式返回this对象
*/
  • 构造函数中的this指向
  • new运算符的作用
如果构造函数中有return 如果return的值对象,this指向返回的对象,如果不是对象,则this指向保持原来的规则,在这里null比较特殊
function fn(){
    this.num=10;
    return ''; // 返回'',1,null 时obj.num为10,返回[],{}时,obj.num为undefined
}

var obj=new fn();
console.log(obj.num);


了解箭头函数中的this指向的特殊性

  • 箭头函数本身是没有this和arguments,在箭头函数中引用this实际上调用的是定义时的上一层作用域的this,上一层作用域,因对对象是不能形成对立的作用域的。
 function move(){
    var _this=this; 
     setTimeout(function(){
        _this.style.left='200px'; 
     })
 }
 
 // es6写法
 function move(){
     setTimeout(()=>{
        this.style.left='200px'; 
     })
 }
 
 
 var obj={
     fn:()=>{
         console.log(this);
     }
 }
 
 obj.fn(); // this指向window

掌握如何改变this指向

改变this指向的方法: call(this,a,b,c) apply(this,[abc]) bind(this,a,b,c)()

var box=document.querySelector('.box'),a,b,c;
var obj={
    fn:()=>{
        console.log(this);
    },
    fn1:function(){
        console.log(this)
    }
}


obj.fn.call(box); // 指向window

obj.fn1.call(box,a,b,c);
obj.fn1.apply(box,[a,b,c]);
obj.fn.bind(box)();