js 對象 get set 詳解

參考javascript忍着祕籍(第二版),有興趣的可以去看下,由淺入深惡補js基礎。

一、 getter和setter來控制屬性訪問

代理是我們通過代理控制對另一個對象的訪問。通過代理可以定義當對象發生交互時可執行的自定義行爲——如讀取或設置屬性值,或調用方法。

JavaScript中,可以通過兩種方式定義gettersetter

  • 通過對象字面量定義,或者在ES6class中定義
  • 通過使用內置的Object.defineProperty方法。
    接下來我們將用兩種方式裏分別實現getter跟setter。

1. 在es6的class中使用getter和setter

class NinjaCollection {
      constructor() {
        this.ninjas = ['Slim', 'Beautiful', 'Lovely']
      }
      get firstNinja() {
        console.log('Getting firstNinja')
        return this.ninjas[0]
      }
      set firstNinja(value) {
        console.log('Setting firstNinja')
        return this.ninjas[0] = value
      }
    }
    const ninjiaCollection = new NinjaCollection();

    console.log(ninjiaCollection.firstNinja === 'Slim', '第一次取值')
    ninjiaCollection.firstNinja = 'Kind'
    console.log(ninjiaCollection.firstNinja === 'Slim', 'Error: 重新賦值後的取值')
    console.log(ninjiaCollection.firstNinja === 'Kind', '重新賦值後的取值')

運行結果如下:
在這裏插入圖片描述

通過日誌我們可以很清楚明瞭的看清set和get的工作內容。

2. 通過使用內置的Object.defineProperty方法

get:指讀取屬性時調用的函數。
set:指寫入屬性時調用的函數。
看下面這個例子,我們來了解下寫入與讀取

let ninja = {
    name:'小花',
    age:16
}

ninja.age = 17;
ninja.age = 18;
console.log('===>1',ninja.age)

Object.defineProperty(ninja,'age',{
    set:function(newAge){
        console.log(this.name+'現在'+newAge+'歲')
    },
    get:function(){
	    return 16;
	}
}) 
//賦值
ninja.age = 17;
ninja.age = 18;
console.log('===>2',ninja.age)

可以先猜下console.log1跟console.log2的結果,第一個是沒有對getset做任何操作。第二個是我們自定義了getset函數。
運行結果如下:
在這裏插入圖片描述
在這裏看到,我們獲取ninja.age的時候只能是得到16,因爲本質上ninja={ name: '小花', age: [Getter/Setter] },也就是說我在使用ninja.age方法時候是在使用get方法,而get方法返回值一直是16,所以我一直獲取不了最新的值。
想要達到get跟set同步的目的可以添加一個屬性值_age,來看這個例子

let ninja = {
    name:'小花',
    _age:16
}

ninja.age = 17;
ninja.age = 19;

Object.defineProperty(ninja,'age',{
    set:function(newAge){
        this._age  = newAge
        console.log(this.name+'現在'+newAge+'歲')
    },
    get:function(){
	    return this._age;
	}
}) 
ninja.age = 13

運行結果如下:
在這裏插入圖片描述
到這兒爲止,我們已經基本瞭解js中對象內get、set的工作原理。

二、使用代理(proxy)控制訪問 ,代理來捕獲get、set

接着使用上面的例子,通過代理來getset進行操作

let ninja = {
    name:'小花',
    _age:16
}
const handers = {
  get() {
   	 //  進行取值時會觸發
	return this._age;    
  },
  set() {
 	 //  進行賦值時會觸發
 	 this._age  = newAge
     console.log(this.name+'現在'+newAge+'歲')
  },
  
}
const observed = new Proxy(target, handers)

如有問題請聯繫我~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章