Object.defineProperty() 详解

定义

MDN:
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

语法

Object.defineProperty(obj, prop, descriptor)

参数

obj:要定义属性的对象。

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

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

返回值:被传递给函数的对象。

例:

const obj1 = {};

Object.defineProperty(obj1, 'property1', {
  value: 22,
  writable: false
});

obj1.property1 = 33;

console.log(obj1.property1); // 22

注:默认情况下,使用 Object.defineProperty() 添加的属性值不可修改。


第三个参数:属性描述符

第三个参数:属性描述符 有两种主要形式:数据描述符存取描述符

  • 数据描述符 是一个具有值的属性。
  • 存取描述符 是由 getter 函数和 setter 函数所描述的属性。

(一个描述符只能是这两者其中之一,不能同时是两者。)

  • 这两种描述符都是对象。它们都有以下可选键值:

    • configurable :当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。 默认为 false。
    • enumerable :当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中。 默认为 false。
  • 数据描述符 具有以下可选键值:

    • value:该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。 默认为 undefined。

    • writable:当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符改变。 默认为 false。

  • 存取描述符 具有以下可选键值:

    • get 属性的 getter 函数,如果没有 getter,则为 undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。 默认为 undefined。

    • set 属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。 默认为 undefined。

创建属性

let obj2 = {}
// 给对象添加一个设置了数据描述符的属性
Object.defineProperty(obj2, "aa", {
    value: 22,
    writable: true,
    enumerable: true,
    configurable: true
})
console.log(obj2.aa) // 22

// 给对象添加一个设置了存取描述符的属性
let bbValue = 55
Object.defineProperty(obj2, "bb", {
    get() {
        return bbValue
    },
    set(newValue) {
        bbValue = newValue
    },
    enumerable: true,
    configurable: true
})
console.log(obj2.bb) // 55

修改属性

如果属性已经存在,Object.defineProperty() 将尝试根据描述符中的值以及对象当前的配置来修改这个属性。

  • Writable 属性
    是数据描述符的键值,当 writable 属性设置为 false 时,该属性不可写。即不能被重新赋值。默认为 false。

    	let obj3 = {}
    	Object.defineProperty(obj3, 'aa', {
    	  value: 22,
    	  writable: false
    	})
    	obj3.aa = 33
    	console.log(obj3.aa) // 22
    
  • Enumerable 属性
    enumerable 定义了属性是否可以在 for…in 循环和 Object.keys() 中被枚举。默认为 false,不可枚举。

    var obj4 = { c: 3 };
    Object.defineProperty(obj4, "a", {
      value: 1,
      enumerable: true,
    });
    Object.defineProperty(obj4, "b", {
      value: 2,
      enumerable: false,
    });
    for (let i in obj4) {
      console.log(i);
    }
    // c
    // a
    console.log(Object.keys(obj4)); // [ 'c', 'a' ]
    
  • Configurable 属性
    configurable 表示属性是否可以被删除,以及除 value 和 writable 外的其他特性是否可以被修改。默认为 false。

    let obj5 = {};
    Object.defineProperty(obj5, "aa", {
      get() {
        return 1;
      },
    configurable: false,
    });
    Object.defineProperty(obj5, "aa", {
      configurable: true,
    }); // 报错
    Object.defineProperty(obj5, "aa", {
      enumerable: true,
    }); // 报错
    Object.defineProperty(obj5, "aa", {
      set() {},
    }); // 报错
    delete obj5.aa // 报错
    

使用点运算符和 Object.defineProperty() 为对象的属性赋值时,数据描述符中的属性默认值不同。

let obj6 = {};

// 点运算符为对象的属性赋值
obj6.aa = 22;
// 等同于
Object.defineProperty(obj6, "aa", {
  value: 22,
  writable: true,
  configurable: true,
  enumerable: true,
});

// Object.defineProperty() 为对象的属性赋值
Object.defineProperty(obj6, "bb", { value : 66 });
// 等同于:
Object.defineProperty(obj6, "bb", {
  value: 66,
  writable: false,
  configurable: false,
  enumerable: false
});
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
课程介绍本套课程,大喵将带着大家手把手,编辑每一行代码,使用原生Javascipt及ES6的一些新特性,仿照目前国内非常流行的Vue框架的源码,开发构建一个属于你们自己的MVVM框架。让大家能够很清晰的学习及掌握,模板编译,数据绑定,响应式,文档碎片,观察者模式,发布订阅模式等等,这些Vue的核心知识点,都是怎么回事,它们之间有哪些关联,是如何进行双向数据绑定的等等。在使用vue2.x的核心Object.defineProperty构建完成框架后,大喵也会使用Vue3.0引入的数据劫持的Proxy新特性,来改造我们的MVVM框架,提升我们的框架性能。最终,大喵会手把手带着大家,从0开始配置webpack.config.js配置文件以及引入babel-loader,配置.babelrc文件,转换我们JS文件中的的ES6语法,最终压缩输出我们的MVVM框架库文件。课程目录01 手把手搭建MVVM框架 课程介绍、02 文件结构及基础类创建、03 入口类DamiaoMvvm的实现、04 模板编译、05 元素节点解析编译、06 v-model 数据绑定逻辑梳理、07 v-model 数据绑定实现、08 模板文本编译逻辑梳理、09 模板文本渲染绑定、10 观察者Wather逻辑梳理、11 Wather 逻辑实现、12 Object.defineProperty()、13 defineProperty 小案例、14 observer数据劫持梳理、15 defineProperty数据劫持实现、16 发布订阅类实现、17 Proxy 介绍与概述、18 使用Proxy改造MVVM框架、19 使用Proxy实现响应式、20 webpack 打包配置、21 babel 配置及文件输出、22 Mvvm Proxy 框架打包、23 Mvvm 框架搭建课程总结MVVM框架介绍MVVM是 Model-View-ViewModel 的缩写。mvvm是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。在MVVM架构模式下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欢莱

为您解决问题,此项目我成功完成

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值