成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

進擊的 JavaScript(六) 之 this

chemzqm / 1319人閱讀

摘要:綁定為這個數(shù)組五綁定如果使用來創(chuàng)建對象,因為后面跟著的是構(gòu)造函數(shù),所以稱它為構(gòu)造器調(diào)用。為傳進來的構(gòu)造函數(shù)你這要看懂這步就行。

記得剛開始,我理解 this 的時候 也是云里霧里的,哈哈,希望通過這篇文章,對你有幫助吧。

關(guān)于 this 最多的說法,就是:誰調(diào)用它,this就指向誰。這話呢,不能說它錯了,只能說它講的不嚴謹,為什么呢?我們先來了解下 this 的幾種綁定規(guī)則。

一、默認綁定

默認綁定 發(fā)生在全局環(huán)境 。

全局環(huán)境中,this 默認綁定到 window。(嚴格模式下一樣)

console.log(this === window);
//true

"use strict";    //使用嚴格模式執(zhí)行代碼
var a = 666;
console.log(this.a)

//666


二、隱式綁定

隱式綁定 發(fā)生在 方法調(diào)用(執(zhí)行)。

什么是方法呢?通常把 對象的屬性值 是函數(shù)的,稱為方法。

var obj = {
    fun: function(){}
}

//這里obj 對象里 的fun 屬性值是個函數(shù), 就把 這個fun 屬性稱為方法了。

通常,方法調(diào)用時,this 隱式綁定到其 所屬的對象 上。

var a = "window";

var obj = {
    a: "obj",
    
    fun: function(){
        console.log(this.a);
    }
}

obj.fun();

//"obj"

來個難一點的:

var obj1 = {
    a: "obj1",
   
    obj2: {
        a: "obj2",
        fun: function(){
            console.log(this.a);
        }
    }
}

obj1.obj2.fun();

//"obj2"

這里的答案 跟你想的一樣嗎? 出現(xiàn)這個答案的關(guān)鍵 就是于,fun 函數(shù) 在作為對象方法執(zhí)行時, this 綁定的是它的 所屬對象,也就是 obj2 。 而非外層 的 obj1。

三、隱式綁定丟失

在判斷是否是隱式綁定的時候,最容易出問題的地方就是發(fā)生在 隱式綁定丟失。

隱式丟失是指被隱式綁定的函數(shù)丟失綁定對象,從而綁定到window。這種情況容易出錯卻又常見。(嚴格模式下,綁定到undefined)

隱式綁定丟失 一般 發(fā)生在 函數(shù)獨立調(diào)用時。

啥是獨立調(diào)用呢?就是一個簡單的函數(shù)執(zhí)行. 函數(shù)名的前面沒有任何引導(dǎo)內(nèi)容。

function ff(){};

ff();   //獨立調(diào)用

當函數(shù)獨立調(diào)用(執(zhí)行)時,this 就會隱式綁定丟失,而綁定到 window 對象上。(非嚴格模式下)

function fun(){
    console.log(this === window);
}
fun();
//true

那么嚴格模式下呢?是指向 undefined 的。

function fun(){
    "use strict";    //使用嚴格模式執(zhí)行代碼
    console.log(this);
}
fun();

//undefined

考考你:

var a = "window";

var obj = {
    a: "obj",
    
    fun1: function(){
        console.log(this.a);
    }
}

var fun2 = obj.fun;

fun2();
//"window"

判斷是否隱式綁定丟失的關(guān)鍵就在于, 判斷函數(shù) 是否是哪種調(diào)用。

上面的例子,關(guān)鍵點就在 最后兩行代碼。
先看其中的第一行:

var fun2 = obj.fun;

這里把 obj 的fun 方法 賦值給了 一個變量 fun2,這里的 fun 并沒有作為對象的方法來執(zhí)行,因為,fun 方法這里沒有執(zhí)行。

其后:

fun2();

再執(zhí)行 fun2,它保存著 fun1 方法,這時候執(zhí)行 fun2(等于fun1) ,但是,它是獨立調(diào)用。因為,沒有作為對象的方法來調(diào)用。所以 this 就被指向 window了。

那么怎么解決隱式丟失問題呢?

var a = "window";

var obj = {
    a: "obj",
    
    fun: function(){
        return function(){
            console.log(this.a);
        }
    }
}

obj.fun()();

//"window"

//這里我們想要的是 obj里 a 的值,可是,隱式綁定丟失導(dǎo)致獲取到了 window 里 a 的值。

可以基礎(chǔ)好的已經(jīng)知道答案了:

