欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

我所理解的JavaScript中的this指向

 更新時間:2020年09月04日 09:02:49   作者:Clloz  
這篇文章主要介紹了JavaScript中this指向的相關(guān)資料,幫助大家更好的理解和學習JavaScript,感興趣的朋友可以了解下

前言

JS 中的 this 指向是一個經(jīng)常被問到的問題,網(wǎng)上也有很多文章是關(guān)于 this 的。本文整理一下我理解下的 this 以及一些我比較疑惑的關(guān)于 this 問題。

this 指向

有幾個 this 的指向問題是幾乎每篇文章都會說的,比如作為函數(shù)直接調(diào)用,作為對象的方法調(diào)用, new 運算符執(zhí)行中的 this 行為。比較通用的說法是, this 指向的是直接調(diào)用該函數(shù)的對象。其實也很好理解,就是為什么需要 this 這個關(guān)鍵字,就是我們有需要在函數(shù)內(nèi)部對調(diào)用函數(shù)的對象進行操作的需求。但是有時候我們遇到的情況并不是像書上或 mdn 上遇到的典型的情況, this 的行為可能就會讓我們感到有點疑惑。

函數(shù)的直接調(diào)用

當我們直接調(diào)用一個已經(jīng)聲明的函數(shù),那么在非嚴格模式下,該函數(shù)內(nèi)部的 this 指向的是全局對象,瀏覽器環(huán)境下就是 window 對象。

function f1(){
 return this;
}
//在瀏覽器中:
f1() === window; //在瀏覽器中,全局對象是window

//在Node中:
f1() === global;

當函數(shù)是在全局環(huán)境下定義的時候,這種現(xiàn)象是可以理解的,因為全局環(huán)境下定義的函數(shù)其實就是掛載在全局對象上的一個屬性,比附上面的 f1 也可以理解為 window.f1。但我認為嚴格模式下的行為才是更符合 this 這個關(guān)鍵字的目的的,特別是我們的函數(shù)可能是在非全局環(huán)境(比如另一個函數(shù)中)定義和調(diào)用的,這種情況下 this 還指向 window 是不太合理的。所以在嚴格模式下,一個函數(shù)直接調(diào)用,它的 this 指向的是 undefined,如果我們想要得到非嚴格模式下的結(jié)果,那我們調(diào)用函數(shù)的方法就要改為 window.f1(),而如果函數(shù)是在非全局環(huán)境下定義的話,那么始終返回的是 undefined。我認為這樣的行為是更符合邏輯的。

'use strict'
function d () {
 function e() {
  console.log(this)
 }
 console.log(this)
}

d()
//undefined
//undefined

window.d()
//Window{}
//undefined

這里在全局模式下使用 use strict 只是為了測試,實際使用還是盡量放在函數(shù)內(nèi)局部使用嚴格模式,全局下的嚴格模式很容易導致出錯。

函數(shù)作為對象的屬性調(diào)用

這也是在代碼中非常常見的場景,我認為這是比函數(shù)調(diào)用更好理解,也更能幫助我們理解 this 行為的場景。簡單的來說就是 this 指向的是 直接 調(diào)用函數(shù)的那個對象。并且要注意的是,這跟函數(shù)在哪里定義的是無關(guān)的,我們看 this,看的就是從哪里調(diào)用的函數(shù)。

//在對象內(nèi)部定義
var o = {
 prop: 37,
 f: function() {
 return this.prop;
 }
};

console.log(o.f()); // 37

//在對象外部定義
var o = {prop: 37};

function independent() {
 return this.prop;
}

o.f = independent;

console.log(o.f()); // 37

//在對象內(nèi)部定義,但是給外部變量引用并執(zhí)行
var o = {
 prop: 37,
 f: function() {
  console.log(this)
 return this.prop;
 }
};
var prop = 100;
var m = o.f;
console.log(m());
//Window{}
//100

上面的段落我給 直接 這兩個字加粗了,想要表達的意思是當我們通過多個對象的屬性嵌套找到并調(diào)用函數(shù),那么最后那個最接近函數(shù)的對象就是函數(shù) this 的指向。

