搜尋
首頁web前端js教程JavaScript中的this規則及this物件用法實例

JavaScript中的this規則及this物件用法實例

Feb 08, 2018 am 11:14 AM
javascriptjsthis

想要確定this裡規則是什麼,幾條規則決定函數裡的 this 是什麼。想確定 this 是什麼其實非常簡單。總體的規則是,透過檢查它的呼叫位置,在函數被​​呼叫的時候確定 this。它遵循下面這些規則,接下來以優先順序說明。

規則

1、如果在呼叫函數時使用 new 關鍵字,那麼函數裡的 this 就是一個全新的物件。

function ConstructorExample() {
  console.log(this);
  this.value = 10;
  console.log(this);
}
new ConstructorExample();
// -> {}
// -> { value: 10 }

2、如果使用 apply、call 或 bind 呼叫函數,那麼函數裡的 this 就是作為參數傳進去的物件。

function fn() {
  console.log(this);
}
var obj = {
  value: 5
};
var boundFn = fn.bind(obj);
boundFn();   // -> { value: 5 }
fn.call(obj); // -> { value: 5 }
fn.apply(obj); // -> { value: 5 }

3、如果函數作為一個方法調用,就是說如果使用點符號調用函數,那麼 this 就是擁有這個函數作為屬性的物件。換句話說,當一個點在函數呼叫的左邊時,this 就是這個點左邊的物件。

var obj = {
  value: 5,
  printThis: function() {
    console.log(this);
  }
};
obj.printThis(); // -> { value: 5, printThis: ƒ }

4、如果函數作為一個純粹的函數調用,也就是說,它在沒有上述任何條件的情況下被調用,那麼 this 就是全域物件。在瀏覽器裡,就是 window 物件。

function fn() {
  console.log(this);
}
// 如果在浏览器里调用:
fn(); // -> Window {stop: ƒ, open: ƒ, alert: ƒ, ...}

注意這個規則其實和第三個規則是一樣的,差別在於沒有宣告為方法的函數會自動成為全域物件 window 的屬性。因此,這其實是一個隱式的方法呼叫。當我們呼叫 fn(),其實就會被瀏覽器理解為 window.fn(),所以 this 就是 window。

console.log(fn === window.fn); // -> true

5、如果上述規則有多個適用,那麼優先權較高的就會設定 this 值。

6、如果是 ES2015 裡的箭頭函數,那麼它將忽略上述所有規則,並在創建的時候接收包含它的作用域作為 this 的值。想確定 this 具體是什麼的話,只需從創建箭頭函數那裡往上一行,看看那兒的 this 是什麼,箭頭函數裡的 this 值和它一樣。

const obj = {
  value: 'abc',
  createArrowFn: function() {
    return () => console.log(this);
  }
};
const arrowFn = obj.createArrowFn();
arrowFn(); // -> { value: 'abc', createArrowFn: ƒ }

看回第三個規則,當我們呼叫 obj.createArrowFn() 的時候,createArrowFn 裡的 this 是 obj,因為這是方法呼叫。因此,obj 會在 arrowFn 裡綁定到 this 上。如果我們在全域作用域建立一個箭頭函數,那麼 this 值就會是 window。

應用規則

讓我們來看一個程式碼範例,並應用這些規則。試試看能否弄清楚不同的函數呼叫下,this 是什麼。

確定應用了哪一條規則

var obj = {
  value: 'hi',
  printThis: function() {
    console.log(this);
  }
};
var print = obj.printThis;
obj.printThis(); // -> {value: "hi", printThis: ƒ}
print(); // -> Window {stop: ƒ, open: ƒ, alert: ƒ, ...}

obj.printThis() 屬於第三條規則,方法呼叫。另一方面,print() 屬於第四條規則,純粹的函數呼叫。對於 print() 來說,我們在呼叫的時候沒有使用 new、bind/call/apply 或點符號,所以它對應了規則四,this 就是全域物件 window。

當適用多個規則的時候

當適用多個規則的時候,使用清單裡更高優先順序的規則。

var obj1 = {
  value: 'hi',
  print: function() {
    console.log(this);
  },
};
var obj2 = { value: 17 };

如果規則二和規則三同時適用,那麼規則二佔優。

obj1.print.call(obj2); // -> { value: 17 }

如果規則一和規則三同時適用,那麼規則一佔優。

new obj1.print(); // -> {}

函式庫

有些函式庫有時候會故意將 this 值綁定到某些函數裡。而通常會在函數裡將最有用的值綁定到 this 上使用。舉個例子,jQuery 把 this 綁定到 DOM 元素上,在回呼中觸發一個事件。如果某個函式庫出現一個不太符合上述規則的 this 值,那麼請仔細閱讀這個函式庫的文檔,它很有可能使用 bind 綁定了。

this物件是在函數運行時,基於函數的執行環境綁定的。下面跟大家介紹js中this物件用法的詳細分析,其實這句話的本質就是,誰呼叫了函數,this就指向誰

具體的來說,通常有以下幾種情況:

全域函數

在全域環境中,this指向Window

   
//例子1
 function A() {
 console.log(this)
 }
 A();//Window

上面的例子很簡單,函數A在全域環境中執行,也就是全域物件Window調用了函數。此時this指向Window

物件方法

當物件方法呼叫時,this指向呼叫該方法的物件

//例子2
var b = {
 getThis:function(){
  console.log(this)
 }
}
b.getThis()//b

到這裡我們舉的例子都比較簡單易懂,接下來來一個有趣的:

//例子3
 var c = {
 getFunc:function(){
  return function(){
  console.log(this)
  }
 }
 }
 var cFun = c.getFunc()
 cFun()//Window

這個例子和前一個例子不一樣,運行c.getFunc()時,首先返回的是一個匿名函數,我們將這個函數賦值給cFun ,接著在全域環境中呼叫了cFun(),所以此時this指向的還是Window。

如果我們一定要讓這裡回傳的是c物件呢?在開頭我們說過,this物件是在函數執行時確定的,在例子3中,執行c.getFunc()時,this物件指向的還是c,所以我們只要保持住這個this就好了,對上面的程式碼稍微改動:

   
//例子4
 var c = {
 getFunc:function(){
  var that = this //在这里保留住this
  return function(){
  console.log(that)
  }
 }
 }
 var cFun = c.getFunc()
 cFun()//c

這也就是我們常常可以在一些程式碼中看到var self = this或var that = this之類的原因了。

call和apply

此時this物件通常指向函數中指定的this值(注意這裡的通常2字,考試要考的)

call和apply算是老生常談,但還是稍微介紹下,怕新同學可能沒接觸過(其實是為了湊點字數),拿call來說,語法是這樣的

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

   

這個方法怎麼用呢,看下面的範例:

//例子5
var d = {
 getThis:function(){
  console.log(this)
 }
}
var e = {
 name:'e'//(给e写个`name`属性只是因为觉得孤零零的太难看了~~)
}
d.getThis.call(e)//e

   

在这里我们就可以看出call函数的意思了:指定一个对象o1去调用其他对象o2的方法,此时this对象指向o1

好了,那为什么前面我们说通常呢?因为,这里的thisArg是可以指定为null和undefined的。请看:

   
//例子6
var d = {
 getThis:function(){
  console.log(this)
 }
}
 d.getThis.call(null)//Window
 d.getThis.call(undefined)//Window

   

此时的this指向全局对象Window

箭头函数

es6中的箭头函数现在也用的比较频繁,但是有个需要注意的点是:

函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

其实出现这种情况的根本原因是:箭头函数没有this对象,所以箭头函数的this就是外层代码的this

//例子7
 var f = {
  getThis:()=>{
   console.log(this)
  }
 }
 f.getThis()//Window

   

这个例子和前面例子2是基本一样的,只是把普通函数改写成箭头函数,但是此时的this对象已经指向了外层的Window。

考虑到这一点可能不好理解,我们再看几个例子:

   
//例子8
 var g = {
 getThis:function(){
  return function(){console.log(this)}
 }
 }
 var h = {
 getThis:function(){
  return ()=> console.log(this)
 }
 }
 g.getThis()()//Window
 h.getThis()()//h

这个例子里,g的getThis写法就和之前的例子3一样,由于函数在全局环境中运行,所以此时this指向Window;h的getThis使用了箭头函数,所以this指向了外层代码块的this所以,此时this指向的是h。

总结

一般情况下this对象指向调用函数的对象,全局环境中执行函数this对象指向Window

在call和apply函数中this指向指定的对象,如果指定的对为undefined或者null,那么this对象指向Window

在箭头函数中,this对象等同于外层代码块的this。

相关推荐:

JS中的this、apply、call、bind实例分享

函数调用的不同方式及this的指向详解

html的标签中的this应该如何使用

以上是JavaScript中的this規則及this物件用法實例的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript框架:為現代網絡開發提供動力JavaScript框架:為現代網絡開發提供動力May 02, 2025 am 12:04 AM

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

JavaScript,C和瀏覽器之間的關係JavaScript,C和瀏覽器之間的關係May 01, 2025 am 12:06 AM

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr

node.js流帶打字稿node.js流帶打字稿Apr 30, 2025 am 08:22 AM

Node.js擅長於高效I/O,這在很大程度上要歸功於流。 流媒體匯總處理數據,避免內存過載 - 大型文件,網絡任務和實時應用程序的理想。將流與打字稿的類型安全結合起來創建POWE

Python vs. JavaScript:性能和效率注意事項Python vs. JavaScript:性能和效率注意事項Apr 30, 2025 am 12:08 AM

Python和JavaScript在性能和效率方面的差異主要體現在:1)Python作為解釋型語言,運行速度較慢,但開發效率高,適合快速原型開發;2)JavaScript在瀏覽器中受限於單線程,但在Node.js中可利用多線程和異步I/O提升性能,兩者在實際項目中各有優勢。

JavaScript的起源:探索其實施語言JavaScript的起源:探索其實施語言Apr 29, 2025 am 12:51 AM

JavaScript起源於1995年,由布蘭登·艾克創造,實現語言為C語言。 1.C語言為JavaScript提供了高性能和系統級編程能力。 2.JavaScript的內存管理和性能優化依賴於C語言。 3.C語言的跨平台特性幫助JavaScript在不同操作系統上高效運行。

幕後:什麼語言能力JavaScript?幕後:什麼語言能力JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript在瀏覽器和Node.js環境中運行,依賴JavaScript引擎解析和執行代碼。 1)解析階段生成抽象語法樹(AST);2)編譯階段將AST轉換為字節碼或機器碼;3)執行階段執行編譯後的代碼。

Python和JavaScript的未來:趨勢和預測Python和JavaScript的未來:趨勢和預測Apr 27, 2025 am 12:21 AM

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

Python vs. JavaScript:開發環境和工具Python vs. JavaScript:開發環境和工具Apr 26, 2025 am 12:09 AM

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。