JavaScript对象的增强知识

news2024/12/24 22:02:00

Object.defineProperty

◼ 在前面我们的属性都是直接定义在对象内部,或者直接添加到对象内部的:
 但是这样来做的时候我们就不能对这个属性进行一些限制:比如这个属性是否是可以通过delete删除的?这个属性是否在for-in遍历的时候被遍历出来呢?
◼ 如果我们想要对一个属性进行比较精准的操作控制,那么我们就可以使用属性描述符。
 通过属性描述符可以精准的添加或修改对象的属性;
 属性描述符需要使用 Object.defineProperty 来对属性进行添加或者修改;


◼ Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
◼ 可接收三个参数:
 obj要定义属性的对象;
 prop要定义或修改的属性的名称或 Symbol;
 descriptor要定义或修改的属性描述符;
◼ 返回值:
 被传递给函数的对象。


◼ 属性描述符的类型有两种:
 数据属性(Data Properties)描述符(Descriptor);
 存取属性(Accessor访问器 Properties)描述符(Descriptor);

数据属性描述符

◼ 数据数据描述符有如下四个特性:
◼ [[Configurable]]:表示属性是否可以通过delete删除属性是否可以修改它的特性(包括另外三个),或者是否可以将它修改为存取属性描述符;
 当我们直接在一个对象上定义某个属性时,这个属性的[[Configurable]]默认为true
 当我们通过属性描述符定义一个属性时,这个属性的[[Configurable]]默认为false;(不可删除)


◼ [[Enumerable]]:表示属性是否可以通过for-in或者Object.keys()返回该属性;
 当我们直接在一个对象上定义某个属性时,这个属性的[[Enumerable]]为true;
 当我们通过属性描述符定义一个属性时,这个属性的[[Enumerable]]默认为false;


◼ [[Writable]]:表示是否可以修改属性的值;
 当我们直接在一个对象上定义某个属性时,这个属性的[[Writable]]为true;
 当我们通过属性描述符定义一个属性时,这个属性的[[Writable]]默认为false;


◼ [[value]]:属性的value值,读取属性时会返回该值,修改属性时,会对其进行修改;
 默认情况下这个值是undefined;

var obj = {
      name: "why", // configurable: true
      age: 18
    }
 
    Object.defineProperty(obj, "name", {
      configurable: false, // 告诉js引擎, obj对象的name属性不可以被删除
      enumerable: false, // 告诉js引擎, obj对象的name属性不可枚举(for in/Object.keys)
      writable: false, // 告诉js引擎, obj对象的name属性不写入(只读属性 readonly)
      value: "coderwhy" // 告诉js引擎, 返回这个value
    })
 
    delete obj.name
    console.log(obj)
 
    // 通过Object.defineProperty添加一个新的属性
    Object.defineProperty(obj, "address", {})
    delete obj.address
    console.log(obj)
 
    console.log(Object.keys(obj))
 
    obj.name = "kobe"
    console.log(obj.name)
 


存取属性描述符

 ◼ 数据数据描述符有如下四个特性:
◼ [[Configurable]]:表示属性是否可以通过delete删除属性,是否可以修改它的特性,或者是否可以将它修改为存取属性描述符;
 和数据属性描述符是一致的;
 当我们直接在一个对象上定义某个属性时,这个属性的[[Configurable]]为true;
 当我们通过属性描述符定义一个属性时,这个属性的[[Configurable]]默认为false;
◼ [[Enumerable]]:表示属性是否可以通过for-in或者Object.keys()返回该属性;
 和数据属性描述符是一致的;
 当我们直接在一个对象上定义某个属性时,这个属性的[[Enumerable]]为true;
 当我们通过属性描述符定义一个属性时,这个属性的[[Enumerable]]默认为false;
◼ [[get]]:获取属性时会执行的函数。默认为undefined
◼ [[set]]:设置属性时会执行的函数。默认为undefined

// vue2响应式原理
    var obj = {
      name: "why"
    }
 
    // 对obj对象中的name添加描述符(存取属性描述符)
    var _name = ""
    Object.defineProperty(obj, "name", {
      configurable: true,
      enumerable: false,
      set: function(value) {
        console.log("set方法被调用了", value)
        _name = value
      },
      get: function() {
        console.log("get方法被调用了")
        return _name
      }
    })
 
    obj.name = "kobe"
    obj.name = "jame"
    obj.name = "curry"
    obj.name = "coderwhy"
 
    // 获取值
    console.log(obj.name)

