JavaScript进阶(十二):defineProperty 的基本使用

这篇博客我们来讲下可响应对象的第二种方法,defineProperty。

尽管来说这个东西有众多的缺陷,但毕竟是非常有一席之地的一个东西,所以我们现在还是要比较深入的了解它一下。

 

首先这个 defineProperty 它的作用是什么?

就如它的名字所说的一样,它可以帮助我们来定义一个属性,只不过它定义出来的属性,不是普通的属性,是一个可以被监控,可以被监听的一个状态。

 

我们先来了解一下它的基本的语法,从最简单的开始说起。

首先,我们定义一个 json:

那么这个 json 是干什么的呢?其实它才是我们真正的那个数据。

 

然后在接下来,我们需要调用 Object.definProperty,在它里面,需要三个参数:

第一个参数,你需要告诉它,你要给哪个对象增加一个属性。

第二个参数,那个属性的名字。

比如我们给它加一个 a:

第三个参数则是一个对象,它里面可以放一些选项,你所有的操作,都是在这里面来规定的。

比如,你想怎么控制,能不能改,能不能删?还是怎么样,都是在这里面来做的。

而它里面,有 2 个最有用的东西,一个叫 get,一个叫 set:

这里顺便一说,defineProperty 的这个 get 和 set,它只是名字叫 get 和 set,跟我们上篇博客讲的访问器是两码事。

访问器的 get 和 set 后面是有名字的

get xxx() { ... }

set xxx() { ... }

而 defineProperty 是这样写的:

get() { ... }

set() { ... }

defineProperty 的这个不是访问器,它就只是一个叫 get 或者 set 的方法。

这里大家要分清楚,不要搞混了。

 

然后 defineProperty 里面的 get 和 set,这两个东西的作用,和访问器几乎是一模一样的。什么作用呢?

就是我可以在读取或者设置的时候,拦截这些操作。

 

那么现在我们就来做的看下,我们先看看 json 里面有没有 a:

可以看到,是有的。

注意,这个 a 哪来的,我们并没有给 json 加啊?

其实是 defineProperty 它加上的,因为它就是用来添加属性的,并且它调用的就是那个 get。

set 也是一样的,从这个角度上来说,defineProperty 可以跟访问器的 get、set 一样来玩。

 

然后,我们现在希望有一个真实的数据,它是能变的,如果我们在 json 里面又加了一个 a 会怎么样呢?

我们来试试:

并且我们在 get 里面 return 的是 json.a,同时 set 里面也是 json.a = val:

这个时候,当我们去访问 a 或者去赋值 a 的时候:

可以看到,和之前的访问器一样,也出现无限死循环了。

所以名字得岔开,这个并不是某个特例。

所以我们需要加个下划线 _a:

这个时候,我们访问或者赋值的时候,就执行了 get 或者 set 了。

 

当然,还有个小事,这里顺便说一下。

我们的这个 json,表面上看起来,它是只有一个 _a 的:

但是如果你把它展开,你会发现,它里面还有个 get a 和 set a。

所以我们的这个 defineProperty,其实它的一个结果,是可以直接在 F12 里面能够看到的。

不知道大家有没有注意过,我们在使用某个框架的时候,当你把它那个对象展开,就会发现它里面有很多虚的,浅紫色的东西。

这些东西其实就证明,这是一个虚的,一个抽象的东西,它并不是真正存在的。

比如我直接去找 json 里面有没有一个 a,你根本就找不了:

其实你是被迫的需要执行 get a 这个函数,它只是一个虚的东西,并不是一个真实的方法,这就是它的由来。

 

所以到这为止,我们就大概的理解了 defineProperty 的作用。

其实也没什么,它就是给某个对象,比方说 json,我们给它添加了一个 'a',表面上看来是一个属性,但其实它背后对应的是一些函数,然后在里面我们可以进行各种各样的操作。

 

然后接下来,我们还有一个小事,就是我们平常对数据进行操作,不一定只是获取和设置,有没有可能我想把这个数据删了?

比如,现在我就要把这个 json.a 删除掉:

这时候它给我返回一个 false。

相信大家都能猜到这个 false 的意思,代表着没删掉。

比如,我们再次访问 json.a:

可以看到,这个 json 它依然是有 a 的。

注意,用 defineProperty 去设置的属性,不是直接用 delete 就能删掉的,我们还需要一个东西才行。

实际上来说,这时候我们就需要用到它里面的其他参数了,它里面还有其他的一些参数可以供我们来选择,并不是只有 get 和 set。

 

所以这时候,我们就需要一个东西,叫做 configurable,就是可配置的意思。

当我们没写的时候,configurable 默认会是一个 false:

可以看到,当我们写上 configurable: false 的时候,它还是删不了,和没加一样。

因为 configurable 默认就是 false,不可配置嘛。

那如果我们给它一个 true,意思就是说,我这个属性 a 是可配置的,可配置就意味着可以删:

可以看到,现在 delete 就是 true 了。

并且现在我在找 json.a,它就是 undefined 了。

因为刚才那个 get 和 set 就都消失了,它就是干这个用的。

 

那么我们稍微来总结一下:

你可以看到 defineProperty 就比我们上篇博客说的访问器,更为的复杂,当然功能也更加的强大。

当你去定义某一个属性的时候,你可以指定很多的东西,当然我们现在说的是最实用的三个东西:get,set,configurable。(其实它还有别的东西,不过意义和用处不大,我们一般就用这三个)

然后定义属性的时候,可以顺便的去指定一些属性的行为,比如是否可配置。(可配置包括 2 个,改和删,一般情况下,我们用的都是删除)

 

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