1. 程式人生 > 實用技巧 >探祕隱藏在物件中的get和set方法

探祕隱藏在物件中的get和set方法

不知道大家有沒有注意過物件中的一些通用方法,例如所有所有的物件都有 toString、constructor 等等一些方法。

當然如果要仔細看的話,大家可以:

 var a = {};
    console.log(a);

我們可以清晰的看到他有很多的內建方法。當然,也可以看到最下面有兩個比較怪的方法 get 和 set ,只要是物件就可以找到這兩個方法,但是究竟怎麼使用這兩個方法呢?

我自己研究了半天,發現可以這樣使用,就拿最簡單的物件 json 來舉例。


 var Json = {
        set Leo(value){
            console.log(value)
        }
     };
    Json.Leo 
= 'liyou' //'liyou'

使用起來你會發現非常的怪異, 這個東西看起來像個函式,但是又必需賦值才能用。我們理解起來大概就是,只要一賦值,這個屬性就被從新賦予新的東西,而「這個」則是執行了這個函式。

那麼,到底他是不是函式呢?我們來繼續探索一下這個 set 。



  typeof Json.Leo //undefined 
    Json.Leo() //Error:Json.Leo is not a function 

也就是說,「這個」東西不是作為他的私有屬性存在,而「這個」也不是函式。

繼續實驗的話,會發現「這個」東西只可以傳一個引數。

 var Json = {
 ​
 •       set Leo(value,nextValue){ 
//Uncaught SyntaxError: Setter must have exactly one formal parameter.

程式碼提示一個只允許使用一個引數,也是說他只支援一個引數。當然,如果我們想傳很多的話,似乎也只能通過 json 。

 var Json = {
        set Leo(...val){ //Uncaught SyntaxError: Setter function argument must not be a rest parameter
            console.log(val)
        }
     };
    Json.Leo 
= 'liyou' ​ ​ ​ 不支援 ES6 的不定陣列參,但是支援 arguments 。 ​ ​ ​ var Json = { set Leo(val){ console.log(arguments[0]) } }; Json.Leo = 'liyou' //'liyou';

而 get 方法和他很接近,使用起來就像一個私有的屬性用起來一樣。

例如:


 var Json = {
        set Leo(val){
            console.log(arguments[0])
        },
        get Leo(){
            console.log('liyou')
        } 
     };
    Json.Leo //'liyou';

當然我們可以看出來,如果賦值就會走 set ,如果沒有賦值就會走 get 。

值得一提的是, get 方法是不允許有引數的,一旦裡面放入一個引數,就會直接報錯。

雖然可以順利使 get 方法,但是如果我們想要找到「這個」東西到底,結果是我們依然找不到他。

 Json.Leo //'liyou'
typeof Json.Leo // undefined

簡而言之,一個內建的函式體可以使用,但是不能當作正常的一個私有屬性來判斷其資料型別。

那麼,如果這個函式體碰上了真正的私有屬性會變稱什麼樣呢?

例如:

 var Json = {
 ​
 •      get Leo(){
 •         return 10;
 •      },
 •     Leo:20
 ​
    };
    console.log(Json.Leo)? 

答案是 undefined 。其實也不難怪,因為似乎 js 也不知道你拿的是內建函式體還是私有屬性,而且似乎本來性質也不一樣,所以到頭來也只能給你一個 undefined 。

當然這裡面的 this 還是指向物件本身的。

例如:



 var Json = {
 ​
 •      get Leo(){
 •        return this
 •      }
 ​
    };
    
    Json.b = Json.Leo//

這個時候 json 下面就有無窮無盡的 b ,就像 window 下面有無窮的 window 一樣。

值得一提的是,「這個」東西只能手動的在寫物件的時候寫到裡面,而不能通過賦值去給予。

例如:

  var a = {};
    a['set Leo'] = function(){}//

這裡面的 set 和上文的 set 不是一個東西。

當然 json 中的 get/set 也可以迴圈使用。

例如:



 var Json = {
 ​
 get Leo(){
 ​
 return {
 ​
 get isTeacher(){
 ​
 console.log('liyou')
 ​
 }
 ​
 }
 ​
 }
 ​
 ​
 ​
 }
 ​
 ​
 ​
 Json.Leo.isTeacher //'liyou'

「這個」東西不能在一般的函式中使用。

比如,function show(){set Leo(){}} // 報錯。雖然 new show() 裡面有這個內建函式,但是還是不能使用。

但是卻可以在 ES6 中的 class 物件中使用。

例如:

 class Leo {
 ​
  constructor() {
 ​
  }
 ​
  get show() {
 ​
   return 'liyou';
 ​
  }
 ​
  set show(value) {
 ​
   console.log('liyou: '+value);
 ​
  }
 ​
 }
 ​
 let inst = new Leo();
 ​
 inst.show = 123;
 ​
 // liyou: 123
 ​
 inst.show
 ​
 // 'liyou'

因為class 類本身也屬於函式物件,所以函式物件中有這個 get/set 內建函式,就不奇怪了。

總結

對了,小編為大家準備了一套2020最新的web前端資料,需要點選下方連結獲取方式

學習前端,你掌握這些。二線也能輕鬆拿8K以上