JavaScript中使用getter和setter有什么不好

本篇內(nèi)容介紹了“JavaScript中使用getter和setter有什么不好”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

工農(nóng)網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)建站!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項目制作,到程序開發(fā),運營維護(hù)。創(chuàng)新互聯(lián)建站于2013年創(chuàng)立到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)建站。

如你所知,getter和setter已經(jīng)成為了JavaScript的一部分。它們廣泛支持所有的主流瀏覽器,甚至是IE8。

我不認(rèn)為這個點子通常是錯誤的,但我認(rèn)為它不是非常適合JavaScript??赡芸雌饋韌etter和setter可以簡化代碼和節(jié)省時間,但其實它們會帶來隱藏錯誤,并且這些錯誤***眼看并不明顯。

getter和setter如何工作?

首先小小地總結(jié)一下這些是什么東西:

有時候,我們希望能允許訪問一個會返回動態(tài)計算值的屬性,或者你可能想要反映內(nèi)部變量的狀態(tài),而不使用顯式的方法調(diào)用。

為了說明它們是如何工作的,讓我們來看一個有著兩個屬性的person對象,這兩個屬性為:firstName和lastName,以及一個計算值:fullName。

var obj = {    firstName: "Maks",    lastName: "Nemisj"  }

計算值fullName會返回firstName和lastName兩者的串聯(lián)。

Object.defineProperty(person, 'fullName', {    get: function () {      return this.firstName + ' ' + this.lastName;    }  });

為了得到fullName的計算值,不需要像person.fullName()帶可怕的括號,只需要使用簡單的var fullName =  person.fullName。

這同樣適用于setter,你可以通過使用函數(shù)設(shè)置值:

Object.defineProperty(person, 'fullName', {    set: function (value) {      var names = value.split(' ');      this.firstName = names[0];      this.lastName = names[1];    }  });

使用就和getter一樣簡單:person.fullName = ‘Boris Gorbachev’。這將調(diào)用上面定義的函數(shù),并分離Boris  Gorbachev成firstName和lastName。

問題在哪里?

你也許在想:“嘿,我喜歡getter和setter方法,它們感覺更自然,就像JSON一樣?!蹦阏f得對,它們的確是這樣的,但是我們先退一步來看一看fullName在getter和setter之前是如何工作的。

為得到值,我們將使用類似于getFullName()的一些東西,以及為了設(shè)置值,我們將使用person.setFullName(‘Maks  Nemisj’)。

如果拼錯函數(shù)名,person.getFullName()寫成person.getFulName()會發(fā)生什么呢?

JavaScript會給出一個錯誤:

person.getFulName();         ^  TypeError: undefined is not a function

這個錯誤會在適當(dāng)?shù)臅r候適當(dāng)?shù)牡胤奖挥|發(fā)。訪問函數(shù)不存在的對象將觸發(fā)錯誤——這是好的。

現(xiàn)在,讓我們來看看當(dāng)用錯誤的名稱來使用setter的時候會發(fā)生什么?

person.fulName = 'Boris Gorbachev';

什么也沒有。對象是可擴(kuò)展的,可以動態(tài)分配鍵和值,因此不會有錯誤在運行時被拋出。

這樣的行為意味著錯誤可能顯示在用戶界面上的某個地方,或者,當(dāng)某些操作被執(zhí)行在錯誤的值上時,而并非是打字錯誤的時刻。

跟蹤應(yīng)該發(fā)生在過去但卻顯示在將來的代碼流上的錯誤是如此有意思。

seal行不行

這個問題可以通過sealAPI來部分解決。只要對象是密封的,它就不能突變,也就是意味著fulName將試圖分配一個新鍵到person對象,并且它會失敗。

出于某種原因,當(dāng)我在Node.js V4.0測試這個的時候,它沒有按照我期待的那樣工作。所以,我不能確保這個解決方案。

而更令人沮喪的是,對于setter一點也沒有解決方法。正如我前面提到的,對象是可擴(kuò)展和可故障保護(hù)的,這意味著訪問一個不存在的鍵不會導(dǎo)致任何錯誤。

如果這種情況只適用于對象的文字的話,我不會多此一舉地寫這篇文章,但在ECMAScript  2015(ES6)和用類定義getter和setter能力的興起之后,我決定寫下關(guān)于潛在陷阱的博客。

類的到來

我知道當(dāng)前類在一些JavaScript社區(qū)不是非常受歡迎。人們對在函數(shù)式/基于原型的語言,例如JavaScript中是否需要它們,爭執(zhí)不休。然而,事實是,類就在ECMAScript  2015(ES6)規(guī)范說明中,并且將存在于此一段時間。