var a = "window";

var obj = {
    a: "obj",
    
    fun: function(){
        var that = this;
        return function(){
            console.log(that.a);
        }
    }
}

obj.fun()();

//"obj"

因為 fun 是作為方法調(diào)用的,所以 this 綁定到 obj 對象上,因此,我們就可以先用一個變量 that 來保存 this,然后 在內(nèi)部的 匿名函數(shù)中 使用 that 就可以了。它保存著 上面 this 的綁定對象。

忽然靈機一動,想出個題目,看人家都玩出題,我也試試,哈哈:

var a = "window";

function fun(){
    var a = "fun";

    return (function(){
        return this.a;
    })()
}

fun()

//“你猜”

這道題中 有立即執(zhí)行函數(shù)、this問題,哈哈,乍一看挺惡心,其實看完上面的,應(yīng)該可以看出來的。

四、顯示綁定

通過call()、apply()、bind()方法把 this 綁定到對象上,叫做顯式綁定。對于被調(diào)用的函數(shù)來說,叫做間接調(diào)用。

var a = "window"

var obj = {
    a:"obj",
}

function fun(){
    console.log(this.a);
}

fun.call(obj);
//"obj";

這里使用了 call 方法,把fun 中的 this 綁定到 obj 對象上。

javascript內(nèi)置的一些函數(shù),具有顯式綁定的功能,如數(shù)組的5個迭代方法:map()、forEach()、filter()、some()、every(),以及創(chuàng)建對象的 Object.create() 函數(shù)(后面原型鏈中會細說),都可以手動綁定this。

大家可以去看下API文檔,數(shù)組的這幾個函數(shù)的最后一個參數(shù),就是指定函數(shù)內(nèi) this 的綁定,如果不指定,則是window,嚴格模式下是undefined。

var a = [1,2,3];

a.forEach(function(){
    console.log(this)
},a);

//綁定 this  為 a 這個數(shù)組

//(3) [1, 2, 3]
//(3) [1, 2, 3]
//(3) [1, 2, 3]
五、new 綁定

如果 使用 new 來創(chuàng)建對象,因為 后面跟著的是構(gòu)造函數(shù),所以稱它為構(gòu)造器調(diào)用。對于this綁定來說,稱為new綁定。

想知道 構(gòu)造器調(diào)用 中 this 的綁定,就要知道 new 到底做了啥了。

先來個 new 的實現(xiàn)??床欢灰o,在后面原型鏈那篇,還會說的。

function New(proto){  //proto 為傳進來的構(gòu)造函數(shù)
    var obj = {};
    obj.__proto__ = proto.prototype;

    proto.apply(obj, Array.prototype.slice.call(argument,1));
    //你這要看懂這步就行。這里把構(gòu)造函數(shù)里的 this  綁定到了 新的obj 對象上,最后 返回了該新對象,作為實例對象。

    return obj;
}

所以在使用 new 來創(chuàng)建實例對象時,new 內(nèi)部把 構(gòu)造函數(shù)的 this 綁定到 返回的新對象 上了。

function Person(name){
    this.name = name;
}
var c = new Person("zdx");
c.name;

總結(jié): this的四種綁定規(guī)則:隱式綁定、隱式綁定丟失、顯式綁定和new綁定,分別對應(yīng)函數(shù)的四種調(diào)用方式:方法調(diào)用、獨立調(diào)用、間接調(diào)用和構(gòu)造器調(diào)用。


附錄:

1、關(guān)于this綁定 的優(yōu)先級問題。

簡單提一下吧:

new 綁定 > 顯示綁定 > 隱式綁定 > 默認綁定 。

2、ES6 中,箭頭函數(shù)的 this 綁定。

箭頭函數(shù)內(nèi)的 this 綁定的 是所屬的環(huán)境(函數(shù)或者對象), 它是固定不變的。

先看下上面的這個例子

var a = "window";

var obj = {
    a: "obj",
    
    fun: function(){
        return function(){
            console.log(this.a);
        }
    }
}

obj.fun()();

//"window"

上面我們使用 一個變量來保存 this 的綁定,下面我們來用 箭頭函數(shù)解決問題

var a = "window";

var obj = {
    a: "obj",
    
    fun: function(){
        return () => {
            console.log(this.a);
        }
    }
}

obj.fun()();

//"obj"

實際上,箭頭函數(shù)內(nèi)部是沒有this 的,所以,它不能使用 new 構(gòu)造器調(diào)用,call顯示綁定。所以它內(nèi)部就是使用了一個變量來保存 箭頭函數(shù) 所屬環(huán)境的(函數(shù)或者對象) this

