iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 5
0
Modern Web

從技術文章深入學習 JavaScript系列 第 5

Day 05 [this 01] this、apply、call、bind

文章選自

作者:sunshine小小倩

連接:https://juejin.im/post/6844903496253177863

來源:掘金

this 的指向

this 永遠指向最後調用他的對象

我常拿來判斷的想法

看他是被當作對象內的方法調用還是全局函數

直接來看例子比較好懂

例子

var name = 'Mike'
let foo = {
    name: 'Mary',
    getName() {
        console.log(this.name)
    }
}
foo.getName() // 很明顯是Mary,因為this指向的是最後調用他的對象
window.foo.getName() // 這也很明顯是Mary,因為會是最後調用的對象(即foo)
let bar = foo.getName // 記住這是賦與內存地址給他,執行的時候並不會變成 window.foo.getName
bar() // Mike (window.bar())

這註解超級重要

// 記住這是賦與內存地址給他,執行的時候並不會變成 window.foo.getName

題外話:

​ 不知道大家有沒有發現我這裡第一行定義是用var來定義,因為如果用let 來定義的話,並不會變成全局變量(window.name),還有這裡如果用嚴格模式會報錯

"use strict" 
var name = 'Mike'
let foo = {
    ... // 底下都一樣

https://ithelp.ithome.com.tw/upload/images/20200915/20124350HqrLCBuuPA.png

如何改變this指向

箭頭函數

明天會開一篇出來講這裡先pass

在函數內部使用 _this = this

這裡用了一個很聰明的辦法,就是:

利用_this變量去紀錄調用過程的this對象

例子:

ar name = "windowsName";

var a = {

  name: "Cherry",

  func1: function () {
    console.log(this.name)
  },

  func2: function () {
    var _this = this; // 這裡在調用時會是a這個對象
    console.log(this); // {name: "Cherry", func1: ƒ, func2: ƒ}
    setTimeout(function () {
      _this.func1() 
    }, 100);
  }
};

a.func2()       // Cherry

https://ithelp.ithome.com.tw/upload/images/20200915/20124350dk2zMw3nYE.png

使用apply、call、bind

先來看例子晚點講原理

可以發現其實三個的用法幾乎一樣,只有bind要再執行一次

var a = {
  name: "Cherry",

  func1: function () {
    console.log(this.name)
  },

  func2: function () {
    // apply
    setTimeout(function () {
      this.func1()  // Cherry
    }.apply(a), 100);

    // call
    setTimeout(function () {
      this.func1()  // Cherry
    }.call(a), 100);

    // bind
    setTimeout(function () {
      this.func1()  // Cherry
    }.bind(a)(), 100);
    
  }
};

a.func2()           

apply、call、bind 區別

這三個都會讓函數執行喔

apply以及call差別

基本上是沒差,只是傳遞參數apply是用array而call是分批傳入

定義:

fun.apply (thisArg,[argsArray])

fun.call (thisArg[, arg1[, arg2[, ...]]])

看起來有夠複雜,其實就是最上面講得那句。直接看例子就懂了

例子:

var a ={
    name : "Cherry",
    fn : function (a,b) {
        console.log(a + b)
    }
}

var b = a.fn;
b.apply(a,[1,2])     // 3
b.call(a,1,2)   // 3

bind 和apply、call 區別

bind跟他們兩個的最大區別就是

bind是創建函數,還需要手動調用

var a ={
    name : "Cherry",
    fn : function (a,b) {
        console.log( a + b)
    }
}

var b = a.fn;
b.bind(a,1,2)()           // 3


上一篇
Day 04 [原型鍊02]淺談instanceof 和typeof 的實現原理
下一篇
Day 06 [this 02] ES6箭頭函數、箭頭函數與普通函數的區別
系列文
從技術文章深入學習 JavaScript29

尚未有邦友留言

立即登入留言