小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

一文搞懂 this、apply、call、bind

 程序員文庫 2021-03-10
“this” 關(guān)鍵字允許在調(diào)用函數(shù)或方法時(shí)決定哪個(gè)對(duì)象應(yīng)該是焦點(diǎn)。

在JavaScript中this可以是全局對(duì)象、當(dāng)前對(duì)象或者任意對(duì)象,這完全取決于函數(shù)的調(diào)用方式,this 綁定的對(duì)象即函數(shù)執(zhí)行的上下文環(huán)境,在 ES5 中,其實(shí) this 的指向,始終堅(jiān)持一個(gè)原理:this 永遠(yuǎn)指向最后調(diào)用它的那個(gè)對(duì)象,正是由于調(diào)用function的對(duì)象不同,才導(dǎo)致了this的指向不同。

關(guān)于this的指向及綁定,請(qǐng)關(guān)注博文 JS五種綁定徹底弄懂this,默認(rèn)綁定、隱式綁定、顯式綁定、new綁定、箭頭函數(shù)綁定詳解

// e.g.1var test = {  a: 5,  b: 6,  sum: function (a, b) {    function getA(a) {      this.a = a;    // 在window上增加了一個(gè)全局變量a
      return this.a; // 此處this = window
    }    function getB(b) {      this.b = b;    //在window上增加了一個(gè)全局變量b
      return this.b; // 此處this = window
    }    return getA(a) + getB(b);
  }
}console.log(test.sum(4, 3));  // 7console.log(a);     // 4   (打印結(jié)果為 window.a)  console.log(b);     // 3   (打印結(jié)果為 window.b)
// e.g.2var user = {  name: 'Echoyya',  age: 27,  greet() {  console.log(this.name)
  },  bf: {    name: 'KK.unlock',    greet() {      console.log(this.name)
    }
  }
}

user.greet()      // Echoyyauser.bf.greet()   // KK.unlock

如果 greet 函數(shù)不是 user 對(duì)象的函數(shù),只是一個(gè)獨(dú)立的函數(shù)。

function greet () {  console.log(this.name)
}var user = { name: 'Echoyya' }

如何能讓 greet 方法調(diào)用的時(shí)候?qū)?nbsp;this 指向 user 對(duì)象?不能再像之前使用 user.greet(),因?yàn)?nbsp;user 并沒有 greet 方法。我們可以通過一些方法去改變this的指向

怎樣改變 this 的指向

(1)使用ES6中箭頭函數(shù)

箭頭函數(shù)中的 this 始終指向函數(shù)定義時(shí)的 this,而非執(zhí)行時(shí)。箭頭函數(shù)中沒有 this 綁定,必須通過查找作用域鏈來決定其值,如果箭頭函數(shù)被非箭頭函數(shù)包含,則 this 綁定的是最近一層非箭頭函數(shù)的 this,否則,this 為 undefined”。

也正因如此,箭頭函數(shù)不能用于構(gòu)造函數(shù)

var name = "windowsName";var obj = {  name: "Echoyya",  func1: function () {    console.log(this.name)
  },  func2: () => {      console.log(this.name)
    }
};

obj.func1() // Echoyyaobj.func2() // windowsName

(2)函數(shù)內(nèi)部使用 _this = this

如果不使用 ES6,那么這種方式應(yīng)該是最簡(jiǎn)單且不易出錯(cuò)的方式了,先將調(diào)用這個(gè)函數(shù)的對(duì)象保存在變量 _this 中,然后在函數(shù)中都使用這個(gè) _this。

obj調(diào)用func時(shí) this 指向obj,防止setTimeout 被 window 調(diào)用,導(dǎo)致 setTimeout 中的 this 指向 window,設(shè)置 var _this = this,將 this(指向變量 obj) 賦值給一個(gè)變量 _this,這樣,在 func 中使用_this 就指向?qū)ο?nbsp;obj

var name = "windowsName";var obj = {  name: "Echoyya",  func: function () {    var _this = this;    setTimeout(function () {      console.log(_this.name)
    }, 1000);
  }
};

obj.func() // Echoyya

(3)使用call,apply,bind方法

call、apply、bind 方法是每個(gè)函數(shù)都有的一個(gè)方法,允許在調(diào)用函數(shù)時(shí)為函數(shù)指定上下文??梢愿淖?this 指向

call 與 apply
  • call 方法,第一個(gè)參數(shù)會(huì)作為函數(shù)被調(diào)用時(shí)的上下文。即this 指向傳給 call 的第一個(gè)參數(shù)。

  • 傳遞參數(shù)給使用 .call 調(diào)用的函數(shù)時(shí),需要在指定上下文(第一個(gè)參數(shù))后一個(gè)一個(gè)地傳入。

  • 語法:fun.call(thisArg [, arg1[, arg2[, ...]]])

