ES10 新特性 setter、getter、defineProperty 与 Proxy 的异同

在 JavaScript 的开发中,经常使用一些数据操作,例如获取、修改、删除等等。而 settergetterdefinePropertyProxy 是 JavaScript 中常用的数据操作方式,它们有着不同的用途和功能。在 ES10 中,这些特性又有了一些新的扩展和变化,本文将探讨它们的异同和使用方式。

setter 和 getter

settergetter 是 JavaScript 中用于定义一个对象属性的两种方法。它们分别用于设置和获取对象属性的值。当我们给一个对象属性赋值时,setter 方法会被调用,而在获取属性值时,getter 方法会被调用。这里是一个简单的例子:

let obj = {
  name: '',
  set setName(name) {
    this.name = name;
  },
  get getName() {
    return this.name;
  }
}

obj.setName = 'Tom';
console.log(obj.getName); // Tom

从上面的例子可以看出,我们在对象中使用了 setget 关键字来定义了 setNamegetName 方法。当我们对 setName 方法进行赋值时,实际上是对 obj 对象的 name 属性进行赋值。而在调用 getName 方法时,实际上是获取了 obj 对象的 name 属性值。

defineProperty

defineProperty 方法是用来定义一个对象的属性。它的语法如下:

Object.defineProperty(obj, prop, descriptor)

其中 obj 表示要定义属性的对象,prop 表示要定义的属性名称,descriptor 是一个包含属性描述信息的对象。

一个简单的例子:

let obj = {};
Object.defineProperty(obj, 'name', {
  set: function (val) {
    this._name = val.toUpperCase();
  },
  get: function () {
    return this._name;
  }
});

obj.name = 'Tom';
console.log(obj.name); // TOM

上面的代码中,我们通过 Object.defineProperty 定义了 name 属性,并定义了 getset 方法来获取和设置 name 属性值。需要注意的是,我们使用了一个下划线 _ 来定义一个内部属性 _name,并在 set 方法中给 _name 赋值。

Proxy

Proxy 是 ES6 新增的一个功能,它可以作为代理对象存在,用于修改某些操作的默认行为。

一个简单的例子:

let obj = {
  name: '',
  age: '',
};

let proxyObj = new Proxy(obj, {
  set: function (target, key, value) {
    target[key] = value.toUpperCase();
    return true;
  },
  get: function (target, key) {
    return target[key];
  }
});

proxyObj.name = 'Tom';
proxyObj.age = '18';

console.log(proxyObj.name); // TOM
console.log(proxyObj.age); // 18

上面的代码中,我们使用了 new Proxy() 方法来创建了一个代理对象 proxyObj,并在其中重写了 setget 方法,用于改变默认的属性设置和获取行为。当我们对 proxyObjname 属性进行赋值时,实际上是将值转换成了大写字母。而在获取 proxyObjage 属性值时,实际上是获取了 obj 对象的 age 属性值。

异同点

setter、getter、defineProperty 和 Proxy 这几种方式在功能上都有着类似的特点,但是它们之间也存在着一些异同点。

不同作用

settergetter 主要作用是定义对象属性的获取和设置方法,而 defineProperty 主要作用是修改对象的某个属性的特性,例如修改属性的可枚举性、可配置性、可写性等。

Proxy 主要作用是拦截对象的默认操作行为,并对其进行一些额外的处理。

兼容性

settergetterdefineProperty 都存在兼容性问题。在 IE9 及以下版本中,它们的支持可能存在问题。而 Proxy 则更加不兼容,它只支持最新版本的浏览器。

功能扩展

在 ES10 中,settergetter 的功能得到了进一步扩展。现在,我们可以直接在 class 中使用 settergetterdefineProperty 的方式来定义属性的 getsetconfigurableenumerablewritable 等特性,这样可以更容易地控制类的属性行为。

class Person {
  constructor() {
    this._name = '';
  }

  get name () {
    return this._name;
  }

  set name (value) {
    this._name = value.toUpperCase();
  }
}

let person = new Person();
person.name = 'Tom';
console.log(person.name); // TOM

总结

setter、getter、defineProperty 和 Proxy 都是 JavaScript 中常用的数据操作方式,它们之间的功能和作用都存在着一些异同。对于具体应用场景的选择,通常需要根据项目需求、浏览器兼容性等因素来综合考虑。同时,ES10 中对这些特性的进一步扩展和变化,使得我们可以更好地掌控对象和类的属性行为,提高了代码的可维护性和可读性。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a0aa22add4f0e0ff8e9653


纠错反馈