var o = {
 a:10,
 b:{
  a:12,
  fn:function(){
   console.log(this.a); //12
  }
 }
}
o.b.fn();

var o = {
 a:10,
 b:{
  // a:12,
  fn:function(){
   console.log(this.a); //undefined
  }
 }
}
o.b.fn();

為什么我說這個場景能夠幫助我們理解,原因就是它反映出 this 這個關(guān)鍵字的本質(zhì)。JS 中的函數(shù)也是一種對象,在我們的執(zhí)行環(huán)境中的活動對象保存的也只是函數(shù)對象的一個引用,如果這個引用是保存在活動對象中的某個對象的屬性中(即我們通過活動對象中的某個對象的屬性找到該函數(shù)),那么函數(shù)執(zhí)行的時候 this 就會指向這個對象,這也是為什么多層對象的調(diào)用,還是最靠近函數(shù)的那個對象作為 this。雖然在代碼中我們的函數(shù)是在對象中定義的,但是實際在內(nèi)存中,對象中只保存著函數(shù)的引用,函數(shù)自己是在一個單獨的內(nèi)存空間中。所以我們通過哪個對象找到函數(shù)并執(zhí)行,函數(shù)中的 this 就指向這個對象。上面的直接調(diào)用 this 返回 undefined 也是說得通的。

通過原型的調(diào)用

有時我們是通過原型來執(zhí)行公用的函數(shù),此時已然符合我們上面的邏輯,我們通過哪個實例 找到 函數(shù),那么 this 就指向那個實例。

var o = {
 f: function() { 
 return this.a + this.b; 
 }
};
var p = Object.create(o);
p.a = 1;
p.b = 4;

console.log(p.f()); // 5

箭頭函數(shù)

箭頭函數(shù)并沒有自己的 this,箭頭函數(shù)中的 this是它所在的執(zhí)行環(huán)境中的 thismdn 寫的是封閉的詞法環(huán)境),當你遇到箭頭函數(shù)中的 this 不確定的時候,你可以想象把這個箭頭函數(shù)換成 console.log(this),這個 console 的輸出就是箭頭函數(shù)中 this 的值,并且箭頭函數(shù)的 this 是綁定的,不會改變(有時候看上去改變了是所在的 context 改變了)。還有一點需要注意的是,用 call,apply,bind 來調(diào)用箭頭函數(shù),第一個參數(shù)是沒有意義的,也就是無法改變 this,如果仍需要使用,第一個參數(shù)應該傳 null???mdn 給出的示例。

var globalObject = this;
var foo = (() => this);
console.log(foo() === globalObject); // true

// 接著上面的代碼
// 作為對象的一個方法調(diào)用
var obj = {foo: foo};
console.log(obj.foo() === globalObject); // true

// 嘗試使用call來設(shè)定this
console.log(foo.call(obj) === globalObject); // true

// 嘗試使用bind來設(shè)定this
foo = foo.bind(obj);
console.log(foo() === globalObject); // true

// 創(chuàng)建一個含有bar方法的obj對象,
// bar返回一個函數(shù),
// 這個函數(shù)返回this,
// 這個返回的函數(shù)是以箭頭函數(shù)創(chuàng)建的,
// 所以它的this被永久綁定到了它外層函數(shù)的this。
// bar的值可以在調(diào)用中設(shè)置,這反過來又設(shè)置了返回函數(shù)的值。
var obj = {
 bar: function() {
 var x = (() => this);
 return x;
 }
};

// 作為obj對象的一個方法來調(diào)用bar,把它的this綁定到obj。
// 將返回的函數(shù)的引用賦值給fn。
var fn = obj.bar();

// 直接調(diào)用fn而不設(shè)置this,
// 通常(即不使用箭頭函數(shù)的情況)默認為全局對象
// 若在嚴格模式則為undefined
console.log(fn() === obj); // true

// 但是注意,如果你只是引用obj的方法,
// 而沒有調(diào)用它
var fn2 = obj.bar;
// 那么調(diào)用箭頭函數(shù)后,this指向window,因為它從 bar 繼承了this。
console.log(fn2()() == window); // true