站在函數(shù)應(yīng)用的角度我們知道了call與apply的用途,那這兩個(gè)方法又有什么區(qū)別呢,其實(shí)區(qū)別就一點(diǎn),參數(shù)傳遞方式不同。

  1. call方法中接受的是一個(gè)參數(shù)列表,第一個(gè)參數(shù)指向this,其余的參數(shù)在函數(shù)執(zhí)行時(shí)都會(huì)作為函數(shù)形參傳入函數(shù)。

    • 語法:fn.call(this, arg1, arg2, ...);

  2. 而apply不同的地方是,除了第一個(gè)參數(shù)作為this指向外,其它參數(shù)都被包裹在一個(gè)數(shù)組中,在函數(shù)執(zhí)行時(shí)同樣會(huì)作為形參傳入。

    • 語法:fn.apply(this, [arg1, arg2, ...]);

除此之外,兩個(gè)方法的效果完全相同:

var o = {    a: 1};function fn(b, c) {    console.log(this.a + b + c);
};
fn.call(o, 2, 3);     // 6fn.apply(o, [2, 3]);  //6
關(guān)于 bind

bind要單獨(dú)說一下,因?yàn)樗ccall,apply還不太一樣。call與apply在改變this的同時(shí),就立刻執(zhí)行,而bind綁定this后并不會(huì)立馬執(zhí)行,而是返回一個(gè)新的綁定函數(shù),需要在執(zhí)行一下。

var o = {    a: 1};function fn(b, c) {    console.log(this.a + b + c);
};var fn2 = fn.bind(o, 2, 3);

fn2();   //6
var name = 'windowsName'function greet () {
  console.log(this.name)
}var user = { name: 'Echoyya' }greet()          // windowsNamegreet.bind()()   // windowsName  (非嚴(yán)格模式下,默認(rèn)指向window)greet.bind(user)()   // Echoyya
var obj = {  name: "Echoyya",  func: function () {    setTimeout(function () {      console.log(this.name)
    }.bind(obj)(), 100);
  }
};

obj.func() // Echoyya
call、apply、bind 區(qū)別

call、apply、bind 都是可以改變 this 的指向的,但是這三個(gè)函數(shù)稍有不同。

var test = {  a: 5,  b: 6,  sum: function (a, b) {    var self = this;    function getA() {      return self.a;
    }    function getB() {      return self.b;
    }    console.log(a, b);    // call, apply, bind 傳入?yún)?shù)
    return getA() + getB();
  }
}var obj = {  a: 2,  b: 3};console.log(test.sum.call(obj, 4, 5));    // 4,5,5  (self = this = obj)   console.log(test.sum.apply(obj, [6, 7])); // 6,7,5  (self = this = obj)   console.log(test.sum.bind(obj, 8, 9)());  // 8,9,5  (self = this = obj)

apply 和 call 的區(qū)別

  • .apply 和 .call 本質(zhì)相同,他們的區(qū)別只是傳入的參數(shù)不同。

    • 傳遞參數(shù)給使用 .call 調(diào)用的函數(shù)時(shí),需要在指定上下文(第一個(gè)參數(shù))后一個(gè)一個(gè)地傳入(參數(shù)列表)。

    • 傳遞參數(shù)給使用 .apply 調(diào)用的函數(shù)時(shí),可以用數(shù)組傳參而且 .apply 會(huì)在函數(shù)中自動(dòng)展開(參數(shù)數(shù)組)。

call、apply、bind到底有什么區(qū)別?bind返回的方法還能修改this指向嗎?

  1. apply與call是函數(shù)應(yīng)用,指定this的同時(shí)也將方法執(zhí)行,bind不同,它只是負(fù)責(zé)綁定this并返回一個(gè)新方法,不會(huì)執(zhí)行。

  2. 嘗試打印返回的新函數(shù)fn2,可以看到它并不是一個(gè)普通的function,而是一個(gè)bound function,簡(jiǎn)稱綁定函數(shù)

    • TargetFunction 指向 bind 前的函數(shù);

    • BoundThis 是綁定的 this 指向

    • BoundArgs 是傳入的其它參數(shù)了。

  3. 當(dāng)我們執(zhí)行fn2時(shí),有點(diǎn)類似于TargetFunction.apply(BoundThis,BoundArgs)??梢缘贸鲆粋€(gè)結(jié)論,當(dāng)執(zhí)行綁定函數(shù)時(shí),this指向與形參在bind方法執(zhí)行時(shí)已經(jīng)確定了,無法改變。

  4. bind多次后執(zhí)行,函數(shù)this還是指向第一次bind的對(duì)象。

    var o1 = { a: 1 };var o2 = { a: 2 };function fn(b, c) {
        console.log(this.a + b + c);
    };var fn1 = fn.bind(o1, 2, 3);//嘗試再次傳入形參fn1(4, 4);           //6//嘗試改變thisfn1.call(o2);        //6//嘗試再次bindfn1.bind(o2, 1, 1)()   // 6

其實(shí)很好理解,當(dāng)執(zhí)行fn1時(shí),本質(zhì)上等于window.fn1(),如果this還能被改變,那this豈不是得指向window,那bind方法就沒太大意義了

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多