理解Object.defineProperty()

Object.defineProperty() 方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。

基本语法:Object.defineProperty(obj, prop, descriptor)
@param obj 【必须】目标对象
@param prop【必须】新增或修改的属性名字
@param descriptor 属性描述符。
属性描述符 包括两种形式:数据描述符和存取描述符。数据描述符是一个拥有可写或不可写值的属性。存取描述符是由一对getter-setter函数功能来描述的属性。
但是该两者不能同时存在,描述符只能是其中之一。

一:数据描述符:
比如如下一个普通对象:

var obj = {
  "name": "kongzhi"
};

数据描述符属性如下:

Object.defineProperty(obj, "name", {
  configurable: true | false,
  enumerable: true | false,
  value: ‘任意类型的值‘,
  writable: true | false
});

下面我们来理解下每个属性的含义:

1. value:
含义: 属性的值,可以是任何类型的值,默认为undefined

1-1 不设置value属性
如下代码:

var obj = {};
Object.defineProperty(obj, "name", {});
console.log(obj.name); // undefined

1-2 设置value属性

// 设置value 代码如下:
var obj = {};
Object.defineProperty(obj, "name", {
  value: "kongzhi"
});
console.log(obj.name); // kongzhi

2. writable

含义:属性的值是否可以被重写,true: 可以被重写,false: 不能被重写。默认为false。

2-1 writable设置为false,不能重写,如下代码:

var obj = {};
Object.defineProperty(obj, "name", {
  value: "kongzhi",
  writable: false
});
// 先打印下值
console.log(obj.name); // kongzhi
// 更改值
obj.name = "longen";
// 再打印下
console.log(obj.name); // kongzhi

2-2 writable设置为true,可以被重写,如下代码:

var obj = {};
Object.defineProperty(obj, "name", {
  value: "kongzhi",
  writable: true
});
// 先打印下值
console.log(obj.name); // kongzhi
// 更改值
obj.name = "longen";
// 再打印下
console.log(obj.name); // longen

3. enumerable

含义:该属性是否可以被枚举(如:for..in 或 Object.keys()). 如果为true的话,可以被枚举,设置为false的话,不能被枚举,默认为false。

3-1 enumerable被设置为false,不能被枚举,如下代码:

var obj = {};
Object.defineProperty(obj, "name", {
  value: "kongzhi",
  writable: false,
  enumerable: false
});
// 先打印对象一下看看
console.log(obj); // {name: "kongzhi"}

// 再枚举对象的属性
for(var attr in obj) {
  console.log(attr); // 什么都没有输出 说明不能被枚举
}

3-2 enumerable 设置为true,可以被枚举,如下代码:

var obj = {};
Object.defineProperty(obj, "name", {
  value: "kongzhi",
  writable: false,
  enumerable: true
});
// 先打印对象一下看看
console.log(obj); // {name: "kongzhi"}

// 再枚举对象的属性
for(var attr in obj) {
  console.log(attr); // 输出 name
}

4. configurable

含义:是否可以删除目标属性或是否可以修改目标属性的特性。如果为true的话,可以被删除或可以修改属性,为false的话,不能删除目标属性或不能修改目标属性,默认为false

4-1 configurable: false, 为false的话,不能删除目标属性或不能修改目标属性。如下代码:

var obj = {};
Object.defineProperty(obj, "name", {
  value: "kongzhi",
  writable: false,
  enumerable: false,
  configurable: false
});
// 先打印对象一下看看
console.log(obj); // {name: "kongzhi"}

// 删除属性
delete obj.name;
// 重新打印下对象,看是否删除成功了
console.log(obj.name); // kongzhi

// 修改属性
obj.name = "longen";
// 重新打印下对象,看是否修改成功了
console.log(obj.name); // kongzhi 

4-2 configurable: true, 可以删除目标属性 或 可以修改目标属性,如下代码:

var obj = {};
Object.defineProperty(obj, "name", {
  value: "kongzhi",
  writable: false,
  enumerable: false,
  configurable: true
});
// 先打印对象一下看看
console.log(obj); // {name: "kongzhi"}

// 删除属性
delete obj.name;
// 重新打印下对象,看是否删除成功了
console.log(obj.name); // undefined

// 修改属性
obj.name = "longen";
// 重新打印下对象,看是否修改成功了
console.log(obj.name); // longen 

二: 存取器描述
使用存取器描述属性的时候,可以使用如下属性:

var obj = {};
Object.defineProperty(obj, "name", {
  enumerable: true | false,
  configurable: true | false,
  get: function() {} | undefined,
  set: function(value) {} | undefined
});

注意:当使用了getter或setter的时候,就不能使用writable和value这两个属性。否则会报错。

getter 是获取属性值的方法。如果没有getter 则默认为 undefined,当我们读取某个属性的时候,其实是在对象内部调用了该方法,该方法必须使用return语句,返回值被作为属性值。
setter 是设置属性的方法。如果没有setter,则默认为undefined,该方法接收一个参数,并将该参数值分配该属性。当我们设置某个属性的时候,实际上在对象的内部调用了该方法。

