不知道大家有沒有註意過對象中的一些通用方法,例如所有所有的對象都有 toString、constructor 等等一些方法。 當然如果要仔細看的話,大家可以: var a = {}; console.log(a); 我們可以清晰的看到他有很多的內置方法。當然,也可以看到最下麵有兩個比較怪的方法 ge ...
當然如果要仔細看的話,大家可以:
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 內置函數,就不奇怪了。
總結