Javascript this 的一些學習總結_javascript技巧
相信有C 、C#或Java等程式設計經驗的各位,對於this關鍵字再熟悉不過了。由於Javascript是一種物件導向的程式語言,它和C 、C#或Java一樣都包含this關鍵字,接下來我們將向大家介紹Javascript中的this關鍵字。
本文目錄
全域程式碼中的this
函數中的this
引用型別
函式呼叫以及非引用型別
引用型別以及this的null值
函式作為建構器被呼叫時this的值
手動設定函數呼叫時this的值
1.1.2 正文
由於許多物件導向的程式語言都包含this關鍵字,我們會很自然地把this和物件導向的程式設計方式連結在一起,this通常指向利用建構器新創建出來的物件。而在ECMAScript中,this不只用來表示創建出來的對象,也是執行上下文的屬性:
複製程式碼
複製程式碼
全域程式碼中的this
複製程式碼
程式碼如下:
/ Global scope
// The implicit property of
// the global object
foo1 = "abc";
alert(foo1); // abc
// The explicit property of
// the global object
函數中的this
當this在函數程式碼中,情況就複雜多了,並且會引發很多的問題。
函數程式碼中this值的第一個特性(同時也是最主要的特性)就是:它並非靜態的綁定在函數上。
正如先前所提到的,this的值是在進入執行上下文(Excution context)的階段確定的,並且在函數程式碼中的話,其值每次都不盡相同。
然而,一旦進入執行程式碼階段,其值就不能改變了。如果要想給this一個新的值是不可能的,因為在那時this根本就不是變數了。
接下來,我們透過具體的例子來說明函數中的this。
首先我們定義兩個物件foo和person,foo包含一個屬性name,而person包含屬性name和方法say(),具體的定義如下:
複製程式碼
程式碼如下:
// Defines foo object.
name: "Foo"
}; 🎜>// Defines person object.
var person = {
name: "JK_Rush",
// the same function say
foo.say = person.say;
foo.say(); // My name is Foo.
透過上面的程式碼,我們發現呼叫person的say()方法時,this指向person對象,當透過賦值方式使得foo的say()方法指向peson中的say()方法。我們呼叫foo的say()方法,發現this不是指向person對象,而不是指向foo對象,這究竟是什麼原因呢?
首先,我們必須知道this的值在函數中是非靜態的,它的值確定在函數調用時,具體程式碼執行前,this的值是由激活上下文程式碼的呼叫者決定的,比如說,調用函數的外層上下文;更重要的是,this的值是由呼叫表達式的形式決定的,所以說this並非靜態的綁定在函數上。
由於this並非靜態地綁定在函數上,那麼我們是否可以在函數中動態地修改this的值呢?
複製程式碼
現在我們在方法say()中,動態地修改this的值,當我們重新執行以上程式碼,發現this的值引用錯誤。這是由於一旦進入執行程式碼階段(函數呼叫時,具體程式碼執行前),this的值就確定了,所以不能改變了。
引用類型
前面我們提到this的值是由啟動上下文程式碼的呼叫者決定的,更重要的是,this的值是由呼叫表達式的形式決定的;那麼表達式的形式是如何影響this的值呢?
首先,讓我們介紹一個內部類型-引用類型,它的值可以用偽代碼表示為一個擁有兩個屬性的物件分別是:base屬性(屬性所屬的物件)以及該base物件中的propertyName屬性:
// Reference type.
// Reference type. = {
base: mybase,
propertyName : 'mybasepropertyName'
引用類型的值只有可能是以下兩種情況:
當處理一個標識符的時候
或是進行屬性存取的時候
// Declares varible.
// Declares varible.
var foo = 23232 ;
function say() {
// Your code.
程式碼如下:
// Reference type.
var fooRefer>var fooRefer. >base: global,
propertyName: 'foo'
};
var sayReference = {
propertyName: 'say'
}; 複製程式碼
複製程式碼
程式碼如下:
複製程式碼
程式碼如下:
程式碼如下: 程式碼如下:
// Reference type.
var fooSayReference = {
base: foo,
propertyName: 'say'
};
我們發現say()方法的base屬性值為foo對象,那麼它對應的this屬性也會指向foo對象。
假設,我們直接呼叫say()方法,它對應的參考類型如下:
base: global,
propertyName: 'say'
};
propertyName: 'say'
由於🎜>由於🎜>因為; say()方法的base屬性值為global(通常來說是window object),那麼它對應的this屬性也會指向global。
// Declares object.
var foo = {
bar: function () {
alert(this);
}
};
(foo. bar)(); // foo.
(foo.bar = foo.bar)(); // global?
(false || foo.bar)(); // global?
( foo.bar, foo.bar)(); // global
這裡注意到四個表達式中,只有第一個表達式this是指向foo物件的,而其他三個表達式則執行global。
現在我們又有疑問了:為什麼屬性訪問,但是最終this的值不是引用型別物件而是全域物件呢?
我們注意到表達式二是賦值(assignment operator),與表達式一組運算子不同的是,它會觸發呼叫GetValue方法(參見11.13.1中的第三步)。 最後回傳的時候就是一個函數物件了(而不是引用型別的值了),這表示this的值會被設定為null,最後會變成全域物件。
第三和第四種情況也是類似的-逗號運算子和OR邏輯表達式都會觸發呼叫GetValue方法,於是相應地就會失去原先的引用型別值,變成了函數型,this的值就變成全了全局對象了。
引用型別以及this的null值
對於前面提及的情形,還有例外的情況,當呼叫表達式左邊是引用型別的值,但是this的值卻是null,最後變成全域物件(global object)。 發生這種情況的條件是當引用類型值的base物件恰好為活躍物件(activation object)。
當內部子函數在父函數中被呼叫的時候就會發生這種情況,透過下面的示意程式碼介紹活躍物件:
// Declares foo function.
function foo() {
function bar() {
alert(this); / global
}
// The same as AO.bar().
bar();
}
由於活躍物件(activation object)總是會傳回this值為-null(用偽代碼表示AO.bar()就相當於null.bar()),然後,this的值最後會由null轉變為全域物件。
當函數呼叫包含在with語句的程式碼區塊中,且with物件包含一個函數屬性的時候,就會出現例外的情況。 with語句會將該物件加入到作用域鏈的最前面,在活躍物件的之前。 相應地,在引用類型的值(標識符或屬性存取)的情況下,base物件就不再是活躍物件了,而是with語句的物件。另外,值得一提的是,它不只針對內部函數,全域函數也是如此, 原因就是with物件掩蓋了作用域鏈中更高層的物件(全域物件或活躍物件):
函數作為建構器被呼叫時this的值
函數當作建構子時,我們透過new運算子建立實例物件是,它會呼叫Foo()函數的內部[[Construct]]方法;在物件建立之後,會呼叫內部的[[Call]]方法,然後所有Foo()函數中this的值會設定為新建立的物件。
// Declares constructor
// Declares constructor
function Foo()
// The new object.
alert(this);
this.x = 10;
}
var foo = new Foo();
alert(foo.x); // 23手動設定函數呼叫時this的值
程式碼如下:
var myObject = {};
var myFunction = function(param1, param2) {
//setviacall()'this'points to my Object when function is invoked
this. foo = param1;
this.bar = param2;
//logs Object{foo = 'foo', bar = 'bar'}
console.log(this);
};
};
}; >// invokes function, set this value to myObject
call()方法第一個參數是必要的this值,接著我們可以傳遞任意多個參數,接著介紹apply()方法的使用。
var myObject = {};
var myObject = {};
var myFunction = function(param1, param2) {
//set via apply(), this points to my Object when function is invoked
this.foo=param1;
this.bar=param2
; logs Object{foo='foo', bar='bar'}
console.log(this);
};
// invoke function, set this value
myFunction.apply(myObject, ['foo', 'bar']);
console.log(myObject);
透過與call()方法對比,我們發現apply()方法和call()方法沒有太大的區別,只是方法簽名不一樣。
1.1.3 總結
本文介紹Javascript中this的使用,更重要的是幫助我們能更好地理解this值在全局、函數、建構函數以及一些特例的情況中位數的變化。
對於在函數上下文中this的值是函數呼叫者提供並且由當前呼叫表達式的形式而定的。如果在呼叫括號()的左邊有引用類型的值,那麼this的值就會設定為該引用類型值的base物件。 所有其他情況下(非引用類型),this的值總是null。然而,由於null對於this來說沒有任何意義,因此會隱式轉換為全域物件。
對於特例情況,我們要記住賦值符、逗號運算子以及||邏輯表達式,會使this丟失原先的引用類型值,變成了函數類型,this的值就變成了全域物件了參考
[1] http://dmitrysoshnikov.com/ecmascript/chapter-3-this/ 英文版
[2] http:// blog.goddyzhao.me/post/11218727474/this 翻譯
[3]
https://net.tutsplus.com/tutorials/javascript-ajax/fully-understanding-the-this-keyplus.com/tutorials/javascript-ajax/fully-understanding-the-this-keyplusword/ [作者]: JK_Rush

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數
