成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么在JavaScript中使用getter和setter是一個壞主意

開發 前端 開發工具
如你所知,getter和setter已經成為了JavaScript的一部分。它們廣泛支持所有的主流瀏覽器,甚至是IE8。但我認為它不是非常適合JavaScript。

[[196708]]

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

我不認為這個點子通常是錯誤的,但我認為它不是非常適合JavaScript。可能看起來getter和setter可以簡化代碼和節省時間,但其實它們會帶來隱藏錯誤,并且這些錯誤***眼看并不明顯。

getter和setter如何工作?

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

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

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

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

計算值fullName會返回firstName和lastName兩者的串聯。

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

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

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

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

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

問題在哪里?

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

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

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

JavaScript會給出一個錯誤:

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

這個錯誤會在適當的時候適當的地方被觸發。訪問函數不存在的對象將觸發錯誤——這是好的。

現在,讓我們來看看當用錯誤的名稱來使用setter的時候會發生什么?

  1. person.fulName = 'Boris Gorbachev'

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

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

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

seal行不行

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

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

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

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

類的到來

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

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

改進person對象,做一個它的real類。person定義了接口用于獲取和設置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.  

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

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

  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.  

有拼寫錯誤的執行不會給出任何錯誤:

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

同樣不嚴格,不冗長,不可追蹤的行為導致可能會出錯。

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

proxy來幫助?

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

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

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

  • 創建基于Person原型的getter和setter清單。
  • 創建將測試這些清單的Proxy對象。

讓我們來實現它。

首先,為了找出什么樣的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. });  

在此之后,創建一個Proxy對象:

  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);  

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

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

責任編輯:龐桂玉 來源: 前端大全
相關推薦

2021-06-24 12:46:40

數據管理模型

2023-09-18 14:54:02

2021-08-31 10:01:04

JavaScript函數屬性

2020-08-02 22:42:25

JavaScript開發

2015-06-08 13:19:11

JavaScriptgettersetter

2016-03-25 10:11:57

BYOD自帶設備

2009-06-29 17:03:41

自動生成Getter和Eclipse

2025-01-15 09:06:58

CSSRegEx前端

2021-07-27 07:12:11

Getter接口Setter

2023-12-04 08:28:35

Docker容器

2015-04-17 16:44:22

swiftOC

2015-08-03 11:45:37

storyboard

2024-11-26 08:30:33

2015-07-28 11:22:30

大數據浪潮

2021-07-30 15:31:35

代碼重用漏洞攻擊

2012-01-04 13:55:23

Canvas

2022-01-03 08:06:15

函數Go數據

2021-10-13 14:06:46

MySQLUtf8符號

2012-04-11 10:39:32

Eclipse

2023-05-16 15:32:45

JavaScriptWeb前端工程師
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 免费成人高清 | 日韩成人免费视频 | 亚洲欧美日韩国产 | 国产精品999 | 精品国产乱码久久久久久老虎 | 亚洲毛片一区二区 | 久久久国产一区二区三区四区小说 | av色站| 日本中文字幕视频 | 国产高清视频 | 久久中文字幕在线 | 亚洲一区视频在线 | 国产精品一区在线播放 | 中文字幕韩在线第一页 | 精品久久久久久久人人人人传媒 | 97伦理最新伦理 | 中文字幕一区二区三区精彩视频 | 欧美九九九 | 日日草天天干 | 亚洲免费婷婷 | 亚洲欧美在线观看 | 一级黄色影片在线观看 | 色婷婷综合久久久中字幕精品久久 | 精品真实国产乱文在线 | 九九视频网 | 黄色小视频入口 | 日韩综合在线 | 色永久| 亚洲在线观看视频 | 成人欧美一区二区三区视频xxx | 伊人网一区 | 久久久久久国产免费视网址 | 国产精久久久久久久 | 久久成人av | 国产91 在线播放 | 国产精品污污视频 | 久久精品视频在线免费观看 | 黑人精品xxx一区一二区 | 午夜性色a√在线视频观看9 | 黄网站免费观看 | av在线一区二区 |