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)

如有问题请联系我~

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