如下代码是使用getter和setter的代码:

var obj = {};
var initValue = "kongzhi";
Object.defineProperty(obj, "name", {
  get: function() {
    // 当获取属性值的时候触发的函数
    return initValue;
  } ,
  set: function(value) {
    // 当设置值的时候触发的函数
    initValue = value;
  }
});
// 获取值
console.log(obj.name); // kongzhi

// 设置值
obj.name = "longen";
// 打印下
console.log(obj.name); // longen
时间: 2024-07-28 19:00:58

理解Object.defineProperty()的相关文章

深入理解 Object.defineProperty

Object.defineProperty() 和 Proxy 对象,都可以用来对数据的劫持操作.何为数据劫持呢?就是在我们访问或者修改某个对象的某个属性的时候,通过一段代码进行拦截行为,然后进行额外的操作,然后返回结果.那么vue中双向数据绑定就是一个典型的应用. Vue2.x 是使用 Object.defindProperty(),来进行对对象的监听的.Vue3.x 版本之后就改用Proxy进行实现的.下面我们先来理解下Object.defineProperty作用. 一: 理解Object

理解Object.defineProperty函数中的get与set

defineProperty是什么: 该函数可以直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象.通俗理解就是: 给对象添加一个新的属性,或者针对对象里的某些属性,可以给这个属性设置一些特性,比如是否只读,是否可以被for..in或Object.keys()遍历等 语法: Object.defineProperty(obj, prop, descriptor) 例如: var obj = {}; Object.defineProperty(obj, "key"

《转》理解Object.defineProperty的作用

对象是由多个名/值对组成的无序的集合.对象中每个属性对应任意类型的值.定义对象可以使用构造函数或字面量的形式: var obj = new Object; //obj = {} obj.name = "张三"; //添加描述 obj.say = function(){}; //添加行为 除了以上添加属性的方式,还可以使用Object.defineProperty定义新属性或修改原有的属性. Object.defineProperty() 语法: Object.definePropert

理解Object.defineProperty的作用

对象是由多个名/值对组成的无序的集合.对象中每个属性对应任意类型的值.定义对象可以使用构造函数或字面量的形式: var obj = new Object; //obj = {} obj.name = "张三"; //添加描述 obj.say = function(){}; //添加行为 除了以上添加属性的方式,还可以使用Object.defineProperty定义新属性或修改原有的属性. Object.defineProperty() 语法: Object.definePropert

[转] 理解Object.defineProperty的作用

对象是由多个名/值对组成的无序的集合.对象中每个属性对应任意类型的值.定义对象可以使用构造函数或字面量的形式: var obj = new Object; //obj = {} obj.name = "张三"; //添加描述 obj.say = function(){}; //添加行为 除了以上添加属性的方式,还可以使用Object.defineProperty定义新属性或修改原有的属性. Object.defineProperty() 语法: Object.definePropert

Object.defineProperty 中的 writable 和 configurable 和 enumerable 的理解

在现在比较新的框架中, 比如 reactjs, vuejs中用得很多的一个属性便是 Object.defineOProperty 此属性的文档在网上一搜, 其中的几个属性, 包括 存取描述符(有set和get的) 和 数据描述符(直接有 value 的就是数据描述符) 有 set get 有 value writable enumerable configurable 虽然有 set 和 get, 但是定义的时候还是要用到 enumerable 和 configurable set 和 get

Object.defineProperty(o,p,descriptor ) 理解应用

1. Object.defineProperty  在一个对象上定义一个新属性,或修改一个已经存在的属性, 最终返回这个对象. var __define = this.__define || function (o, p, g, s) { Object.defineProperty(o, p, { configurable: true, enumerable: true, get: g, set: s }); }; o: 需要定义属性的 对象. p:要定义或修改的 名称 或 属性. descri

解析神奇的 Object.defineProperty

这个方法了不起啊..vue.js是通过它实现双向绑定的..而且Object.observe也被草案发起人撤回了..所以defineProperty更有必要了解一下了. 几行代码看他怎么用 var a= {} Object.defineProperty(a,"b",{ value:123 }) console.log(a.b);//123 很简单,它接受三个参数,而且都是必填的.. 传入参数 第一个参数:目标对象 第二个参数:需要定义的属性或方法的名字. 第三个参数:目标属性所拥有的特性

解析 神奇的 Object.defineProperty

这个方法了不起啊..vue.js和avalon.js 都是通过它实现双向绑定的..而且Object.observe也被草案发起人撤回了..所以defineProperty更有必要了解一下了几行代码看他怎么用 var a= {} Object.defineProperty(a,"b",{ value:123 }) console.log(a.b);//123 很简单,,它接受三个参数,而且都是必填的.. 传入参数 第一个参数:目标对象 第二个参数:需要定义的属性或方法的名字. 第三个参数