日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
為什么在JavaScript中使用getter和setter是一個(gè)壞主意

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

創(chuàng)新互聯(lián)公司是專業(yè)的海安網(wǎng)站建設(shè)公司,海安接單;提供成都網(wǎng)站建設(shè)、成都網(wǎng)站制作,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行海安網(wǎng)站開發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

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

getter和setter如何工作?

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

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

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

 
 
 
  1. var obj = { 
  2.  
  3.   firstName: "Maks", 
  4.  
  5.   lastName: "Nemisj" 
  6.  
  7. }  

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

 
 
 
  1. Object.defineProperty(person, 'fullName', { 
  2.  
  3.   get: function () { 
  4.  
  5.     return this.firstName + ' ' + this.lastName; 
  6.  
  7.   } 
  8.  
  9. });  

為了得到fullName的計(jì)算值,不需要像person.fullName()帶可怕的括號(hào),只需要使用簡(jiǎn)單的var fullName = person.fullName。

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

 
 
 
  1. Object.defineProperty(person, 'fullName', { 
  2.  
  3.   set: function (value) { 
  4.  
  5.     var names = value.split(' '); 
  6.  
  7.     this.firstName = names[0]; 
  8.  
  9.     this.lastName = names[1]; 
  10.  
  11.   } 
  12.  
  13. });  

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

問題在哪里?

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

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

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

JavaScript會(huì)給出一個(gè)錯(cuò)誤:

 
 
 
  1. person.getFulName(); 
  2.  
  3.        ^ 
  4.  
  5. TypeError: undefined is not a function  

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

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

 
 
 
  1. person.fulName = 'Boris Gorbachev'; 

什么也沒有。對(duì)象是可擴(kuò)展的,可以動(dòng)態(tài)分配鍵和值,因此不會(huì)有錯(cuò)誤在運(yùn)行時(shí)被拋出。

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

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

seal行不行

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

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

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

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

類的到來

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

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

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

 
 
 
  1. class Person { 
  2.  
  3.   constructor(firstName, lastName) { 
  4.  
  5.     this.firstName = firstName; 
  6.  
  7.     this.lastName = lastName; 
  8.  
  9.   } 
  10.  
  11.   getFullName() { 
  12.  
  13.     return this.firstName + ' ' + this.lastName; 
  14.  
  15.   } 
  16.  
  17.   setFullName(value) { 
  18.  
  19.     var names = value.split(' '); 
  20.  
  21.     this.firstName = names[0]; 
  22.  
  23.     this.lastName = names[1]; 
  24.  
  25.   } 
  26.  
  27. }  

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

雖然這種情況在定義getter和setter在一個(gè)類上的時(shí)候沒有任何不同。但它不會(huì)阻止任何人拼錯(cuò)。

 
 
 
  1. class Person { 
  2.  
  3.   constructor(firstName, lastName) { 
  4.  
  5.     this.firstName = firstName; 
  6.  
  7.     this.lastName = lastName; 
  8.  
  9.   } 
  10.  
  11.   get fullName() { 
  12.  
  13.     return this.firstName + ' ' + this.lastName; 
  14.  
  15.   } 
  16.  
  17.   set fullName(value) { 
  18.  
  19.     var names = value.split(' '); 
  20.  
  21.     this.firstName = names[0]; 
  22.  
  23.     this.lastName = names[1]; 
  24.  
  25.   } 
  26.  
  27. }  

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

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

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

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

proxy來幫助?

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

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

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

  • 創(chuàng)建基于Person原型的getter和setter清單。
  • 創(chuàng)建將測(cè)試這些清單的Proxy對(duì)象。

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

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

 
 
 
  1. var names = Object.getOwnPropertyNames(Person.prototype); 
  2.  
  3. var getters = names.filter((name) => { 
  4.  
  5.   var result =  Object.getOwnPropertyDescriptor(Person.prototype, name); 
  6.  
  7.   return !!result.get; 
  8.  
  9. }); 
  10.  
  11. var setters = names.filter((name) => { 
  12.  
  13.   var result =  Object.getOwnPropertyDescriptor(Person.prototype, name); 
  14.  
  15.   return !!result.set; 
  16.  
  17. });  

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

 
 
 
  1. var handler = { 
  2.  
  3.   get(target, name) { 
  4.  
  5.     if (getters.indexOf(name) != -1) { 
  6.  
  7.       return target[name]; 
  8.  
  9.     } 
  10.  
  11.     throw new Error('Getter "' + name + '" not found in "Person"'); 
  12.  
  13.   }, 
  14.  
  15.   set(target, name) { 
  16.  
  17.     if (setters.indexOf(name) != -1) { 
  18.  
  19.       return target[name]; 
  20.  
  21.     } 
  22.  
  23.     throw new Error('Setter "' + name + '" not found in "Person"'); 
  24.  
  25.   } 
  26.  
  27. }; 
  28.  
  29. person = new Proxy(person, handler);  

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

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


網(wǎng)頁(yè)名稱:為什么在JavaScript中使用getter和setter是一個(gè)壞主意
本文鏈接:http://m.5511xx.com/article/codjdso.html