理解JavaScript中的this

理解this

JavaScript中的this是其靈活性的表現(xiàn),同時也因為this的多變性與其他語言的不一致,也成為JavaScript的一個難以理解的地方。因此在這里總結(jié)一下this常見的情況,以加深記憶

JavaScript中的this表示執(zhí)行上下文對象,有以下幾種綁定規(guī)則:

1.默認綁定

JavaScript中規(guī)定,函數(shù)中的this默認會和window對象綁定(在嚴格模式下默認綁定會失效)

var name = 'yip'
function a(){
    console.log(this.name);
}
a();//yip

2.隱式綁定

當函數(shù)的調(diào)用位置有另外一個上下文對象時,this會和這個上下文對象綁定,簡單來說就是和函數(shù)的調(diào)用者綁定

var name = 'yip';
function a(){
    console.log(this.name);
}
var obj = {
    name:'xie',
    a:a
}
obj.a();//xie

隱式綁定有兩種特殊情況會導致隱式綁定失效

var name = 'yip';
function a(){
    console.log(this.name);
}
var obj = {
    name:'xie',
    a:a
}
var obj1 = {
    name : 'zhan'
}
var b = obj.a;
b();//yip,這是第一種情況,這時的b只是取得了obj.a的引用,執(zhí)行時上下文還是沒有綁定
obj.a();//xie
(obj1.a = obj.a)()//yip,這里是第二種情況,間接引用,但是執(zhí)行上下文還是沒有綁定

在計時器setTimeout中,以及把函數(shù)作為參數(shù)傳遞到另一函數(shù)中,也會發(fā)生隱式丟失,在這種情況下,相當于隱式賦值。

var name = 'yip';
function a(){
    console.log(this.name);
}
var obj = {
    name:'xie',
    a:a,
    b:function(){
        setTimeout(function(){
            console.log(this.name);
        },1000)
    }
}
setTimeout(obj.a,1000);//yip
function argFunc (func){
    func();
}
argFunc(a);//yip
obj.b();//yip

3.顯示綁定

JavaScript中有3個特殊的方法。call、apply、bind,可以顯式指定函數(shù)的執(zhí)行上下文

var name = 'yip';
function a(){
    console.log(this.name);
}
var obj = {
    name:'xie',
    a:a
}
var obj1 = {
    name : 'zhan'
}
obj.a();//xie
a.call(obj);//xie
a.apply(obj);//xie
var b = a.bind(obj);
b();//xie

bind 與 apply和call 作用相似,但bind返回一個函數(shù),可以在后來被調(diào)用,其執(zhí)行環(huán)境由bind綁定;

ES5以下實現(xiàn)bind

function mybind(func,context){
    if(func.bind){
        return func.bind(context);
    }else{
        return function(){
            func.apply(context);
        }
    }
}

構(gòu)造函數(shù)里的this

JavaScript中規(guī)定,任何函數(shù)都可以用new操作符實例化對象,使用new操作符之后,函數(shù)就變?yōu)闃?gòu)造函數(shù),其中的this指向新建的對象。

使用new操作符時,在JavaScript機制中執(zhí)行下列幾步操作

  1. 新建一個空對象;

  2. 執(zhí)行函數(shù)內(nèi)容;

  3. 把this指向新建的對象;

  4. 返回一個對象,可能是函數(shù)中返回的也可能是新建打的對象

    function a(){
    this.name = 'yip';
    this.sayName = fucntion (){
    console.log(this.name);
    }
    }
    var obj = new a();
    obj.sayName();//yip

一個簡單的驗證方法是看函數(shù)調(diào)用的前面是否是一個引用對象。

事件處理器中的this

在事件處理器中的this指向事件發(fā)生的對象。

var name = 'yip';
var mybtn = document.getElementById('mybtn');
function callback (){
    console.log(this);
}
mybtn.addEventListener("click",callback)//button

ES6箭頭函數(shù)

在ES6中,新增箭頭函數(shù),在箭頭函數(shù)中不使用上面所說的任意一種綁定規(guī)則,而是根據(jù)外層作用域的this來決定this(函數(shù)內(nèi)或者是全局)。

這可以解決在函數(shù)中使用setTimeout發(fā)生的隱式丟失,ES6之前的解決方案是通過聲明一個變量存儲this來實現(xiàn)

var self = this;

ES6中是:

var name = 'yip';
function a(){
    console.log(this.name);
}
var obj = {
    name:'xie',
    a:a,
    b:function(){
        setTimeout(()=>{
            console.log(this.name);
        },1000)
    }
}
obj.b();//xie

因此常把ES6的箭頭函數(shù)用于事件處理器和計時器中

var name = 'yip';
var mybtn = document.getElementById('mybtn');
callback = () =>{
    console.log(this);
}
mybtn.addEventListener("click",callback)//window
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. this之謎 在JavaScript中,this是當前執(zhí)行函數(shù)的上下文。因為JavaScript有4種不同的...
    百里少龍閱讀 1,093評論 0 3
  • 一些誤解 指向自身?(并不是所有時候都指向自身) 作用域問題?(this并不一定指向函數(shù)的作用域,并且在任何時候都...
    猿小v閱讀 549評論 3 12
  • 首先必須要說的是,this的指向在函數(shù)定義的時候是確定不了的,只有函數(shù)執(zhí)行的時候才能確定this到底指向誰...
    馬里奧Joseph閱讀 369評論 0 3
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持,譯者再次奉上一點點福利:阿里云產(chǎn)品券,享受所有官網(wǎng)優(yōu)惠,并抽取幸運大...
    HetfieldJoe閱讀 7,002評論 15 54
  • 每天上班路過早市,我總能在路的拐角看到那個賣魚的男人,他身上的衣服特別的臟,上面粘滿魚鱗、魚血。他的頭發(fā)也臟兮兮的...
    千帆過盡z閱讀 335評論 0 0

友情鏈接更多精彩內(nèi)容