Object.defineProperty()的基本知识

73 阅读2分钟

Object.defineProperty()

会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

备注: 应当直接在Object构造器对象上调用此方法,而不是在任意一个 Object 类型的实例上调用。

语法

Object.defineProperty(obj, prop, descriptor)

参数

obj要定义属性的对象
prop要定义或修改的属性的名称或Symbol
descriptor要定义或修改的属性描述符

返回值

被传递给函数的对象

属性描述符

有两种主要形式:数据描述符和存取描述符。

属性描述符描述
数据描述符具有值的属性,该值可以是可写的,也可以是不可写的
存取描述符由 getter 函数和 setter 函数所描述的属性

可选键值

键值默认值描述数据描述符存取描述符
configurablefalse为ture时,该属性也能从对应的对象上被删除。
enumerablefalse为ture时,才会出现在对象的枚举属性中。
valueundefined该属性对应的值。×
writablefalse为ture时,才能被赋值运算符改变×
getundefined当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。×
setundefined当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。×

演示

//平常写法
let A={};
A.a=1;

console.log(A)//{a:1}

//等同于:
Object.defineProperty(A, "a", {
  value: 1,
  writable: true,      //可被修改
  configurable: true,  //可被删除
  enumerable: true     //可被枚举
});

console.log(A)//{a:1}
//修改
A.a=2
console.log(A)//{a:2}
//实例上的所有可枚举属性
Object.keys(A)//['a']
//删除
delete A.a
console.log(A)//{}


function myclass() {
}

myclass.prototype.x = 1;
Object.defineProperty(myclass.prototype, "y", {
  writable: false,
  value: 1
});

//如果一个不可写的属性被继承,它仍然可以防止修改对象的属性。
function myclass() {}

myclass.prototype.x = 1;
Object.defineProperty(myclass.prototype, "y", {
  writable: false,
  value: 1
});

var a = new myclass();
a.x = 2;//改的只是对象自身上的,而不是原型
console.log(a.x); // 2 
console.log(myclass.prototype.x); // 1 
a.y = 2; // 
console.log(a.y); // 1 因为不可修改所以不变
console.log(myclass.prototype.y); // 1