浅谈Object.defineProperty()

简介: 前言学习前端的小伙伴一定对前端三大框架不陌生,其中在国内Vue使用的企业可以说是最多的。如果去面试前端相关岗位,一定为问你框架相关的知识。其中Vue的响应式原理一定会问的,那么在Vue2.x中,实现响应式的原理可以说Object.defineProperty()这个ES5的API是核心。

1.Object.defineProperty()简介


在JS代码中,我们经常使用到Object对象,通常我们给对象设置属性时,一般通过对象的.操作符或者[]操作符直接赋值的,或者直接使用对象字面量的方式赋值。


比如Obj.a=1,Obj['b']=4等等。


这样赋值后,属性值是可以在后续更改的,而且该对象可以枚举,即通过循环等方式获取到该对象的属性值。


但是在有些时候我们只想定义了对象之后,在后续无法更改其属性值或者无法枚举,这个时候Object.defineProperty()就派上了用场。


静态方法Object.defineProperty(obj, prop, descriptor),其可以通过定义属性的元数据信息精确地控制属性的行为。


方法详细操作:

**方法名:**Object.defineProperty(obj, prop, descriptor)


参数:


  • obj
    Object,Required,要在其上定义属性的对象。
  • prop
    String|Symbol,Required,要定义或修改的属性的名称。
  • descriptor
    Object,Required,将被定义或修改的属性描述符。


**返回值:**Object,返回被传递给函数的对象obj。


2.属性描述符


Object.defineProperty(obj, prop, descriptor)接收3个参数,其中descriptor就是属性描述符,它就是可以定义属性行为的元数据信息。属性描述符又有两种表现形式:数据描述符和存取描述符,这两种描述符不能够同时存在。


1)数据描述符和存取描述符均有以下键值:


configurable


当且仅当该属性的 configurable 为 true 时,才能够再次修改该属性的属性描述符,同时该属性也能从对应的对象上被删除。默认为 false。


enumerable


当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 false。


(2)数据描述符可选键值:


value

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


writable:

当且仅当该属性的writable为true时,该属性才能被写入值。默认为 false。


(3)存取描述符可选键值:


get:

一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。默认为 undefined。


set:

一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。默认为 undefined。


3.代码示例


(1)创建属性

<script>
    const Obj = {};
    // 向对象Obj中添加一个属性a,并设置数据描述符
    Object.defineProperty(Obj, "a", {
        value: 100, // 默认值1
        writable: true, // 可写
        enumerable: true, // 可枚举
        configurable: true // 可以再次修改属性描述符
    });
    // 对象Obj有了属性a,其值为1
    console.log(Obj.a) // 输出: 1
</script>


(2)get、set存取描述符

const Obj = {};
let v = null;
Object.defineProperty(Obj, 'a', {
    get: function () {
        return v;
    },
    set: function (newValue) {
        v = newValue;
    }
});
Obj.a = 1000;
console.log(Obj.a); // 输出: 1,表示属性a的getter和setter均生效


总结


一句话来说,Object.defineProperty()就是用来操作对象属性的,赋予属性生命,Vue2.x就是一个使用Object.defineProperty()的典范。


相关文章
|
11月前
|
Java API 数据处理
《如何在Java中实现函数式编程》
在Java中实现函数式编程主要依赖于Lambda表达式和函数式接口。通过定义单方法接口并使用`@FunctionalInterface`注解,可以轻松创建Lambda表达式的实例,执行基本运算。结合Java 8的Stream API,还能进行复杂的数据处理,如过滤、映射和归约操作,极大提升了代码的简洁性和可读性。
210 16
|
机器学习/深度学习 Python
L1和L2正则化
L1和L2正则化
|
9月前
|
存储 机器学习/深度学习 PyTorch
PyTorch Profiler 性能优化示例:定位 TorchMetrics 收集瓶颈,提高 GPU 利用率
本文探讨了机器学习项目中指标收集对训练性能的影响,特别是如何通过简单实现引入不必要的CPU-GPU同步事件,导致训练时间增加约10%。使用TorchMetrics库和PyTorch Profiler工具,文章详细分析了性能瓶颈的根源,并提出了多项优化措施
416 1
PyTorch Profiler 性能优化示例:定位 TorchMetrics 收集瓶颈,提高 GPU 利用率
|
11月前
|
人工智能 PyTorch 算法框架/工具
Ascend Extension for PyTorch是个what?
Ascend Extension for PyTorch 是针对华为昇腾处理器的PyTorch框架适配插件,旨在让PyTorch开发者能充分利用昇腾AI处理器的强大计算能力。此扩展通过最小化对原生PyTorch的改动,实现了对昇腾NPU的支持,包括动态图特性、自动微分等功能的完整继承,并提供了与原生PyTorch一致的使用体验。项目详情及源码可在昇腾社区获取。
Ascend Extension for PyTorch是个what?
|
12月前
|
网络协议
网络通信的基石:TCP/IP协议栈的层次结构解析
在现代网络通信中,TCP/IP协议栈是构建互联网的基础。它定义了数据如何在网络中传输,以及如何确保数据的完整性和可靠性。本文将深入探讨TCP/IP协议栈的层次结构,揭示每一层的功能和重要性。
705 5
|
API PHP 数据库
PHP中的异常处理机制深度解析与最佳实践####
本文深入探讨了PHP中异常处理机制的核心概念、工作原理及其在现代Web开发中的应用。通过剖析try-catch结构、自定义异常类及异常的继承体系,揭示了如何高效地捕获、处理并管理运行时错误,以提升应用的稳定性和用户体验。文章还结合实例,分享了在实际项目中实施异常处理的最佳实践,帮助开发者构建更加健壮的PHP应用程序。 ####
|
测试技术 C# 数据库
C# 一分钟浅谈:测试驱动开发 (TDD) 实践
【10月更文挑战第18天】测试驱动开发(TDD)是一种软件开发方法论,强调先编写测试代码再编写功能代码,以确保代码质量和可维护性。本文从 TDD 的基本概念入手,详细介绍了其核心步骤——编写测试、运行测试并失败、编写代码使测试通过,以及“红绿重构”循环。文章还探讨了 TDD 的优势,包括提高代码质量、促进设计思考、减少调试时间和文档化。此外,文中分析了常见问题及解决方案,如测试覆盖率不足、测试代码过于复杂、忽视重构和测试依赖过多,并通过一个简单的计算器类的代码案例,展示了 TDD 的实际应用过程。
234 1
|
安全 搜索推荐 Android开发
安卓与iOS:两大操作系统的比较
本文将深入探讨安卓和iOS两大操作系统的差异,包括它们的设计理念、用户界面、应用生态以及安全性等方面。通过对比分析,我们可以更好地理解这两个系统各自的优势和不足,从而为用户在选择手机时提供一些参考。
|
定位技术 Python
Matplotlib 教程 之 Matplotlib imshow() 方法 1
《Matplotlib imshow() 方法教程》:本文介绍 Matplotlib 库中的 imshow() 函数,该函数常用于绘制二维灰度或彩色图像,也可用于展示矩阵、热力图等。文中详细解释了其语法及参数,例如颜色映射(cmap)、归一化(norm)等,并通过实例演示了如何使用 imshow() 显示灰度图像。
357 2
|
数据采集 定位技术 计算机视觉
归一化
【9月更文挑战第15天】
576 3