正确写法 

      get: function() {
        console.log("get方法被调用了")
        return _name
      }

无限递归写法

      get: function() {
        return obj.name
      }

Object.defineProperties

Object.defineProperties() 方法直接在一个对象上同时定义多个新的属性或修改现有属性,并且返回该对象。

 var obj = {
      name: "why",
      age: 18,
      height: 1.88
    }
 
    // Object.defineProperty(obj, "name", {})
    // Object.defineProperty(obj, "age", {})
    // Object.defineProperty(obj, "height", {})
 
    // 新增的方法
    Object.defineProperties(obj, {
      name: {
        configurable: true,
        enumerable: true,
        writable: false
      },
      age: {
      },
      height: {
      }
    })

对象的其他方法补充

◼ 获取对象的属性描述符:
 getOwnPropertyDescriptor
 getOwnPropertyDescriptors
◼ 禁止对象扩展新属性:preventExtensions
 给一个对象添加新的属性会失败(在严格模式下会报错);
◼ 密封对象,不允许配置和删除属性:seal
 实际是调用preventExtensions
 并且将现有属性的configurable:false
◼ 冻结对象,不允许修改现有属性:freeze
 实际上是调用seal
 并且将现有属性的writable: false

 var obj = {
      name: "why",
      age: 18
    }
 
    // 1.获取属性描述符
    console.log(Object.getOwnPropertyDescriptor(obj, "name"))
    console.log(Object.getOwnPropertyDescriptors(obj))
 
    // 2.阻止对象的扩展
    Object.preventExtensions(obj)
    obj.address = "广州市"
    console.log(obj)
 
    // 3.密封对象(不能进行配置)
    Object.seal(obj)
    delete obj.name
    console.log(obj)
 
    // 4.冻结对象(不能进行写入)
    Object.freeze(obj)
    obj.name = "kobe"
    console.log(obj)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/623787.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微信能取代对讲机吗?区别在哪?

对讲机和微信的区别在哪?为什么大家在通讯方面选择对讲机而不是微信? 微信作为社交软件在多个领域都有着广泛的应用,不过在对讲机行业也在讨论一个话题:微信能否取代对讲机?下面河南宝蓝小编就和大家聊聊这个话题。 …

基于redis实现秒杀并防止超卖

基于redis实现秒杀并防止超卖 为什么基于redis针对秒杀商品库存为一个的情况setnx代码实现测试 针对有多个库存的商品实现测试 为什么基于redis 因为所有redis的操作(这里指的是key的操作,像备份落盘之类的另算)都是单线程的,所以…

一文读懂:LoRA实现大模型LLM微调

LoRA大模型LLM微调 为什么要进行微调?LoRA思路提高权重更新效率选择低的秩 实现LoRALoRA在LLaMA实现 为什么要进行微调? 在快速发展的人工智能领域中,以高效和有效的方式使用大型语言模型变得越来越重要。 预训练的大型语言模型通常被称为优…

02-启动 Vue 项目

一. 学习目标 掌握 Vue 项目的启动 二. 学习内容 掌握 Vue 项目的启动 三. 学习过程 项目的启动也有两种方式,一种是通过图形界面启动,另一种是通过命令行启动。 1.图形界面 打开vscode编辑器,点击 1.文件 ——>打开文件夹&#xff0c…

springboot实现支付宝支付(沙箱环境)

springboot实现支付宝支付 1. 获取应用id,应用私钥和支付宝公钥2. 开始开发3. 内网穿透4. 测试支付功能 1. 获取应用id,应用私钥和支付宝公钥 进入支付宝控制台:https://open.alipay.com/develop/manage 找到沙箱 这里可以看到应用id 可以看到应用私钥和支付宝公钥,获取这…

Zoho:集成ChatGPT、开发大型语言模型,加紧布局AI+SaaS

在企业的数字化转型进程中,管理层和员工的数字化意识会随着建设的推进而不断提高,对于办公场景的数字化应用需求也不断产生。传统的办公系统建设中,系统的应用能力需要支撑越来越丰富的场景需求。 《今日人工智能》采访到Zoho中国VP兼SaaS事业…

【编程语言 · C语言 · for语句】

