在vue2中,这个 js 原生API就是整个vue2的核心了。

我们先来看一下官方文档对该属性的描述:

Object.defineProperty() 允许精确地添加或修改对象上的属性。

Object.defineProperty的语法如下:

1
Object.defineProperty(obj, prop, descriptor)

下面是它的参数介绍:

  • obj
    要定义属性的对象。

  • prop
    一个字符串或 Symbol,指定了要定义或修改的属性键。

  • descriptor
    要定义或修改的属性的描述符。

不知道你是不是有这样的疑问,descriptor 到底是个啥?这里呢,我们来了解一下:

对象的属性描述符是一个用于描述对象属性特性的配置对象,它包含以下可选属性:

  1. value: 属性的值,默认为 undefined。用于设置属性的初始值。

  2. writable: 布尔值,默认为 false。如果为 true,则属性的值可以被修改,否则为只读属性。

  3. enumerable: 布尔值,默认为 false。如果为 true,则属性可以通过 for...in 循环和 Object.keys() 方法枚举,否则不可枚举。

  4. configurable: 布尔值,默认为 false。如果为 true,则属性的描述符可以被修改,也可以通过 delete 删除属性,否则不可修改和删除。

  5. get: 一个函数,默认为 undefined。用于获取属性值时调用的 getter 函数。

  6. set: 一个函数,默认为 undefined。用于设置属性值时调用的 setter 函数。

我们来做一个示例,一个一个的来了解:

value

1
2
3
4
5
const myObj = {};

Object.defineProperty(myObj, 'name', {
value: 'chuyuxuan',
});

在上面的例子中,myObj 对象的 name 属性被定义为一个属性描述符对象,vaule为该属性的默认值:

  • value'chuyuxuan',表示初始值为 'chuyuxuan'
image-20230805150440778

writable

1
2
3
4
5
6
7
8
const myObj = {};

Object.defineProperty(myObj, 'name', {
value: 'chuyuxuan',
writable: false
});

myObj.name = 'chuyuxuan new'

默认为 false。如果为 true,则属性的值可以被修改,否则为只读属性。

image-20230805150930446 image-20230805151223460

enumerable

默认为 false。如果为 true,则属性可以通过 for...in 循环和 Object.keys() 方法枚举,否则不可枚举。

1
2
3
4
5
6
7
8
9
10
const myObj = {};

Object.defineProperty(myObj, 'name', {
value: 'chuyuxuan',
writable: false,
enumerable: true,
});

Object.keys(myObj)

image-20230805151558735 image-20230805151902589

configurable

configurable: 布尔值,默认为 false。如果为 true,则属性的描述符可以被修改(及可以再次通过 definePorperty改动),也可以通过 delete 删除属性,否则不可修改和删除。让我们来看一下示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const myObj = {};

Object.defineProperty(myObj, 'name', {
value: 'chuyuxuan',
writable: false,
enumerable: true,
configurable: true,
});
console.log(myObj)
Object.defineProperty(myObj, 'name', {
value: 'chuyuxuan_new',
writable: false,
enumerable: true,
});
console.log(myObj)

image-20230805153020740 image-20230805153521558

get 与 set

  1. get: 一个函数,默认为 undefined。用于获取属性值时调用的 getter 函数。
  2. set: 一个函数,默认为 undefined。用于设置属性值时调用的 setter 函数。

⚠️注意: MDN 中有这样一句话:如果描述符没有 valuewritablegetset 键中的任何一个,它将被视为数据描述符。如果描述符同时具有 [valuewritable] 和 [getset] 键,则会抛出异常。 也就是说,writable,valueget,set 是互斥的, 如果同时存在,会抛出异常。

1
2
3
4
5
6
7
8
9
10
11
12
const obj = {
_name: 'chuyuxuan', // 使用下划线约定,表示这是一个私有属性
get name() { // 定义获取属性值的行为
console.log('触发getName函数')
return this._name;
},
set name(value) { // 定义设置属性值的行为
console.log('触发setName函数')
this._name = value;
},
};

image-20230805180635600

如上图,当我们调用的时候,触发了对应的函数。