您好,登錄后才能下訂單哦!
這篇文章主要講解了“this 的六項正面與側(cè)面是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“this 的六項正面與側(cè)面是什么”吧!
通常創(chuàng)建對象來表示真實世界中的實體,如用戶和訂單等:
let user = { name: "John", age: 30 };
并且,在現(xiàn)實世界中,用戶可以進(jìn)行 操作:從購物車中挑選某物、登錄和注銷等。
在 JavaScript 中,行為(action)由屬性中的函數(shù)來表示。
剛開始,我們來教 user 說 hello:
let user = { name: "John", age: 30 }; user.sayHi = function() { alert("Hello!"); }; user.sayHi(); // Hello!
這里我們使用函數(shù)表達(dá)式創(chuàng)建了一個函數(shù),并將其指定給對象的 user.sayHi 屬性。
隨后我們像這樣 user.sayHi() 調(diào)用它。用戶現(xiàn)在可以說話了!
作為對象屬性的函數(shù)被稱為 方法。
所以,在這我們得到了 user 對象的 sayHi 方法。
當(dāng)然,我們也可以使用預(yù)先聲明的函數(shù)作為方法,就像這樣:
let user = { // ... }; // 首先,聲明函數(shù) function sayHi() { alert("Hello!"); }; // 然后將其作為一個方法添加 user.sayHi = sayHi; user.sayHi(); // Hello!
*面向?qū)ο缶幊?
當(dāng)我們在代碼中用對象表示實體時,就是所謂的 面向?qū)ο缶幊?,簡稱為 “OOP”。
OOP 是一門大學(xué)問,本身就是一門有趣的科學(xué)。怎樣選擇合適的實體?如何組織它們之間的交互?這就是架構(gòu),有很多關(guān)于這方面的書,例如 E. Gamma、R. Helm、R. Johnson 和 J. Vissides 所著的《設(shè)計模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》,G. Booch 所著的《面向?qū)ο蠓治雠c設(shè)計》等。
在對象字面量中,有一種更短的(聲明)方法的語法:
// 這些對象作用一樣 user = { sayHi: function() { alert("Hello"); } }; // 方法簡寫看起來更好,對吧? let user = { sayHi() { // 與 "sayHi: function()" 一樣 alert("Hello"); } };
如上所示,我們可以省略 "function",只寫 sayHi()。
說實話,這種表示法還是有些不同。在對象繼承方面有一些細(xì)微的差別(稍后將會介紹),但目前它們并不重要。在幾乎所有的情況下,較短的語法是首選的。
通常,對象方法需要訪問對象中存儲的信息才能完成其工作。
例如,user.sayHi() 中的代碼可能需要用到 user 的 name 屬性。
為了訪問該對象,方法中可以使用 this 關(guān)鍵字。
this 的值就是在點之前的這個對象,即調(diào)用該方法的對象。
舉個例
let user = { name: "John", age: 30, sayHi() { // "this" 指的是“當(dāng)前的對象” alert(this.name); } }; user.sayHi(); // John
在這里 user.sayHi() 執(zhí)行過程中,this 的值是 user。
技術(shù)上講,也可以在不使用 this 的情況下,通過外部變量名來引用它:
let user = { name: "John", age: 30, sayHi() { alert(user.name); // "user" 替代 "this" } };
……但這樣的代碼是不可靠的。如果我們決定將 user 復(fù)制給另一個變量,例如 admin = user,并賦另外的值給 user,那么它將訪問到錯誤的對象。
下面這個示例證實了這一點:
let user = { name: "John", age: 30, sayHi() { alert( user.name ); // 導(dǎo)致錯誤 } }; let admin = user; user = null; // 重寫讓其更明顯 admin.sayHi(); // TypeError: Cannot read property 'name' of null
如果我們在 alert 中以 this.name 替換 user.name,那么代碼就會正常運行。
在 JavaScript 中,this 關(guān)鍵字與其他大多數(shù)編程語言中的不同。JavaScript 中的 this 可以用于任何函數(shù),即使它不是對象的方法。
下面這樣的代碼沒有語法錯誤:
function sayHi() { alert( this.name ); }
this 的值是在代碼運行時計算出來的,它取決于代碼上下文。
例如,這里相同的函數(shù)被分配給兩個不同的對象,在調(diào)用中有著不同的 “this” 值:
let user = { name: "John" }; let admin = { name: "Admin" }; function sayHi() { alert( this.name ); } // 在兩個對象中使用相同的函數(shù) user.f = sayHi; admin.f = sayHi; // 這兩個調(diào)用有不同的 this 值 // 函數(shù)內(nèi)部的 "this" 是“點符號前面”的那個對象 user.f(); // John(this == user) admin.f(); // Admin(this == admin) admin['f'](); // Admin(使用點符號或方括號語法來訪問這個方法,都沒有關(guān)系。)
這個規(guī)則很簡單:如果 obj.f() 被調(diào)用了,則 this 在 f 函數(shù)調(diào)用期間是 obj。所以在上面的例子中 this 先是 user,之后是 admin。
在沒有對象的情況下調(diào)用:this == undefined
我們甚至可以在沒有對象的情況下調(diào)用函數(shù):
function sayHi() { alert(this); } sayHi(); // undefined
在這種情況下,嚴(yán)格模式下的 this 值為 undefined。如果我們嘗試訪問 this.name,將會報錯。
在非嚴(yán)格模式的情況下,this 將會是 全局對象(瀏覽器中的 window,我們稍后會在 全局對象 一章中學(xué)習(xí)它)。這是一個歷史行為,"use strict" 已經(jīng)將其修復(fù)了。
通常這種調(diào)用是程序出錯了。如果在一個函數(shù)內(nèi)部有 this,那么通常意味著它是在對象上下文環(huán)境中被調(diào)用的。
如果你經(jīng)常使用其他的編程語言,那么你可能已經(jīng)習(xí)慣了“綁定 this”的概念,即在對象中定義的方法總是有指向該對象的 this。
在 JavaScript 中,this 是“自由”的,它的值是在調(diào)用時計算出來的,它的值并不取決于方法聲明的位置,而是取決于在“點符號前”的是什么對象。
在運行時對 this 求值的這個概念既有優(yōu)點也有缺點。一方面,函數(shù)可以被重用于不同的對象。另一方面,更大的靈活性造成了更大的出錯的可能。
這里我們的立場并不是要評判編程語言的這個設(shè)計是好是壞。而是要了解怎樣使用它,如何趨利避害。
箭頭函數(shù)有些特別:它們沒有自己的 this。如果我們在這樣的函數(shù)中引用 this,this 值取決于外部“正常的”函數(shù)。
舉個例子,這里的 arrow() 使用的 this 來自于外部的 user.sayHi() 方法:
let user = { firstName: "Ilya", sayHi() { let arrow = () => alert(this.firstName); arrow(); } }; user.sayHi(); // Ilya
這是箭頭函數(shù)的一個特性,當(dāng)我們并不想要一個獨立的 this,反而想從外部上下文中獲取時,它很有用。在后面的 深入理解箭頭函數(shù) 一章中,我們將深入介紹箭頭函數(shù)。
感謝各位的閱讀,以上就是“this 的六項正面與側(cè)面是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對this 的六項正面與側(cè)面是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。