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

一篇文章詳細講解JavaScript中的this(普通函數(shù)、箭頭函數(shù)、?函數(shù)運用)

 更新時間:2025年04月12日 10:02:16   作者:秦老黑  
這篇文章主要介紹了JavaScript中this關鍵字的指向規(guī)則,包括全局環(huán)境、函數(shù)、對象方法、構造函數(shù)、事件處理函數(shù)和箭頭函數(shù)中的this指向,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

前言

this對象:解析器在每次調用函數(shù)時,都會向函數(shù)內部轉遞一個隱含的參數(shù),這個參數(shù)就是this,this指向的是一個對象,這個對象我們稱為函數(shù)執(zhí)行的上下文對象,根據(jù)函數(shù)調用方式的不同,this會指向不同的對象

一、將根據(jù)一下幾個方面介紹this的指向問題

  • 全局環(huán)境中的 this
  • 函數(shù)中的 this
  • 對象方法中的 this
  • 構造函數(shù)中的 this
  • 事件處理函數(shù)中的 this
  • 箭頭函數(shù)中的 this

1、全局環(huán)境中的this

在全局環(huán)境中(不在任何函數(shù)或對象內部),this指向全局對象(在瀏覽器環(huán)境中是window,在node.js中是global

console.log(this === window); // 在瀏覽器中輸出 true

2、函數(shù)中的this

當一個函數(shù)被直接調用時,this在非嚴格模式下指向全局對象(window),在嚴格模式下指向undefined

JS嚴格模式:JavaScript在語法和行為上存在一些模糊的特性,可能導致一些不易察覺的錯誤,為提高代碼的質量和可維護性,js引入了嚴格模式,通過啟用一些額外的規(guī)則,強制執(zhí)行更嚴格的語法和行為。在嚴格模式下代碼中的潛在問題將被捕獲并拋出錯誤,有助于提前發(fā)現(xiàn)和修復潛在bug。

function regularFunction() {
  console.log(this);
}

regularFunction(); // 非嚴格模式下指向 window,嚴格模式下為 undefined

// 演示嚴格模式下的情況
(function () {
  "use strict";
  regularFunction();
})();

3、對象方法中的this

當函數(shù)作為對象的方法被調用時,this指向調用該方法的對象

var person = {
  name: "John",
  sayName: function () {
    console.log(this.name);
  }
};

person.sayName(); // 輸出 "John",這里的 this 指向 person 對象

4、構造函數(shù)中的this

使用new關鍵字(實例化)調用函數(shù)時,該函數(shù)被當作構造函數(shù)(類),this會指向新創(chuàng)建的對象實例

function Person(name) {
  this.name = name;
  this.sayHello = function () {
    console.log("Hello, I'm " + this.name);
  };
}

var john = new Person("John");
john.sayHello(); // 輸出 "Hello, I'm John",這里 this 指向 john 實例

構造函數(shù)怎么執(zhí)行創(chuàng)建對象的過程:

  • 調用一個構造函數(shù),他會立即創(chuàng)建一個對象
  • 將新建的對象設置為函數(shù)中的this,在構造函數(shù)中可以使用this來引用新建的對象
  • 逐行執(zhí)行函數(shù)中的代碼
  • 將新建的對象作為返回值返回

在構造函數(shù)中,創(chuàng)建對象和返回對象都給我們隱藏了,使用同一個構造函數(shù)創(chuàng)建的對象,我們稱為一類對象,也將一個構造函數(shù)稱為一個類。我們將通過一個構造函數(shù)創(chuàng)建的對象,稱為是該類的實例。

5、事件處理函數(shù)中的this

在DOM事件處理函數(shù)中,this通常指向觸發(fā)事件的元素。

<button id="myButton">Click me</button>

<script>
  var button = document.getElementById("myButton");
  button.onclick = function () {
    console.log(this); // 點擊按鈕時,這里的 this 指向按鈕元素
    				  //打印 :<button id="myButton">Click me</button>
  };
</script>

7、箭頭函數(shù)中的this

箭頭函數(shù)沒有自己的this,它的this繼承自外層作用域的this

// 普通函數(shù)
function outerFunction() {
  this.name = "Outer";
  var innerFunction = function () {
    console.log(this.name);
  };
  innerFunction();
}

// 箭頭函數(shù)
function outerFunctionWithArrow() {
  this.name = "Outer with Arrow";
  var innerFunction = () => {
    console.log(this.name);
  };
  innerFunction();
}

new outerFunction(); // 輸出 undefined,因為 innerFunction 中的 this 指向全局對象,全局對象沒有 name 屬性
new outerFunctionWithArrow(); // 輸出 "Outer with Arrow",箭頭函數(shù)的 this 繼承自 outerFunctionWithArrow 的 this

二、改變this指向的方法

由于箭頭函數(shù)的this來自于繼承,箭頭函數(shù)無法使用以下三種方法改變this指向

1、call()方法

  • call 方法是附加在函數(shù)調用后面使用,可以忽略函數(shù)本身的 this 指向
  • 語法: 函數(shù)名.call(要改變的 this 指向,要給函數(shù)傳遞的參數(shù)1,要給函數(shù)傳遞的參數(shù)2, ...)
  • 使用 call 方法的時候:
    1、會立即執(zhí)行函數(shù)
    2、第一個參數(shù)是你要改變的函數(shù)內部的 this 指向
    3、第二個參數(shù)開始,依次是向函數(shù)傳遞參數(shù)
var obj = { name: 'Jack' }
function fn(a, b) {
  console.log(this)
  console.log(a)
  console.log(b)
}
fn(1, 2)
fn.call(obj, 1, 2)
  • fn(1,2) 的時候,函數(shù)內部的 this 指向 window(函數(shù)被直接調用)
  • fn.call(obj, 1, 2) 的時候,函數(shù)內部的 this 就指向了 obj 這個對象

2、apply()方法

  • apply 方法是附加在函數(shù)調用后面使用,可以忽略函數(shù)本身的 this 指向
  • 語法: 函數(shù)名.apply(要改變的 this 指向,[要給函數(shù)傳遞的參數(shù)1, 要給函數(shù)傳遞的參數(shù)2, ...])
  • 使用 call 方法的時候:
    1、會立即執(zhí)行函數(shù)
    2、第一個參數(shù)是你要改變的函數(shù)內部的 this 指向
    3、第二個參數(shù)是一個 數(shù)組,數(shù)組里面的每一項依次是向函數(shù)傳遞的參數(shù)(和call方法的主要區(qū)別點)
var obj = { name: 'Jack' }
function fn(a, b) {
  console.log(this)
  console.log(a)
  console.log(b)
}
fn(1, 2)
fn.apply(obj, [1, 2])
  • fn(1,2) 的時候,函數(shù)內部的 this 指向 window(函數(shù)被直接調用)
  • fn.call(obj, 1, 2) 的時候,函數(shù)內部的 this 就指向了 obj 這個對象

3、bind()方法

  • bind 方法是附加在函數(shù)調用后面使用,可以忽略函數(shù)本身的 this 指向
  • 和 call / apply 有一些不一樣,就是不會立即執(zhí)行函數(shù),而是返回一個已經改變了 this 指向的函數(shù)
  • 語法: var newFn = 函數(shù)名.bind(要改變的 this 指向); newFn(傳遞參數(shù))
var obj = { name: 'Jack' }
function fn(a, b) {
  console.log(this)
  console.log(a)
  console.log(b)
}
fn(1, 2)
var newFn = fn.bind(obj)
newFn(1, 2)
  • bind 調用的時候,不會執(zhí)行 fn 這個函數(shù),而是返回一個新的函數(shù)
  • 這個新的函數(shù)就是一個改變了 this 指向以后的 fn 函數(shù)
  • fn(1, 2) 的時候 this 指向 window
  • newFn(1, 2) 的時候執(zhí)行的是一個和 fn 一摸一樣的函數(shù),只不過里面的 this 指向改成了 obj

三、回調函數(shù)中this指向

這里我們補充一下在回調函數(shù)運用中this指向(也是容易混淆的知識點)

1、對象方法作為回調函數(shù)

如果回調函數(shù)是一個對象的方法,并且是以對象方法的方式傳遞進去的,那么 this 通常會指向該對象。

var myObject = {
  value: 10,
  callbackFunction: function () {
    console.log(this.value);
  }
};
[1,2,3].forEach(() => {
  myObject.callbackFunction()
});        //輸出三個10

在這個例子中,forEach 是數(shù)組的方法,myObject.callbackFunction 作為回調函數(shù)傳遞給 forEach。當 forEach 調用這個回調函數(shù)時,this 仍然指向 myObject,因為這個函數(shù)本質上還是 myObject 的一個方法。

2、箭頭函數(shù)作為回調函數(shù)

箭頭函數(shù)沒有自己的 this,它會繼承外層作用域的 this(依據(jù)詞法作用域規(guī)則)。

function outerFunction() {
  this.name = "Outer";
  var array = [1, 2, 3];
  array.forEach(() => {
    console.log(this.name);  //打印三次Outer
  });
}
new outerFunction();

根據(jù)上面兩個例子,這里我們介紹一下普通函數(shù)箭頭函數(shù)在確定this指向時的一些區(qū)別:

1、普通函數(shù)

普通函數(shù)在函數(shù)定義時會確定函數(shù)的作用域,但不會明確函數(shù)中this的指向。普通函數(shù)中this的指向是在函數(shù)被調用時被確定(指向調用者或者全局對象)

2、箭頭函數(shù)

箭頭函數(shù)由于其本身不會生成this,其this繼承自外層作用域。箭頭函數(shù)在定義時不僅會確定作用域,而且會捕獲外層作用域的this作為自身的this,箭頭函數(shù)的this在定義時就已經確定,在其后的函數(shù)調用時,無論調用箭頭函數(shù)的是誰它的this指向都不會發(fā)生改變。

以上面這個例子為例:

箭頭函數(shù)定義在 outerFunction 這個函數(shù)內部,注意不是定義在 forEach 方法內。具體可以了解一下函數(shù)傳參的步驟,這里箭頭函數(shù)是先在 outerFunction 這個函數(shù)內部定義,之后才作為參數(shù)傳給 forEach 方法。箭頭函數(shù)繼承了 outerFunction 函數(shù)的this,并在之后被 forEach 方法調用時不會發(fā)生改變。

3、回調函數(shù)指向全局對象的常見情況

當普通函數(shù)作為回調函數(shù),并且這個普通函數(shù)是被一個全局函數(shù)(如 setTimeout、setInterval)或者在全局作用域中獨立調用的函數(shù)(沒有通過對象來調用)調用時,在非嚴格模式下,this 通常會指向全局對象。

//被一個全局函數(shù)調用
setTimeout(function () {
  console.log(this); 
}, 1000);
//在全局作用域中獨立調用
  function outer(){
    inner()
  }
  function inner(){
    console.log(this);
  }
  outer()

四、總結與常見錯誤示例

this指向:1、普通函數(shù):誰調用函數(shù),this就指向誰,沒有調用者就指向全局對象Window
2、箭頭函數(shù):箭頭函數(shù)不會創(chuàng)建this,它的this繼承自上層作用域中的this

1、案例一

//回調函數(shù)中錯誤使用this
var person = {
  name: "Eve",
  greetLater: function () {
    setTimeout(function () {
      console.log(this.name); // 此處的function為普通函數(shù),作為setTimeout的參數(shù)this指向全局對象
    }, 1000);
  }
};

person.greetLater();

此處的function為普通函數(shù),被一個全局函數(shù)調用,其this指向全局對象 Window 。

要想輸出 Eve ,將此處的普通函數(shù)改為箭頭函數(shù)即可。

var person = {
  name: "Eve",
  greetLater: function () {
    setTimeout( ()=> {
      console.log(this.name); // 輸出Eve
    }, 1000);
  }
};

person.greetLater();

2、案例二

//在嵌套函數(shù)中混淆 this 指向
var outer = {
  name: "Outer Object",
  innerFunction: function () {
    var inner = {
      name: "Inner Object",
      nestedFunction: function () {
        console.log(this.name); // 這里 this 指向 inner,而不是 outer
      }
    };
    inner.nestedFunction();
  }
};

outer.innerFunction();

nestedFunction 是作為 inner 對象的方法被調用,this指向 inner 對象(根據(jù)普通函數(shù) this 指向的規(guī)則,當函數(shù)作為對象的方法被調用時,this 會指向調用該函數(shù)的對象。)

4.2.1、使用外層作用域this的方法

想要訪問到 outer 對象的 name 屬性,可以使用以下兩種方法:

1、保存外層 this 的引用

var outer = {
  name: "Outer Object",
  innerFunction: function () {
    var self = this;
    var inner = {
      name: "Inner Object",
      nestedFunction: function () {
        console.log(self.name); // 現(xiàn)在可以訪問到 outer 的 name 屬性,輸出 "Outer Object"
      }
    };
    inner.nestedFunction();
  }
};

outer.innerFunction();

在方法的開頭先把 this 保存到一個變量中(通常命名為 self 或 that 等),然后在 inner 對象中使用這個保存的變量來訪問 outer 對象的屬性。

2、使用箭頭函數(shù)

var outer = {
  name: "Outer Object",
  innerFunction: function () {
    var inner = {
      name: "Inner Object",
      nestedFunction: () => {
        console.log(this.name); // 輸出 "Outer Object"
      }
    };
    inner.nestedFunction();
  }
};

outer.innerFunction();

將 nestedFunction 改為箭頭函數(shù),因為箭頭函數(shù)會繼承外層作用域的 this,在這里外層作用域是 outer.innerFunction(),其 this 指向 outer 對象,所以箭頭函數(shù)里的 this 也能指向 outer 對象。

總結

到此這篇關于JavaScript中this(普通函數(shù)、箭頭函數(shù)、 函數(shù)運用)的文章就介紹到這了,更多相關JS中this普通函數(shù)、箭頭函數(shù)、回調函數(shù)運用內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 小程序實現(xiàn)簡單吸頂效果

    小程序實現(xiàn)簡單吸頂效果

    這篇文章主要為大家詳細介紹了小程序實現(xiàn)簡單吸頂效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 使用 Jest 和 Supertest 進行接口端點測試實例詳解

    使用 Jest 和 Supertest 進行接口端點測試實例詳解

    這篇文章主要介紹了使用 Jest 和 Supertest 進行接口端點測試,結合實例形式詳細分析了使用 Jest 和 Supertest 進行接口端點測試具體原理、操作技巧與相關注意事項,需要的朋友可以參考下
    2020-04-04
  • 微信小程序入門之繪制時鐘

    微信小程序入門之繪制時鐘

    這篇文章主要為大家詳細介紹了微信小程序入門之繪制時鐘,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • IE6下CSS圖片緩存問題解決方法

    IE6下CSS圖片緩存問題解決方法

    ie6下如果用css圖片平鋪,會出現(xiàn)cpu短暫100%的情況,主要原因在于,ie6會重復下載圖片。
    2010-12-12
  • js函數(shù)的延遲加載實現(xiàn)代碼

    js函數(shù)的延遲加載實現(xiàn)代碼

    延遲加載的函數(shù),第一次調用后,會覆蓋原來的老函數(shù),以后再次調用的是新函數(shù),不會再進行條件的判斷,提升效率
    2012-10-10
  • fmt:formatDate的輸出格式詳解

    fmt:formatDate的輸出格式詳解

    本篇文章主要是對fmt:formatDate的輸出格式進行了詳細的介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • Javascript實現(xiàn)單例模式

    Javascript實現(xiàn)單例模式

    單例模式也稱作為單子模式,更多的也叫做單體模式。為軟件設計中較為簡單但是最為常用的一種設計模式。這篇文章主要介紹了Javascript實現(xiàn)單例模式的相關資料,需要的朋友可以參考下
    2016-01-01
  • ionic grid(柵格)九宮格制作詳解

    ionic grid(柵格)九宮格制作詳解

    這篇文章主要為大家詳細介紹了ionic grid九宮格的制作方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • 一文全面解析JS中的this綁定規(guī)則

    一文全面解析JS中的this綁定規(guī)則

    寫過JavaScript的都知道,JS中的this相對來講是比較難以捉摸的,尤其在一些復雜的場景下的指向總是讓人摸不著頭腦,所以這篇文章我們就來系統(tǒng)的學習和研究一下this的綁定規(guī)則,需要的朋友可以參考下
    2024-04-04
  • js綜合應用實例簡單的表格統(tǒng)計

    js綜合應用實例簡單的表格統(tǒng)計

    在做調查問卷的過程中,遇到一個表格的統(tǒng)計問題,一個需要用到js方面的綜合知識,感覺還不錯所以記錄下來與大家分享,感興趣的朋友可以了解下
    2013-09-09

最新評論