其他情況

還有一些情況我覺得比較簡單,就一筆帶過。
1. 當函數(shù)被用作事件處理函數(shù)時,它的 this 指向觸發(fā)事件的元素。
2. 當代碼被內(nèi)聯(lián) on-event 處理函數(shù)調(diào)用時,它的this指向監(jiān)聽器所在的 DOM 元素,需要注意的是只有最外層的 this 是這樣,如果里面還有嵌套函數(shù),則嵌套函數(shù)的 this 在非嚴格模式下仍然指向全局對象。
3. 構(gòu)造函數(shù)中的 this 請看之前的文章JavaScript中new操作符的解析和實現(xiàn)
4. bindcallapply 都一樣,函數(shù)的 this 被綁定到第一個參數(shù)上。

總結(jié)

以上就是我所總結(jié)的 JS 中的 this 的一些要點,如果有什么遺漏或者錯誤的地方,歡迎指正。

到此這篇關(guān)于我所理解的JavaScript中的this指向的文章就介紹到這了,更多相關(guān)JavaScript this指向內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Js模板引擎(TrimPath)

    詳解Js模板引擎(TrimPath)

    本文詳細介紹了在頁面中引用template.js文件之后,具體的使用方法及實例,有需要的朋友可以參考下
    2016-11-11
  • Bootstrap布局之柵格系統(tǒng)詳解

    Bootstrap布局之柵格系統(tǒng)詳解

    這篇文章主要為大家詳細介紹了Bootstrap布局之柵格系統(tǒng),小編對Bootstrap柵格系統(tǒng)(布局)也很陌生,特分享整理這篇文章,感興趣的小伙伴們可以參考一下
    2016-06-06
  • js自定義回調(diào)函數(shù)

    js自定義回調(diào)函數(shù)

    這篇文章主要介紹了javascript自定義回調(diào)函數(shù),感興趣的小伙伴們可以參考一下
    2015-12-12
  • 微信小程序textarea層級過高的解決方法

    微信小程序textarea層級過高的解決方法

    這篇文章主要給大家介紹了關(guān)于微信小程序textarea層級過高問題的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-03-03
  • JS簡單生成由字母數(shù)字組合隨機字符串示例

    JS簡單生成由字母數(shù)字組合隨機字符串示例

    這篇文章主要介紹了JS簡單生成由字母數(shù)字組合隨機字符串,結(jié)合實例形式分析了javascript使用Math.random()生成隨機字符串相關(guān)操作技巧,需要的朋友可以參考下
    2018-05-05
  • js實現(xiàn)拖拽效果

    js實現(xiàn)拖拽效果

    本文主要是為了讓大家更好的理解js的面向?qū)ο?,通過實現(xiàn)拖拽效果向大家展示js面向?qū)ο螅浅2诲e,這里推薦給大家。
    2015-02-02
  • List the UTC Time on a Computer

    List the UTC Time on a Computer

    List the UTC Time on a Computer...
    2007-06-06
  • 一文詳解如何跳出map或者foreach循環(huán)

    一文詳解如何跳出map或者foreach循環(huán)

    javascript中的遍歷方法有很多,今天主要總結(jié)一下這些遍歷方法如何跳出循環(huán),這篇文章主要給大家介紹了關(guān)于如何跳出map或者foreach循環(huán)的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • H5+C3+JS實現(xiàn)雙人對戰(zhàn)五子棋游戲(UI篇)

    H5+C3+JS實現(xiàn)雙人對戰(zhàn)五子棋游戲(UI篇)

    這篇文章主要為大家詳細介紹了H5+C3+JS實現(xiàn)雙人對戰(zhàn)五子棋游戲,實現(xiàn)雙人對戰(zhàn)模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • JS調(diào)用某段SQL語句的方法

    JS調(diào)用某段SQL語句的方法

    這篇文章主要為大家詳細介紹了通過JS調(diào)用某段SQL語句的相關(guān)方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10

最新評論