新聞中心
[[393083]]
一、對(duì)象方法,"this"
通常創(chuàng)建對(duì)象來(lái)表示真實(shí)世界中的實(shí)體,如用戶和訂單等:

成都創(chuàng)新互聯(lián)成立與2013年,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站建設(shè)、做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元山亭做網(wǎng)站,已為上家服務(wù),為山亭各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18980820575
- let user = {
- name: "John",
- age: 30
- };
并且,在現(xiàn)實(shí)世界中,用戶可以進(jìn)行 操作:從購(gòu)物車中挑選某物、登錄和注銷等。
在 JavaScript 中,行為(action)由屬性中的函數(shù)來(lái)表示。
二、方法示例
剛開始,我們來(lái)教 user 說(shuō) hello:
- let user = {
- name: "John",
- age: 30
- };
- user.sayHi = function() {
- alert("Hello!");
- };
- user.sayHi(); // Hello!
這里我們使用函數(shù)表達(dá)式創(chuàng)建了一個(gè)函數(shù),并將其指定給對(duì)象的 user.sayHi 屬性。
隨后我們像這樣 user.sayHi() 調(diào)用它。用戶現(xiàn)在可以說(shuō)話了!
作為對(duì)象屬性的函數(shù)被稱為 方法。
所以,在這我們得到了 user 對(duì)象的 sayHi 方法。
當(dāng)然,我們也可以使用預(yù)先聲明的函數(shù)作為方法,就像這樣:
- let user = {
- // ...
- };
- // 首先,聲明函數(shù)
- function sayHi() {
- alert("Hello!");
- };
- // 然后將其作為一個(gè)方法添加
- user.sayHi = sayHi;
- user.sayHi(); // Hello!
- *面向?qū)ο缶幊?
- 當(dāng)我們?cè)诖a中用對(duì)象表示實(shí)體時(shí),就是所謂的 面向?qū)ο缶幊?,?jiǎn)稱為 “OOP”。
- OOP 是一門大學(xué)問(wèn),本身就是一門有趣的科學(xué)。怎樣選擇合適的實(shí)體?如何組織它們之間的交互?這就是架構(gòu),有很多關(guān)于這方面的書,例如 E. Gamma、R. Helm、R. Johnson 和 J. Vissides 所著的《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》,G. Booch 所著的《面向?qū)ο蠓治雠c設(shè)計(jì)》等。
三、方法簡(jiǎn)寫
在對(duì)象字面量中,有一種更短的(聲明)方法的語(yǔ)法:
- // 這些對(duì)象作用一樣
- user = {
- sayHi: function() {
- alert("Hello");
- }
- };
- // 方法簡(jiǎn)寫看起來(lái)更好,對(duì)吧?
- let user = {
- sayHi() { // 與 "sayHi: function()" 一樣
- alert("Hello");
- }
- };
如上所示,我們可以省略 "function",只寫 sayHi()。
說(shuō)實(shí)話,這種表示法還是有些不同。在對(duì)象繼承方面有一些細(xì)微的差別(稍后將會(huì)介紹),但目前它們并不重要。在幾乎所有的情況下,較短的語(yǔ)法是首選的。
四、方法中的 “this”
通常,對(duì)象方法需要訪問(wèn)對(duì)象中存儲(chǔ)的信息才能完成其工作。
例如,user.sayHi() 中的代碼可能需要用到 user 的 name 屬性。
為了訪問(wèn)該對(duì)象,方法中可以使用 this 關(guān)鍵字。
this 的值就是在點(diǎn)之前的這個(gè)對(duì)象,即調(diào)用該方法的對(duì)象。
舉個(gè)例
- let user = {
- name: "John",
- age: 30,
- sayHi() {
- // "this" 指的是“當(dāng)前的對(duì)象”
- alert(this.name);
- }
- };
- user.sayHi(); // John
在這里 user.sayHi() 執(zhí)行過(guò)程中,this 的值是 user。
技術(shù)上講,也可以在不使用 this 的情況下,通過(guò)外部變量名來(lái)引用它:
- let user = {
- name: "John",
- age: 30,
- sayHi() {
- alert(user.name); // "user" 替代 "this"
- }
- };
……但這樣的代碼是不可靠的。如果我們決定將 user 復(fù)制給另一個(gè)變量,例如 admin = user,并賦另外的值給 user,那么它將訪問(wèn)到錯(cuò)誤的對(duì)象。
下面這個(gè)示例證實(shí)了這一點(diǎn):
- let user = {
- name: "John",
- age: 30,
- sayHi() {
- alert( user.name ); // 導(dǎo)致錯(cuò)誤
- }
- };
- let admin = user;
- user = null; // 重寫讓其更明顯
- admin.sayHi(); // TypeError: Cannot read property 'name' of null
如果我們?cè)?alert 中以 this.name 替換 user.name,那么代碼就會(huì)正常運(yùn)行。
五、“this” 不受限制
在 JavaScript 中,this 關(guān)鍵字與其他大多數(shù)編程語(yǔ)言中的不同。JavaScript 中的 this 可以用于任何函數(shù),即使它不是對(duì)象的方法。
下面這樣的代碼沒有語(yǔ)法錯(cuò)誤:
- function sayHi() {
- alert( this.name );
- }
this 的值是在代碼運(yùn)行時(shí)計(jì)算出來(lái)的,它取決于代碼上下文。
例如,這里相同的函數(shù)被分配給兩個(gè)不同的對(duì)象,在調(diào)用中有著不同的 “this” 值:
- let user = { name: "John" };
- let admin = { name: "Admin" };
- function sayHi() {
- alert( this.name );
- }
- // 在兩個(gè)對(duì)象中使用相同的函數(shù)
- user.f = sayHi;
- admin.f = sayHi;
- // 這兩個(gè)調(diào)用有不同的 this 值
- // 函數(shù)內(nèi)部的 "this" 是“點(diǎn)符號(hào)前面”的那個(gè)對(duì)象
- user.f(); // John(this == user)
- admin.f(); // Admin(this == admin)
- admin['f'](); // Admin(使用點(diǎn)符號(hào)或方括號(hào)語(yǔ)法來(lái)訪問(wèn)這個(gè)方法,都沒有關(guān)系。)
這個(gè)規(guī)則很簡(jiǎn)單:如果 obj.f() 被調(diào)用了,則 this 在 f 函數(shù)調(diào)用期間是 obj。所以在上面的例子中 this 先是 user,之后是 admin。
在沒有對(duì)象的情況下調(diào)用:this == undefined
我們甚至可以在沒有對(duì)象的情況下調(diào)用函數(shù):
- function sayHi() {
- alert(this);
- }
- sayHi(); // undefined
在這種情況下,嚴(yán)格模式下的 this 值為 undefined。如果我們嘗試訪問(wèn) this.name,將會(huì)報(bào)錯(cuò)。
在非嚴(yán)格模式的情況下,this 將會(huì)是 全局對(duì)象(瀏覽器中的 window,我們稍后會(huì)在 全局對(duì)象 一章中學(xué)習(xí)它)。這是一個(gè)歷史行為,"use strict" 已經(jīng)將其修復(fù)了。
通常這種調(diào)用是程序出錯(cuò)了。如果在一個(gè)函數(shù)內(nèi)部有 this,那么通常意味著它是在對(duì)象上下文環(huán)境中被調(diào)用的。
解除 this 綁定的后果
如果你經(jīng)常使用其他的編程語(yǔ)言,那么你可能已經(jīng)習(xí)慣了“綁定 this”的概念,即在對(duì)象中定義的方法總是有指向該對(duì)象的 this。
在 JavaScript 中,this 是“自由”的,它的值是在調(diào)用時(shí)計(jì)算出來(lái)的,它的值并不取決于方法聲明的位置,而是取決于在“點(diǎn)符號(hào)前”的是什么對(duì)象。
在運(yùn)行時(shí)對(duì) this 求值的這個(gè)概念既有優(yōu)點(diǎn)也有缺點(diǎn)。一方面,函數(shù)可以被重用于不同的對(duì)象。另一方面,更大的靈活性造成了更大的出錯(cuò)的可能。
這里我們的立場(chǎng)并不是要評(píng)判編程語(yǔ)言的這個(gè)設(shè)計(jì)是好是壞。而是要了解怎樣使用它,如何趨利避害。
六、箭頭函數(shù)沒有自己的 “this”
箭頭函數(shù)有些特別:它們沒有自己的 this。如果我們?cè)谶@樣的函數(shù)中引用 this,this 值取決于外部“正常的”函數(shù)。
舉個(gè)例子,這里的 arrow() 使用的 this 來(lái)自于外部的 user.sayHi() 方法:
- let user = {
- firstName: "Ilya",
- sayHi() {
- let arrow = () => alert(this.firstName);
- arrow();
- }
- };
- user.sayHi(); // Ilya
這是箭頭函數(shù)的一個(gè)特性,當(dāng)我們并不想要一個(gè)獨(dú)立的 this,反而想從外部上下文中獲取時(shí),它很有用。在后面的 深入理解箭頭函數(shù) 一章中,我們將深入介紹箭頭函數(shù)。
七、總結(jié)
- 存儲(chǔ)在對(duì)象屬性中的函數(shù)被稱為“方法”。
- 方法允許對(duì)象進(jìn)行像 object.doSomething() 這樣的“操作”。
- 方法可以將對(duì)象引用為 this。
this 的值是在程序運(yùn)行時(shí)得到的。
- 一個(gè)函數(shù)在聲明時(shí),可能就使用了 this,但是這個(gè) this 只有在函數(shù)被調(diào)用時(shí)才會(huì)有值。
- 可以在對(duì)象之間復(fù)制函數(shù)。
- 以“方法”的語(yǔ)法調(diào)用函數(shù)時(shí):object.method(),調(diào)用過(guò)程中的 this 值是 object。
請(qǐng)注意箭頭函數(shù)有些特別:它們沒有 this。在箭頭函數(shù)內(nèi)部訪問(wèn)到的 this 都是從外部獲取的。
網(wǎng)頁(yè)標(biāo)題:完全搞懂對(duì)象方法,"this"的六項(xiàng)正面與側(cè)面
標(biāo)題路徑:http://m.5511xx.com/article/copijij.html


咨詢
建站咨詢
