js this 問題

jsthis 是個比較令人頭疼的東西,尤其是在面試的時候凉馆,深受面試官的喜愛答憔。我們今天來談?wù)?js 中的 this

this 是什么裸诽,為什么要用 this

它是一個在每個函數(shù)作用域中自動定義的特殊標識符關(guān)鍵字, this機制提供了更優(yōu)雅的方式來隱含地“傳遞”一個對象引用蹬竖,導致更加干凈的 API 設(shè)計和更容易的復(fù)用沼沈。當我們的代碼和使用環(huán)境約復(fù)雜,我們就越能感受到 this 的重要性

先看一段代碼

 let x = {
   num: 1,
   sum: function(data) {
     return this.num + data
   }
 }
 let y = {
   num: 1,
   sum: function(data) {
     return this.num + data
   }
 }
 let y_sum = y.sum
  console.log(x.sum(1)) // 2
  console.log(y_sum(1)) // NaN

單從上面的代碼來看案腺,兩者似乎沒有區(qū)別庆冕,但是運行后的結(jié)果確是不一樣的

在看一段代碼

 let x = {
   num: 1,
   sum: function(data) {
     return this.num + data
   }
 }
 let y = {
   num: 1,
   sum: data => {
     return this.num + data
   }
 }
  console.log(x.sum(1)) // 2
  console.log(y.sum(1)) // NaN

也是一樣,看著倆段代碼差別不大劈榨,但是結(jié)果卻完全不一樣

var num = 2
var obj = {
  num: 1,
  say: function () {
    setTimeout(function(){
      console.log(this.num) // 2
    }, 0)
  }
}
obj.say()

一般函數(shù)的this指向是指執(zhí)行該函數(shù)的運行對象

 let x = {
   num: 1,
   sum: function(data) {
     return this.num + data
     // 這里的this是指運行了sum函數(shù)的x访递。所以this.num = 1
   }
 }
 let y = {
   num: 1,
   sum: function(data) {
     return this.num + data
     // 由于這里運行sum函數(shù)的不再是y而是window。所以這里相當于window.num = undefined
   }
 }
 let y_sum = y.sum
  console.log(x.sum(1)) // 2
  console.log(y_sum(1)) // NaN

箭頭函數(shù)的指向是指向運行該函數(shù)的父執(zhí)行上下文的this,箭頭函數(shù)中的this是在定義函數(shù)的時候綁定同辣,而不是在執(zhí)行函數(shù)的時候綁定拷姿。

 let x = {
   num: 1,
   sum: function(data) {
     return this.num + data
     // 這里的this指的是x
   }
 }
 let y = {
   num: 1,
   sum: data => {
     return this.num + data
   }
   // 這里因為是箭頭函數(shù),所以這里的this在sum函數(shù)定義的時候就開始綁定了旱函,這里的this是window
 }
  console.log(x.sum(1)) // 2
  console.log(y.sum(1)) // NaN

  var obj = {
  say: function () {
    let _say = () => {
      console.log(this);
      // 這里的this就是say响巢,因為在定義_say時,_say會去拿父執(zhí)行上下文的this
    }
    return _say()
  }
}
obj.say()

對于匿名函數(shù)來說棒妨,this的指向是window

var num = 2
var obj = {
  num: 1,
  say: function () {
    setTimeout(function(){
      console.log(this.num) // 2
      // 這里的this是window
    }, 0)
  }
}
obj.say()
// 這里如果是箭頭函數(shù)踪古,結(jié)果又不一樣了
var obj2 = {
  num: 1,
  say: function () {
    setTimeout(() =>{
      console.log(this.num) // 1
    }, 0)
  }
}
obj2.say()

雖然有的時候,函數(shù)會在window下調(diào)用,this會指向window對象伏穆,但是this 不會以任何方式指向函數(shù)的 詞法作用域

function foo() {
    var a = 2;
    this.bar();
}

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

foo(); //undefined

開發(fā)者試圖用 this 在 foo() 和 bar() 的詞法作用域間建立一座橋拘泞,使得bar() 可以訪問 foo()內(nèi)部作用域的變量 a。這樣的橋是不可能的枕扫。 你不能使用 this 引用在詞法作用域中查找東西陪腌。這是不可能的。

更多練習

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

var obj2 = {
    a: 42,
    foo: foo
};

var obj1 = {
    a: 2,
    obj2: obj2
};

obj1.obj2.foo(); // 42
// 這里最終調(diào)用foo函數(shù)的依然是obj2


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

function doFoo(fn) {
    // `fn` 只不過 `foo` 的另一個引用
  // 在這里fn() != obj.foo()
    fn();
}

var obj = {
    a: 2,
    foo: foo
};

var a = "oops, global";

doFoo( obj.foo ); // "oops, global"

var obj = {
  say: function () {
    function _say() {
      // this 是什么烟瞧?想想為什么诗鸭?
      console.log(this)
    }
    return _say.bind(obj)
  }()
}
obj.say()
// 這里_say通過bind將this指向了obj,但是打印的結(jié)果卻還是window参滴,為什么呢强岸?
// 這里可以看作: 因為 = 賦值語句是由右向左運行的。所以這里的obj應(yīng)該是個undefined,所以this指向了window

換種寫法就會完全不一樣了

var obj = {}
obj.say: function () {
    function _say() {
      console.log(this)
    }
    return _say.bind(obj)
}()
obj.say()
// 這里this指向了obj

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末卵洗,一起剝皮案震驚了整個濱河市请唱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌过蹂,老刑警劉巖十绑,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異酷勺,居然都是意外死亡本橙,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門脆诉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來甚亭,“玉大人,你說我怎么就攤上這事击胜】髡” “怎么了?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵偶摔,是天一觀的道長暇唾。 經(jīng)常有香客問我,道長辰斋,這世上最難降的妖魔是什么策州? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮宫仗,結(jié)果婚禮上够挂,老公的妹妹穿的比我還像新娘。我一直安慰自己藕夫,他們只是感情好孽糖,可當我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布枯冈。 她就那樣靜靜地躺著,像睡著了一般办悟。 火紅的嫁衣襯著肌膚如雪霜幼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天誉尖,我揣著相機與錄音,去河邊找鬼铸题。 笑死铡恕,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的丢间。 我是一名探鬼主播探熔,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼烘挫!你這毒婦竟也來了诀艰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤饮六,失蹤者是張志新(化名)和其女友劉穎其垄,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卤橄,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡绿满,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了窟扑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喇颁。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖嚎货,靈堂內(nèi)的尸體忽然破棺而出橘霎,到底是詐尸還是另有隱情,我是刑警寧澤殖属,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布姐叁,位于F島的核電站,受9級特大地震影響忱辅,放射性物質(zhì)發(fā)生泄漏七蜘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一墙懂、第九天 我趴在偏房一處隱蔽的房頂上張望橡卤。 院中可真熱鬧,春花似錦损搬、人聲如沸碧库。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嵌灰。三九已至弄匕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沽瞭,已是汗流浹背迁匠。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留驹溃,地道東北人稳摄。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓僵娃,卻偏偏與公主長得像跌捆,于是被迫代替她去往敵國和親鸭廷。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容