JavaScript Object 对象 再解(三)

JavaScript的两类属性

该部分仍然来自 winter 老师 重学前端课程 06 章

对 JavaScript 来说,属性并非是简单的名称与值,JavaScript 用一组特征(attribute) 来描述属性(property)

首先来说第一类属性,数据属性。它比较接近于其它语言的属性概念。数据属性有四个特征。

  • value:就是属性的值
  • writable: 决定属性能否被赋值
  • enumerable: 决定for in 能不能够枚举该属性。
  • configurable:决定该属性能否被删除或者改变特征值。

在大多数情况下,我们只关心属性的值即可。

第二类属性是访问器(getter/setter)属性,它也有四个特征。

  • getter: 函数或 undefined,在取属性值的时候被调用。

  • setter:函数或 undefined,在设置属性的时候被调用。

    vue 的双向绑定好像就是这么弄的,vue 自己之前写过,但是不太熟,源码也还没有看。以后补上(不久的以后)

  • enumerable: 决定 for in 能否枚举该属性。

  • configurable: 决定该属性能否被删除或者改变特征值。

访问器属性使得属性在读和写时执行代码,它允许使用者在写和读属性时,得到完全不同 的值,它可以视为一种函数的语法糖。

我们通常定义属性的代码都会产生数据属性,其中的 writable、enumerable、configurable 都默认为 true。我们可以使用内置函数 Object.getOwnPropertyDescripter来查看,如以下的代码所示:

// a,b 都是数据属性
var o = {a : 1}
o.b = 2;
// {value: 1, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(o, 'a')
// {value: 2, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(o, 'b')

我们在这里使用了两种语法来定义属性,定义完属性后,我们用 JavaScript 的 API 来查看 这个属性,我们可以发现,这样定义出来的属性都是数据属性,writeable、 enumerable、configurable 都是默认值为 true。

如果我们要想改变属性的特征,或者定义访问器属性,我们可以使用 Object.defineProperty,示例如下:

var o = {a: 1};
Object.defineProperty(o, "b", {value: 2, writable: false, enumerable: false, configurable: false })
// {value: 1, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(o, 'a')
// {value: 2, writable: false, enumerable: false, configurable: false}
Object.getOwnPropertyDescriptor(o, 'b')

这里我们使用了 Object.defineProperty 来定义属性,这样定义属性可以改变属性的 writable 和 enumerable。

我们同样用 Object.getOwnPropertyDescriptor 来查看,发现确实改变了 writable 和 enumerable 特征。因为 writable 特征为 false,所以我们重新对 b 赋值,b 的值不会发 生变化。

在创建对象时,也可以使用 get 和 set 关键字来创建访问器属性,代码如下所示:

var o = {
  get a() {
    return 1
  }
}
console.log(o.a);

访问器属性跟数据属性不同,每次访问属性都会执行 getter 或者 setter 函数。这里我们 的 getter 函数返回了 1,所以 o.a 每次都得到 1。

这样,我们就理解了,实际上 JavaScript 对象的运行时是一个“属性的集合”,属性以字 符串或者 Symbol 为 key,以数据属性特征值或者访问器属性特征值为 value。

对象是一个属性的索引结构(索引结构是一类常见的数据结构,我们可以把它理解为一个 能够以比较快的速度用 key 来查找 value 的字典)。我们以上面的对象 o 为例,你可以想 象一下“a”是 key。

{writable:true,value:1,configurable:true,enumerable:true}是 value。我 们在前面的类型课程中,已经介绍了 Symbol 类型,能够以 Symbol 为属性名,这是 JavaScript 对象的一个特色。{writable:true,value:1,configurable:true,enumerable:true}是 value。我 们在前面的类型课程中,已经介绍了 Symbol 类型,能够以 Symbol 为属性名,这是 JavaScript 对象的一个特色。

JavaScript 提供了完全运行时的对象系统,放心大胆的用基于原型的面向对象。

posted @ 2020-06-16 15:51  jaiodfjiaodf  阅读(147)  评论(0编辑  收藏  举报