JS添加getter与setter的六大方法。
一、定义 getter 与 setter
1.通过对象初始化器在创建对象的时候指明(也可以称为通过字面值创建对象时声明)
在 chrome 中调试视图如下:
可以看到对象下多了 get 属性以及 set 属性
当然 get 语句与 set 语句可以声明多次用来对应多个 getter 和 setter
使用这种方法的好处是可以在声明属性的时候同时声明对应的 getter 和 setter
这里就有人问了,能不能将o 对象的 get 及 set 方法的方法名都改成 “a”,这样就可以直接通过“.”来访问方法直接操作
打开 chrome 查看创建后的视图如下:
可以看到这个时候的get与set方法已经和上面不同,但是是否真的能起作用呢,答案是否定的,当我们通过o.a调用的是get语句 声明的 a方法,进入到该方法后遇到this.a方法继续调用该方法形成死循环最终导致死循环报内存溢出错误。
新语法(ES6):暂时只有 firefox 支持,其他浏览器会报错
打开 firefox 查看调试:
输出结果如下:
2.使用 Object.create 方法
引用 MDN:
概述 Object.create() 方法创建一个拥有指定原型和若干个指定属性的对象。 语法 Object.create(proto, [ propertiesObject ])
我们都知道使用 Object.create 方法传递一个参数的时候可以创建一个以该参数为原型的对象。
第二个参数是可选项,是一个匿名的参数对象,该参数对象是一组属性与值,该对象的属性名称将是新创建的对象的属性名称,值是属性描述符(包扩数据描述符或存取描述符,具体解释看后面的内容 什么是属性描述符)。
通过属性描述符我们可以实现为新创建的对象添加 get 方法以及 set 方法
在 chrome 中调试试图如下:
可以看到新创建对象通用多了 get 以及 set 属性。
输出结果如下:
上面这个例子并没有用来针对的 get 方法以及 set 方法使用的属性
亦或者是:
输出结果如下:
使用这种方式的好处是可配置性高,但初学者容易迷糊。
3.使用 Object.defineProperty 方法
引用 MDN:
概要 Object.defineProperty() 方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。 语法 Object.defineProperty(obj, prop, descriptor) 参数 obj 需要定义属性的对象。 prop 需被定义或修改的属性名。 descriptor 需被定义或修改的属性的描述符。
这个方法与前面两种的区别是:使用前面两种只能在声明定义的时候指定getter与setter,使用该方法可以随时的添加或修改。
如果说需要一次性批量添加 getter 与 setter 也是没问题的,使用如下方法:
4.使用 Object.defineProperties 方法
MDN:
概述 Object.defineProperties() 方法在一个对象上添加或修改一个或者多个自有属性,并返回该对象。 语法 Object.defineProperties(obj, props) 参数 obj 将要被添加属性或修改属性的对象 props 该对象的一个或多个键值对定义了将要为对象添加或修改的属性的具体配置
不难看出用法与Object.defineProperty方法类似
输出结果如下:
5.使用 Object.prototype.__defineGetter__ 以及 Object.prototype.__defineSetter__ 方法
输出结果为1和2 查看 MDN 有如下说明:
二、什么是属性描述符?
MDN:
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。
数据描述符是一个拥有可写或不可写值的属性。
存取描述符是由一对 getter-setter 函数功能来描述的属性。
描述符必须是两种形式之一;不能同时是两者。
数据描述符和存取描述符均具有以下可选键值:
value 与属性相关的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。 writable true 当且仅当可能用 赋值运算符 改变与属性相关的值。默认为 false。
存取描述符同时具有以下可选键值:get
一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。方法将返回用作属性的值。默认为 undefined。 set 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将收到作为唯一参数的新值分配给属性。默认为 undefined。
以上是摘自MDN的解释,看起来是很晦涩的,具体什么意思呢: 首先我们从以上解释知道该匿名参数对象有个很好听的名字叫属性描述符,属性描述符又分成两大块:数据描述符以及存取描述符(其实只是一个外号,给指定的属性集合起个外号)。
数据描述符包括两个属性 :value属性以及writable属性,第一个属性用来声明当前欲修饰的属性的值,第二个属性用来声明当前对象是否可写即是否可以修改
存取描述符就包括get与set属性用来声明欲修饰的象属性的getter及setter
属性描述符内部,数据描述符与存取描述符只能存在其中之一,但是不论使用哪个描述符都可以同时设置configurable属性以及enumerable属性。
configurable属性用来声明欲修饰的属性是否能够配置,仅有当其值为true时,被修饰的属性才有可能能够被删除,或者重新配置。
enumerable属性用来声明欲修饰属性是否可以被枚举。
知道了什么是属性描述符,我们就可以开始着手创建一些对象并开始配置其属性
三、创建属性不可配置不可枚举的对象
输出结果如下:
五、Configurable 特性
六、提高及扩展
1.属性描述符中容易被误导的地方之writable与configurable
2.通过上面的学习,我们都知道传递属性描述符参数时,是定义一个匿名的对象,里面包含属性描述符内容,若每定义一次便要创建一个匿名对象传入,将会造成内存浪费。故优化如下:
如果有其他疑问或是看法可以在评论里或投稿跟小编进行讨论,也可以关注微信公众号【筑梦前端】进行投稿,与小编一起探讨更多的编程知识。