就相當于:

var a = "window";

var obj = {
    a: "obj",
    
    fun: function(){
            that = this;
            return function(){
                console.log(that.a);
            }
    }
}

obj.fun()();

//"obj"

考考你:

var a = "window";

var obj = {
    a: "obj",
    
    fun1: function(){
        return () => {
            console.log(this.a);
        }
    }
}

var fun2  = obj.fun1;

fun2()();

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/96444.html

相關(guān)文章

  • JS面向?qū)ο蠖?this/原型鏈/new原理

    摘要:情況沒有明確作用對象的情況下,通常為全局對象例如函數(shù)的回調(diào)函數(shù),它的就是全局對象。正因如此,機器可以作為這類對象的標志,即面向?qū)ο笳Z言中類的概念。所以機器又被稱為構(gòu)造函數(shù)。原型鏈也就是繼承鏈。 JS面向?qū)ο蠖?this/原型鏈/new原理 阮一峰JavaScript教程:面向?qū)ο缶幊?阮一峰JavaScript教程:實例對象與 new 命令 阮一峰JavaScript教程:this 關(guān)...

    anRui 評論0 收藏0
  • 進擊 JavaScript(四) 閉包

    摘要:此時產(chǎn)生了閉包。導(dǎo)致,函數(shù)的活動對象沒有被銷毀。是不是跟你想的不一樣其實,這個例子重點就在函數(shù)上,這個函數(shù)的第一個參數(shù)接受一個函數(shù)作為回調(diào)函數(shù),這個回調(diào)函數(shù)并不會立即執(zhí)行,它會在當前代碼執(zhí)行完,并在給定的時間后執(zhí)行。 上一節(jié)說了執(zhí)行上下文,這節(jié)咱們就乘勝追擊來搞搞閉包!頭疼的東西讓你不再頭疼! 一、函數(shù)也是引用類型的。 function f(){ console.log(not cha...

    Anleb 評論0 收藏0
  • 進擊JavaScript(四)原型與原型鏈

    摘要:每一個由構(gòu)造函數(shù)創(chuàng)建的對象都會默認的連接到該神秘對象上。在構(gòu)造方法中也具有類似的功能,因此也稱其為類實例與對象實例一般是指某一個構(gòu)造函數(shù)創(chuàng)建出來的對象,我們稱為構(gòu)造函數(shù)的實例實例就是對象。表示該原型是與什么構(gòu)造函數(shù)聯(lián)系起來的。 本文您將看到以下內(nèi)容: 傳統(tǒng)構(gòu)造函數(shù)的問題 一些相關(guān)概念 認識原型 構(gòu)造、原型、實例三角結(jié)構(gòu)圖 對象的原型鏈 函數(shù)的構(gòu)造函數(shù)Function 一句話說明什么...

    XBaron 評論0 收藏0
  • 前端進擊巨人():知否知否,須知this

    摘要:有關(guān)函數(shù)柯里化的詳解,請回閱前端進擊的巨人五學(xué)會函數(shù)柯里化。構(gòu)造函數(shù)中的通過操作符可以實現(xiàn)對函數(shù)的構(gòu)造調(diào)用。在了解構(gòu)造函數(shù)中的前,有必要先了解下實例化對象的過程。 showImg(https://segmentfault.com/img/bVburMp?w=800&h=600); 常見this的誤解 指向函數(shù)自身(源于this英文意思的誤解) 指向函數(shù)的詞法作用域(部分情況) th...

    Andrman 評論0 收藏0
  • 進擊 JavaScript(五) 立即執(zhí)行函數(shù)與閉包

    摘要:匿名函數(shù)是不能單獨寫的,所以就提不上立即執(zhí)行了。六立即執(zhí)行函數(shù)在閉包中的應(yīng)用立即執(zhí)行函數(shù)能配合閉包保存狀態(tài)。來看下上節(jié)內(nèi)容中閉包的例子現(xiàn)在,我們來利用立即執(zhí)行函數(shù)來簡化它第一個匿名函數(shù)執(zhí)行完畢后,返回了第二個匿名函數(shù)。 前面的閉包中,提到與閉包相似的立即執(zhí)行函數(shù),感覺兩者還是比較容易弄混吧,嚴格來說(因為犀牛書和高程對閉包的定義不同),立即執(zhí)行函數(shù)并不屬于閉包,它不滿足閉包的三個條件。...

    vincent_xyb 評論0 收藏0

發(fā)表評論

0條評論

chemzqm

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<