JS中控制对象的访问

文章目录


一、使用getter和setter控制访问对象的属性

我们可以使用普通的自定义的getter和setter方法来控制对属性的访问。

// 普通的getter和setter,需要显示地调用相关的方法
function Person() {
  let age = 10;// 当做私有属性来用

  this.getAge = function () {
    console.log("获取属性值:");
    return age;
  }

  this.setAge = function (value) {
    console.log('设置属性值:', value);
    age = value;
  }
}


let p1 = new Person();
console.log(p1.getAge());
p1.setAge(20);
console.log(p1.getAge());

上边代码中,我们所有与age属性交互的地方都必须显示地调用相关的方法。JavaScript支持真正的getter和setter用于访问普通的数据属性。

在JavaScript中,可以通过两种方式定义getter和setter。

  • 通过对象字面量定义,或者在ES6的class中定义
  • 通过使用内置的Object.defineProperty()方法来定义

1、在对象字面量中定义getter和setter

  • 在属性名前添加get关键字定义getter方法,getter方法不接受任何参数
  • 在属性名前添加set关键字定义setter方法,setter方法接受一个参数
  • 获取属性值将隐式调用getter方法,设置属性值将隐式调用setter方法
let obj = {
  names: ['小明', '小红'],
  get firstName() {
    console.log('获取第一个人名'); // 可以进行一些日志记录
    return this.names[0];
  },
  set firstName(value) {
    console.log('设置第一个人名');
    this.names[0] = value;
  }
}

console.log(obj.firstName); // 把firstName当做属性进行操作
obj.firstName = '小黑';
console.log(obj.firstName);

2、在ES6的class中定义getter和setter

在“类”的内部可以使用 getset 关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。

// ES6的class中的getter和setter
class Student {
  constructor() {
    this.names = ['小明', '小红'];
  }

  get firstName() {
    console.log('get firstname');
    return this.names[0];
  }

  set firstName(value) {
    console.log('set firstname');
    this.names[0] = value;
  }
}

let s1 = new Student();
console.log(s1.firstName);

s1.firstName = 'xiaohei';
console.log(s1.firstName);

3、通过Object.defineProperty()定义getter和setter

不了解Object.defineProperty()使用方法的同学可以阅读:属性描述对象 - JavaScript 教程 - 网道

取值函数get不能接受参数,存值函数set只能接受一个参数(即属性的值)。

案例1:

var obj = Object.defineProperty({}, 'p', {
  get: function () {
    return 'getter';
  },
  set: function (value) {
    console.log('setter: ' + value);
  }
});

obj.p // "getter"
obj.p = 123 // "setter: 123"

案例2:

function Animal() {
  let _age = 2; // 可以实现私有属性

  Object.defineProperty(this,'age',{
    get:function () {
      console.log('get age');
      return _age;
    },
    set:function (value) {
      console.log('set age');
      _age = value;
    }
  })
}

let dog = new Animal();
console.log(dog.age);
dog.age = 4;
console.log(dog.age);

4、小结

如果一个属性具有getter和setter方法,访问该属性时将隐式调用getter方法,为该属性赋值时将隐式调用setter方法。

针对指定的属性不一定需要同时定义 getter和 setter。例如,通常我们可以仅提供 getter。如果在这种情况下试图写入属性值,具体的行为取决于代码是在严格模式还是非严格模式。如果在非严格模式下,对仅有getter 的属性赋值不起作用,JavaScript引擎默默地忽略我们的请求。另一方面,如果在严格模式下,JavaScript引擎将会抛出异常,表明我们试图将给一个仅有 getter没有setter的属性赋值。


二、使用代理控制对象的访问

可以看我写的另一篇博客:JS中代理Proxy的简单使用

上一篇:Android studio (AS)实现Getter和Setter的快捷键


下一篇:Vue响应式