for 语句 C语言中,使用for语句也可以控制一个循环,并且在每一次循环时修改循环变量。在循环语句中,for语句的应用最为灵活,不仅可以用循环次数已经确定的情况,而且可以用于循环次数不确定而只给出循环结束条件的情况。…

jenkins构建pipline无法执行shell命令原因

问题表现 新的服务器上,新安装的jenkins,在上面创建了一个pipline项目,脚本里有shell命令,但是jenkins每次执行都卡住,经过尝试,无论多简单的命令都执行不了,cp,mv等都不行&#xf…

华为路由器:ospf协议三张表及邻居建立过程

说明:本篇接上一篇继续讲解 拓扑图 为了方便,我把R1/2/3/4/5的router id改成了回环网卡的IP。 ospf协议三张表 邻居表(neighbortable) OSPF用邻居机制来发现和维持路由的存在,邻居表存储了双向通信的邻居关系OSPF路…

矩形图:数据之美在图形中展现

在当今信息爆炸的时代,数据已经成为决策和洞察的重要基石,但海量的数据如果不经过整理和呈现,往往难以得出有意义的结论。这时候,可视化工具的作用就变得尤为重要了。在众多可视化形式中,矩形图以其简洁直观的特点受到…

团队管理之性能实施团队日志9

最近项目进入胶着状态。 混合场景在有些项目组里已经可以开始了,但还是有两三个项目组现在是完全没办法混合起来的。 本周计划是把基准测试、容量测试跑完,稳定性测试每个项目组至少能跑一遍。 但是从进度上来看,容量测试至少有四个系统不能跑…

各类动态路由协议汇总简介

目录 一、前言 二、OSPF协议 (一)OSPF是什么 (二)OSPF的工作原理 (三)OSPF的特点 (四)OSPF的使用 (五)OSPF的优点 (六)总结 …

ROS——从深度图转换到octomap(C++)

文章目录 介绍环境准备三维灰度栅格图三维RGB栅格图对点云进行过滤处理参考介绍 八叉树是用于在3D视觉中细分空间的数据结构。每个立方体都可以逐级地细分为8个子立方体,直到达到了给定的最小体积(体素)尺寸。且该最小体积(体素)决定了八叉树的分辨率。 octomap的作用:…

代码随想录算法训练营第五十一天|309.最佳买卖股票时机含冷冻期|714.买卖股票的最佳时机含手续费

LeetCode309.最佳买卖股票时机含冷冻期 动态规划五部曲: 1,确定dp数组以及下标的含义:dp[i][j],第i天状态为j,所剩的最多现金为dp[i][j]。出现冷冻期之后,状态其实是比较复杂度,例如今天买入股…

接口自动化【七】__包装响应结果的数据为key-value

文章目录 前言 一、本章学习的思路 二、用接口新建商品_使用步骤 ​​​​​​​步骤一:先用抓包的方式拿到新建商品的接口 步骤二:我们先用单接口的形式,把这个商品添加成功 三、处理响应接口_(包装响应结果的数据为&#xf…

Flume自定义拦截器 - ETL拦截器和分类拦截器

水善利万物而不争,处众人之所恶,故几于道💦 目录 一、拦截器(Interceptor)和选择器(Selector) 拦截器(Interceptor) 选择器(Selector) 二、自定…

【机器学习 | 深度学习】Colab是什么?以及如何使用它?

文章目录 一、介绍二、如何使用 Colaboratory 创建代码三、实例测试 一、介绍 Colaboratory(简称为Colab)是由Google开发的一种基于云端的交互式笔记本环境。它提供了免费的计算资源(包括CPU、GPU和TPU),可让用户在浏…

本地部署gitlab学习git使用

文章目录 前言一、安装gitlab二、nginx反向代理三、本地配置hosts,自定义域名四、配置gitlab独立ngxin实现域名访问五、其他总结 前言 最近想学习git使用了,在本地部署一个gitlab社区版玩玩吧~ gitlab只能部署在liunx系统上面,可以使用云服务…

TLD2314EL-ASEMI代理英飞凌汽车芯片TLD2314EL

编辑:ll TLD2314EL-ASEMI代理英飞凌汽车芯片TLD2314EL 型号:TLD2314EL 品牌:Infineon(英飞凌) 封装:SSOP-14-EP-150mil 特性:LED驱动、汽车芯片 宽温度范围:-40C~150C 封装:SSOP-14&…