跳到主要内容

Object.defineProperty 使用指南

参数

在使用 Object.defineProperty 方法时,我需要提供以下参数:

obj 要定义属性的对象。

prop 要修改或定义的属性名称或 Symbol

descriptor 用于定义或修改属性的描述符。

方法的特点

通过 Object.defineProperty 定义的属性具有以下特点:

属性不可修改、不可枚举、不可删除。

function defineProperty() {
var obj = {};
// 定义多个属性
Object.defineProperties(obj, {
a: {
value: 1,
},
b: {
value: 2,
},
});
return obj;
}

var obj = defineProperty();
// 尝试修改属性a的值
obj.a = 5;
// 尝试枚举属性
for (var key in obj) {
console.log(key);
}
// 尝试删除属性a
delete obj.a;
console.log(obj);

让属性可以进行删除、枚举、修改

通过设置属性描述符中的 writableenumerableconfigurable,我可以使属性变得可修改、可枚举和可删除。

function defineProperty() {
var obj = {};
// 定义多个属性
Object.defineProperties(obj, {
a: {
value: 1,
writable: true, // 可写
enumerable: true, // 可枚举
configurable: true, // 可配置
},
b: {
value: 2,
writable: true,
enumerable: true,
configurable: true,
},
});
return obj;
}

var obj = defineProperty();

// 修改属性a的值
obj.a = 5;
// 枚举属性
for (var key in obj) {
console.log(key);
}
// 删除属性a
delete obj.a;
console.log(obj);

get/set

get

使用 get 方法,我可以在访问属性时自定义返回值。使用 get 时,不能同时使用 value

set

使用 set 方法,在修改属性值时调用特定的方法。使用 set 时,不能同时使用 writable

function defineProperty() {
var obj = {};
var internalA = 1;

Object.defineProperties(obj, {
a: {
// 访问器
get() {
return `当前值:${internalA}`;
},
// 设置器
set(newVal) {
internalA = newVal;
var paragraph = document.getElementsByTagName('p')[0];
if (paragraph) {
paragraph.innerHTML = internalA;
}
},
},
b: {
value: 2,
},
});

return obj;
}

var obj = defineProperty();
obj.a = 2;
console.log(obj.a);

定义数组

通过 Object.defineProperty,我可以定义一个数组,并在设置值时自动记录变化。

function DataArray() {
var value = null;
var history = [];

Object.defineProperty(this, 'val', {
get: function () {
return value;
},
set: function (newVal) {
value = newVal;
history.push({ val: value });
console.log('值已更新');
},
});

this.getHistory = function () {
return history;
};
}

var dataArray = new DataArray();

dataArray.val = 123;
dataArray.val = 234;

console.log(dataArray.getHistory());