對我來說,類是指定在類的外部世界(消費者)和應(yīng)用程序的內(nèi)部世界之間的定義良好的API的一種方式。這就是白紙黑字放入規(guī)則的抽象,并且我們假定這些規(guī)則不會很快改變。

改進(jìn)person對象,做一個它的real類。person定義了接口用于獲取和設(shè)置fullName。

class Person {    constructor(firstName, lastName) {      this.firstName = firstName;      this.lastName = lastName;    }    getFullName() {      return this.firstName + ' ' + this.lastName;    }    setFullName(value) {      var names = value.split(' ');      this.firstName = names[0];      this.lastName = names[1];    }  }

類定義了一個嚴(yán)格的接口描述,但getter和setter方法使其變得不太嚴(yán)格。我們已經(jīng)習(xí)慣了臃腫的錯誤,當(dāng)工作于對象文字和JSON時的鍵中出現(xiàn)拼寫錯誤的時候。我希望至少類能夠更嚴(yán)格,并且在這個意義上,提供更好的反饋給開發(fā)人員。

雖然這種情況在定義getter和setter在一個類上的時候沒有任何不同。但它不會阻止任何人拼錯。

class Person {    constructor(firstName, lastName) {      this.firstName = firstName;      this.lastName = lastName;    }    get fullName() {      return this.firstName + ' ' + this.lastName;    }    set fullName(value) {      var names = value.split(' ');      this.firstName = names[0];      this.lastName = names[1];    }  }

有拼寫錯誤的執(zhí)行不會給出任何錯誤:

var person = new Person('Maks', 'Nemisj');  console.log(person.fulName);

同樣不嚴(yán)格,不冗長,不可追蹤的行為導(dǎo)致可能會出錯。

在我發(fā)現(xiàn)這一點后,我有一個問題:在使用getter和setter的時候,有沒有什么可以做的,以便于使得類更嚴(yán)格?我發(fā)現(xiàn):有是肯定有,但是這值得嗎?增加額外層次的復(fù)雜性到代碼就只是為了使用數(shù)量更少的括號?對于API定義,也可以不使用getter和setter,而這樣一來就能解決這個問題。除非你是一個鐵桿開發(fā)人員,并愿意繼續(xù)進(jìn)行,不然還有另一種解決方案,如下所述。

proxy來幫助?

除了getter和setter方法,ECMAScript  2015(ES6)還自帶proxy對象。proxy可以幫助你確定委托方法,這些委托方法可以在實際訪問鍵執(zhí)行之前,用來執(zhí)行各種操作。事實上,它看起來像動態(tài)getter  / setter方法。

proxy對象可以用來捕捉任何到類的實例的訪問,并且如果在類中沒有找到預(yù)先定義的getter或setter就會拋出錯誤。

為了做到這一點,必須執(zhí)行下面兩個操作:

  • 創(chuàng)建基于Person原型的getter和setter清單。

  • 創(chuàng)建將測試這些清單的Proxy對象。

讓我們來實現(xiàn)它。

首先,為了找出什么樣的getter和setter方法可以用在類Person上,可以使用getOwnPropertyNames和getOwnPropertyDescriptor:

var names = Object.getOwnPropertyNames(Person.prototype);  var getters = names.filter((name) => {    var result =  Object.getOwnPropertyDescriptor(Person.prototype, name);    return !!result.get;  });  var setters = names.filter((name) => {    var result =  Object.getOwnPropertyDescriptor(Person.prototype, name);    return !!result.set;  });

在此之后,創(chuàng)建一個Proxy對象:

var handler = {    get(target, name) {      if (getters.indexOf(name) != -1) {        return target[name];      }      throw new Error('Getter "' + name + '" not found in "Person"');    },    set(target, name) {      if (setters.indexOf(name) != -1) {        return target[name];      }      throw new Error('Setter "' + name + '" not found in "Person"');    }  };  person = new Proxy(person, handler);

現(xiàn)在,只要你嘗試訪問person.fulName,就會顯示Error: Getter “fulName” not found in  “Person”的消息。

希望這篇文章可以幫助你全面了解getter和setter方法,以及它們將會帶到代碼中的危險。

“JavaScript中使用getter和setter有什么不好”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

當(dāng)前名稱:JavaScript中使用getter和setter有什么不好
網(wǎng)站鏈接:http://bm7419.com/article10/jjcodo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站、虛擬主機、網(wǎng)站維護(hù)網(wǎng)站改版、網(wǎng)站收錄網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作