this

187 阅读3分钟

了解this

this到底是什么呢?没有人能一句话概括,因为this总是在函数被调用的时候才被确定。因此,场景的不同会总成this指向的改变,但亘古不变的是,this总是指向执行这个函数的主体

this到底是谁?

那么,如何判断this到底指向什么呢?我画了个流程图,供大家参考:

this是谁取决于谁执行了这个函数,概括下来共有5种情况:

1.先看函数名前是否有“.”,有,前面是谁this就是谁;没有,则this指向window

function fn(){
  console.log(this);
}
var obj={fn:fn};
fn();//this->window
obj.fn();//this->obj
function sum(){
     fn();//this->window
}
sum();
var oo={
 sum:function(){
 console.log(this);//this->oo
       fn();//this->window
  }
};
oo.sum();

2.自执行函数中,this永远指向window

  (function(){ //this->window })();
  ~function(){ //this->window }();

3.给元素绑定事件,方法中的this指向该元素

/* dom零级绑定 */ 
oDiv.onclick=function(){
  //this->oDiv
};
/* dom二级时间绑定 */ 
oDiv.addEventListener("click",function(){
  //this->oDiv
},false);

4.构造函数中的函数,它的this看谁调用,也就是谁"."了,那么this就只想谁了,如果没有,那么this就指向window

function CreateJsPerson(name,age){
    //浏览器默认创建的对象就是我们的实例p1->this
    this.name=name;//->p1.name=name
    this.age=age;
    this.writeJs=function(){
    	console.log("my name is"+this.name +",i can write Js");
	};
	//浏览器再把创建的实例默认的进行返回
}
var p1=new CreateJsPerson("尹华芝",48);

注意:如果不是"XX."的格式,那么this还是指向window,如下例:

function Fn(){
    this.x=100//this->f1
    this.getX=function(){
    	console.log(this.x);//this->需要看getX执行的时候才知道
    }
}
var f1=new Fn;
f1.getX();//->方法中的this是f1,所以f1.x=100
var ss=f1.getX;
ss();//->方法中的this是window ->输出undefined		

5.call,apply,bind

1.call,apply和bind的区别

call,apply在将第一个参数变为this之后,会执行函数,而bind只负责绑定,不会自动执行

bind不执行
  var a ={
        name : "Cherry",
        fn : function (a,b) {
            console.log( a + b)
        }
    }
  var b = a.fn;
  b.bind(a,1,2) //单绑定,未执行
  b.bind(a,1,2)() //执行
call,apply在严格和非严格模式下,this指向的区别

call,apply修改this后,自动执行,且在严格和非严格模式下的this指向有所区别

var obj={name:"浪里行舟 "};
function fn(num1,num2){
console.log(num1+num2);
console.log(this);
}
fn.call(100,200);//this->100 num1=200 num2=undefined
fn.call(obj,100,200);//this->obj num1=100 num2=200

//在非严格模式下
fn.call();//this->window
fn.call(null);//this->window
fn.call(undefined);//this->window

//严格模式下 
fn.call();//在严格模式下this->undefined
fn.call(null);// 在严格模式 下this->null
fn.call(undefined);//在严格模式下this->undefined

call在非严格模式下,参数是null,undefined的情况下都会指向window

2.call和apply的区别

传参的区别:call第二个参数开始接受一个参数列表,apply第二个参数开始接受一个参数数组

fn.call(obj,100,200);
fn.apply(obj,[100,200]);

箭头函数的指向

箭头函数的this指向不是在函数被调用时才确定,而是在定义时确定

那么到底指向谁呢?简单来说,箭头函数的this取决于外部函数的this,如果外部第一层不是函数,那么指向window

第一例:this取决于外部函数的this

    <button id="btn1">测试箭头函数this_1</button>
    <button id="btn2">测试箭头函数this_2</button>
    <script type="text/javascript">   
        let btn1 = document.getElementById('btn1');
        let obj = {
            name: 'kobe',
            age: 39,
            getName: function () {
                btn1.onclick = () => {
                    console.log(this);//obj
                };
            }
        };
        obj.getName();
    </script>

第一例:箭头函数外第一层不是函数,则指向window

    <button id="btn1">测试箭头函数this_1</button>
    <button id="btn2">测试箭头函数this_2</button>
    <script type="text/javascript">   
        let btn2 = document.getElementById('btn2');
        let obj = {
            name: 'kobe',
            age: 39,
            getName: () => {
                btn2.onclick = () => {
                    console.log(this);//window
                };
            }
        };
        obj.getName();
    </script>

参考文章:

你还没搞懂this?

this