在 JavaScript 的开发中,经常使用一些数据操作,例如获取、修改、删除等等。而 setter
、getter
、defineProperty
和 Proxy
是 JavaScript 中常用的数据操作方式,它们有着不同的用途和功能。在 ES10 中,这些特性又有了一些新的扩展和变化,本文将探讨它们的异同和使用方式。
setter 和 getter
setter
和 getter
是 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
从上面的例子可以看出,我们在对象中使用了 set
和 get
关键字来定义了 setName
和 getName
方法。当我们对 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
属性,并定义了 get
和 set
方法来获取和设置 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
,并在其中重写了 set
和 get
方法,用于改变默认的属性设置和获取行为。当我们对 proxyObj
的 name
属性进行赋值时,实际上是将值转换成了大写字母。而在获取 proxyObj
的 age
属性值时,实际上是获取了 obj
对象的 age
属性值。
异同点
setter、getter、defineProperty 和 Proxy 这几种方式在功能上都有着类似的特点,但是它们之间也存在着一些异同点。
不同作用
setter
和 getter
主要作用是定义对象属性的获取和设置方法,而 defineProperty
主要作用是修改对象的某个属性的特性,例如修改属性的可枚举性、可配置性、可写性等。
而 Proxy
主要作用是拦截对象的默认操作行为,并对其进行一些额外的处理。
兼容性
setter
、getter
和 defineProperty
都存在兼容性问题。在 IE9 及以下版本中,它们的支持可能存在问题。而 Proxy 则更加不兼容,它只支持最新版本的浏览器。
功能扩展
在 ES10 中,setter
和 getter
的功能得到了进一步扩展。现在,我们可以直接在 class 中使用 setter
、getter
、defineProperty
的方式来定义属性的 get
、set
、configurable
、enumerable
、writable
等特性,这样可以更容易地控制类的属性行为。
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