头痛的this指向问题

es5中的this

this是javascript中的一个关键字,它代表函数运行时,自动生成一个内部对象,只能在函数内部使用.

es5中的this是变化的 ,它指向是一大难点, 记住 : this指向调用它的那个对象

面试题中进行分析

全局调用 , this指向global

var name = 'global';
function a(){
    var name = 'fun';
    console.log(this.name);
}
a();
//global
//虽然函数内部有一个name变量,但是函数是在全局调用,所以是指向全局对象中的name

用call改变 , this指向

var name = 'global';
function a(){
    var name = 'fun';
    console.log(this.name);
}
obj = {
    name:'obj'
}
a.call(obj);
//obj
//可以用call,apply,bind改变this指向的对象

作为方法的调用

var name = 'global';
var obj = {
    name : 'obj',
    thisName : function(){
        var name = 'fun';
        console.log(this.name);
    }
}
obj.thisName();
//obj

闭包

var name = 'global';
var obj = {
    name : 'obj',
    thisName : function(){
        return function s(){
            console.log(this.name)
        }
    }
}
obj.thisName()();
//global
//方法中的闭包将s()函数弹出到全局环境栈中,所以函数执行this指向global

作为函数构造器调用
所谓构造函数,就是通过这个函数生成一个新对象(object)。这时,this就指这个新对象

var x = 2;
function test(){
  this.x = 1;
}
var o = new test();
alert(o.x) //1 this指向
alert(x); //2 验证,全局变量没有改变

es6中this在箭头函数中的使用

箭头函数中没有this , 它的this是继承而来
默认指向它所处的对象(在定义this时就已经确定this指向)
箭头函数可以方便地让我们在 setTimeout ,setInterval中方便的使用this

es5中的定时器

定时器函数中,没有默认的宿主对象,所以默认this指向window
(1)普通函数

var name = 'global';
var obj = {
    name : 'obj',
    say : function(){
            console.log(this.name)
    }
}
obj.say()
//obj

(2)定时器

var name = 'global';
var obj = {
    name : 'obj',
    say : function(){
        setTimeout(function(){
            console.log(this.name)
        },300)
    }

}
obj.say()
//global

(3)解决方案1:找个变量保存this

var name = 'global';
var obj = {
    name : 'obj',
    say : function(){
        //由于setTimeont中this指向window,所以需要找一个变量存储一下this
        var that = this;
        setTimeout(function(){
            console.log(that.name)
        },300)
    }

}
obj.say()
//obj

(4)解决方案2:func.bind(this) 给回调函数直接绑定宿主对象

var name = 'global';
var obj = {
    name : 'obj',
    say : function(){
        setTimeout(function(){
            console.log(this.name)
        }.bind(this),300)
    }

}
obj.say()
//obj

(5)解决方案3:es6中箭头函数解决定时器this指向

var name = 'global';
var obj = {
    name : 'obj',
    say : function(){
        setTimeout(()=>{
            console.log(this.name)
        },300)
    }

}
obj.say()
//obj
验证成果

window.val = 1;
 var obj = {
   val: 2,
   dbl: function () {
     this.val *= 2;
     val *= 2;
     console.log(val);
     console.log(this.val);
   }
 };
 // 说出下面的输出结果
 obj.dbl();
 var func = obj.dbl;
 func();
 //2 4 8 8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值