JavaScript 动态属性赋值方式与原理剖析

JavaScript类型系统解析:原始类型与对象的双轨制设计 JavaScript类型系统并非简单的‘弱类型’标签,而是由原始类型与对象类型构成的双轨制结构,其核心在于运行时行为差异——原始值按值传递、不可变、自动装箱;对象按引用传递、可变、动态扩展。这种设计源于早期浏览器性能约束,在IEEE 754浮点数表示、`null`历史bug、`typeof`局限性、`==`隐式转换等细节中持续体现。理解该机制是准确使用`Array.isArray()`、`Object.prototype.toString.call()`、`Number.isNaN()`等标准检测方法的前提 阅读详情

      工作中遇到一个场景,是给不同的按钮挂载不同的跳转地址,在vue页面实现的。实际实现的就是给一个前端定义好的对象添加后台返回的数据,这里用一个实例代替业务代码来展现 一下这个场景:

首先页面按钮代码与触发方法:

<template>
  <div>
    <button v-for="(path, id) in paths" :key="id" @click="handleButtonClick(id)">
      {{ id }}
    </button>
  </div>
</template>

原业务代码这里的按钮是一个个手写出来,这里用v-for循环一个意思。主要为了实现,多个按钮绑定对应不同的地址,然后实现点击跳转,下面就是这个点击操作触发的方法:

<script>
export default {
  data() {
    return {
      paths: {}, // 初始化为空对象
      userId: 'your-user-id', // 用户ID
      rowId: 'your-row-id' // 行ID
    };
  },

  methods: {
    async fetchButtonPaths() {
      try {
        const res = await thingsToDo(this.userId, this.rowId);
        if (res.data.msg === 'success') {
          const buttonPaths = res.data.data.buttonPaths;
          buttonPaths.forEach(path => {
            this.paths[path.id] = path.path; // 动态添加属性
          });
        } else {
          console.error('获取按钮路径失败:', res.data.msg);
        }
      } catch (error) {
        console.error('请求错误:', error);
      }
    },

    handleButtonClick(buttonId) {
      const path = this.paths[buttonId];
      if (path) {
        this.$router.push(path);
      } else {
        console.error('未找到按钮路径:', buttonId);
      }
    }
  },

  created() {
    this.fetchButtonPaths(); // 在组件创建时获取按钮路径
  }
};
</script>

上述写法首先定义了需要接收返回数据的集对象,paths:{}是核心对象,那两个id不重要。

下面两个方法fetchButtonPaths代表了异步请求后台的操作,其中

const buttonPaths = res.data.data.buttonPaths;
          buttonPaths.forEach(path => {
            this.paths[path.id] = path.path; // 动态添加属性
          });

这里是核心赋值代码,这里实现了 JavaScript中动态属性的赋值。其中后台返回的值res的内容结构格式如下:

{
  "msg": "success",
  "data": {
    "buttonPaths": [
      { "id": "button1", "path": "/exam/applys/confirmnotpayexaminee1" },
      { "id": "button2", "path": "/exam/applys/confirmnotpayexaminee2" },
      { "id": "button3", "path": "/exam/applys/confirmnotpayexaminee3" }
    ]
  }
}

上述操作后,在data属性中定义的paths:{}对象就有了内容, 拆开来看这里的操作实现了下面的转变:

const paths = {}; // 初始化为空对象
const path = { id: "button1", path: "/exam/applys/confirmnotpayexaminee1" };

// 动态添加属性
paths[path.id] = path.path;

console.log(paths); // 输出: { button1: "/exam/applys/confirmnotpayexaminee1" }

然后使用点击方法便可根据id的值获取到对应的跳转地址实现跳转,功能到这就完成了, JavaScript 动态属性赋值一般也是这么操作的,但是我有了一个疑问:

最初在data中创建的paths:{}集合是空的,里面没有事先写好的属性名,但是在动态赋值的时候,
paths[path.id] = path.path;却可以正确的添加id:path格式的键值对,这是怎么实现的,按照传统后端思维,paths集合中获取没有的key进行操作,一定会报错的。

然后我便查阅了一些资料,在这同时做个小小的原理总结:

首先说结论,

  • JavaScript动态属性赋值:在 JavaScript 中,对象的属性可以动态添加。即使对象初始为空,你也可以随时为其添加新的属性。
  • this.paths[path.id] = path.path:这行代码实际上是将 path.path 的值赋给 this.paths 对象中名为 path.id 的属性。如果该属性不存在,JavaScript 会自动创建它。

依据上述案例解释下流程详细步骤:

  1. 初始化对象:

    • const paths = {}; 初始化一个空对象 paths。
  2. 路径对象:

    • const path = { id: "button1", path: "/exam/applys/confirmnotpayexaminee1" }; 定义一个路径对象 path,包含 id 和 path 属性。
  3. 动态添加属性:

    paths[path.id] = path.path; 这行代码做了以下几件事:
    • 将 path.path 的值(即 "/exam/applys/confirmnotpayexaminee1")赋值给 paths 对象的 "button1" 属性。
    • 如果 paths 对象中不存在 "button1" 属性,JavaScript 会自动创建这个属性。
    • paths 对象中查找名为 "button1" 的属性。
    • path.id 是字符串 "button1"。

上述就是大面上的解释,但是我觉得还不够,本着希望从源码中得到解答的精神,继续查阅资料,终于触碰到了我的知识壁垒,下面我就做个简单的原理概述,结束这次的菜狗验证:

JavaScript 引擎在处理对象属性赋值时,会执行以下步骤:

  1. 检查对象是否存在:

    • 确认对象是否存在。如果对象不存在,会抛出错误。
  2. 查找属性:

    • 检查对象中是否已经存在指定的属性。
  3. 属性不存在时创建属性:

    • 如果属性不存在,引擎会创建一个新的属性,并将其值设置为指定的值。

伪代码实现

为了更好地理解这一过程,我们可以用伪代码来模拟 JavaScript 引擎的行为:

function assignProperty(obj, key, value) {
  // 检查对象是否存在
  if (typeof obj !== 'object' || obj === null) {
    throw new TypeError('Cannot set property of non-object');
  }

  // 检查对象中是否已经存在指定的属性
  if (!(key in obj)) {
    // 属性不存在,创建新的属性
    obj[key] = value;
  } else {
    // 属性已存在,更新属性值
    obj[key] = value;
  }
}

// 测试
const paths = {};
const path = { id: "button1", path: "/examn/applys/confirmnotpayexaminee1" };

assignProperty(paths, path.id, path.path);

console.log(paths); // 输出: { button1: "/exam/applys/confirmnotpayexaminee1" }

实际的 JavaScript 引擎实现

实际的 JavaScript 引擎(如谷歌的 V8)的实现要复杂得多,涉及到许多优化技术,如内联缓存、隐藏类等。以下是一个简化的 V8 引擎的实现步骤:

  1. 对象表示:

    • 在 V8 中,对象通常由一个哈希表或数组来表示,每个属性对应一个键值对。
  2. 属性查找:

    • 使用哈希表查找属性。如果属性存在,直接返回属性值。
    • 如果属性不存在,继续下一步。
  3. 属性创建:

    • 创建一个新的属性,并将其值设置为指定的值。
    • 更新对象的内部结构(如哈希表或数组)。

V8 引擎的内部结构

V8 引擎使用了一些高级的数据结构和优化技术来提高性能。以下是简化的内部结构:

  1. 哈希表:

    • 使用哈希表来存储对象的属性,以便快速查找和插入。
  2. 隐藏类:

    • 使用隐藏类来优化属性访问。隐藏类是一种内部表示,用于描述对象的结构。
  3. 内联缓存:

    • 使用内联缓存来加速属性访问和修改操作。

示例代码

为了更直观地理解,我们可以用一个简单的 JavaScript 对象来模拟这一过程:

class SimpleObject {
  constructor() {
    this.properties = {};
  }

  hasProperty(key) {
    return key in this.properties;
  }

  getProperty(key) {
    return this.properties[key];
  }

  setProperty(key, value) {
    this.properties[key] = value;
  }
}

// 测试
const paths = new SimpleObject();
const path = { id: "button1", path: "/exam/applys/confirmnotpayexaminee1" };

if (!paths.hasProperty(path.id)) {
  paths.setProperty(path.id, path.path);
} else {
  paths.setProperty(path.id, path.path);
}

console.log(paths.getProperty(path.id)); // 输出: /exam/applys/confirmnotpayexaminee1

总结

  • 动态属性赋值:在 JavaScript 中,对象的属性可以动态添加。如果属性不存在,JavaScript 引擎会自动创建这个属性。
  • 内部实现:JavaScript 引擎(如 V8)使用哈希表、隐藏类和内联缓存等技术来优化属性的查找和创建过程。

 前端菜狗,欢迎指导。

从CTFshow NodeJS靶场实战,聊聊原型链污染漏洞的几种利用姿势(附web338-344详细payload) 本文深入剖析NodeJS原型链污染漏洞的原理与利用方式,通过CTFshow靶场web338-344实战案例,详细演示了从基础污染到模板引擎RCE的高级利用技巧。文章不仅提供了多种payload构造方法,还总结了有效的防御策略,帮助开发者提升JavaScript应用安全性。 阅读详情

相关推荐

JavaScript动态添加对象属性的方法

通过以上三种方法,我们可以动态地添加属性到JavaScript对象中。根据需求的不同,我们可以选择适合的方法来实现属性的动态添加。最简单的方法是使用点符号来添加属性。首先,我们需要创建一个对象,然后使用点符号将属性名作为对象的成员来添加属性。在JavaScript中,我们经常需要在运行时动态地向对象添加属性。这可以通过几种不同的方法实现,让我们逐一介绍这些方法。除了使用点符号,我们还可以使用方括号符号来添加属性。如果我们需要更多的属性控制,例如定义属性的特性(如可写、可枚举等),我们可以使用。

DevProZ的博客 1158

JavaScript解构、剩余参数与展开语法:原理、陷阱与协同实战

解构赋值、剩余参数和展开语法是ES2015+中处理不确定结构数据的核心机制。它们并非语法糖,而是基于模式匹配、弹性参数绑定与数据管道流动的底层语言能力。理解其在V8引擎中的优化逻辑(如模式特化、轻量数组引用、栈上分配)可规避性能陷阱;掌握三者语义边界(如`...`在函数参数中为‘收’、在字面量中为‘放’、在解构中为‘兜底’)能避免TypeError和静默失败。这些特性已深度应用于Vue 3 API解构、React props透传、Node.js CLI参数解析等主流场景,是现代前端工程实践的基础设施。

weixin_33795093的博客 359

SceneSplat

目标:训练一个网络,输入高斯参数 → 输出与自然语言空间对齐的特征。考虑到标注语义的 3DGS 数据有限,作者设计了。策略,让模型在无标签场景上学到有用表征。都有一个与自然语言对齐的语义特征。这是整个方法的第一步,目标是让。

weixin_61091146的博客 1284

Js动态拼接对象、添加属性

放在点符号后面,我们可以动态地指定属性的名字,并将其赋值为变量value。方法将一个新对象和一个拥有动态键值的对象合并在一起。不同的是,我们使用方括号符号来包裹变量key。作为第一个参数,可以确保创建一个新的对象。来动态添加一个名为name。来动态添加一个名为name。,以动态地指定属性的名字。此方法也是使用变量key。二、动态添加对象属性。

CheneyChen27的博客 3068

Linux安装消息队列IBM MQ 7.5开发版安装配置详解

消息队列IBM MQ 7.5开发版安装配置详解 文章目录消息队列IBM MQ 7.5开发版安装配置详解前言一、什么是IBM MQ?二、安装前准备1、安装前准备2、安装MQ Server3、启动实例4、创建队列一个名为TEXT的队列(测试)5、启动端口监听6、启动成功总结 前言 IBM 已经熟练地优化了 MQ(消息队列),在市场上已有超过 25 年的历史。借助 MQ(消息队列),如果无法立即传递消息,那么会在其等待队列中确保消息安全,直到保证传递为止。竞争产品可能会传递两次消息或根本不传递消息,而 M

zhx__的博客 5165

RK-XCKU5P RoCEv2 传感器桥工程分析报告

烧入后这块 FPGA 就是一个固定身份(CA:FE:C0:FF:EE:00 / 192.168.0.2 / 无 FEC 100G)的RoCEv2 UC 端点,每秒在 UDP 12267 广播自报家门;对端 CX5 只要关 FEC、配 192.168.0.101 +MTU 4200,就能 ping 通它、用 UDP 8192 读写它的全部寄存器、再按"ECB 旁路交换 QPN/rkey"的方式建立 UC RDMA 通道收发数据。

eloudy的专栏 245

【JS】js给对象动态添加、设置、删除属性名和属性值

但是当我们遇到需要给对象动态添加属性和属性值时,点获取法好像就不方便了,尤其是我们不知道属性名的时候更麻烦。简短的回答是“有特别的顺序”整数属性会被进行排序,其他属性则按照创建的顺序显示。计算属性的含义很简单[fruit]含义是属性名应该从fruit变量中获取。注意如果我们遍历一个对象,我们获取属性的顺序是和属性添加时的顺序相同吗?当创建一个对象时,我们可以在对象字面量中使用方括号。js中访问对象属性一共有两种方法点获取法和方括号获取法。最常用的对象属性获取方法是点获取法。...

余浩的博客 2万+

无人机+消防车:高楼灭火系统技术详解

传统的消防设备,如登高车、车载水枪、水炮和高喷车,在50米以上高度的火源面前往往力不从心,100米以上高层火灾则更加依赖消防员“爬楼”灭火,效率低下且风险极高。消防水带:采用聚乙烯丝材质,超轻、耐腐蚀、强度高,能够携带大量水或灭火泡沫进行高空喷水灭火作业。“无人机+消防车”高楼灭火系统主要由消防车和无人机两部分组成,通过机车联动实现高效灭火。高效灭火:无人机能够快速到达高层建筑顶部或指定位置进行灭火作业,大大提高了灭火效率。空压泡沫系统:配备超大水箱,支持长时间供应灭火泡沫,满足无人机灭火剂的需求。

专注多旋翼、复合翼无人机技术研究,从事低空经济行业。 1670

2022-03-28 工作记录--JS-对象添加动态属性 + 获取到动态属性的属性值

JS-对象添加动态属性

weixin_48850734的博客 3508

Aurix TC387 Ethernet代码解析之二_移植

英飞凌官方仅提供了TC397的例程,故需通过TC397例程来移植到TC387新建工程里。TC397官方例程名称【Ethernet_1_KIT_TC397_TFT】,网络上可以免费获取到,此处不赘述。使用工具【

m0_69929716的博客 884

通俗易懂的Harris 角点检测

点击上方“3D视觉工坊”,选择“星标”干货第一时间送达Harris 角点检测 认为特征点具有局部差异性。如何描述“特征点具有局部差异性”:以每一个点为中心,取一个窗口,窗口大小为5*5...

3D视觉工坊 1473

Js对象动态添加属性

/ 输出: { name: ‘zhang’ }console.log(obj);// 输出: { name: ‘zhang’ }console.log(obj);// 输出: {name: ‘zhang’}

优快云18202250010的博客 963

MounRiver Studio(MRS)使用技巧:添加头文件目录;增加代码分组

MounRiver Studio(MRS)使用技巧:添加头文件目录

cheng___yi的博客 1808

JavaScript原型链污染:原理、利用与防御实战指南

在JavaScript开发中,对象属性访问和原型链机制是核心概念。当程序尝试访问对象属性时,引擎会遵循原型链向上查找,这一机制构成了基于原型的继承模型。然而,如果攻击者能够通过特定API(如对象合并、动态属性赋值)向对象的原型中注入或修改属性,就会引发原型链污染漏洞,其技术价值在于揭示了语言特性被滥用的安全风险。这种漏洞常出现在对象合并、配置扩展等常见操作中,可能导致全局配置篡改、权限绕过等严重后果。本文聚焦于原型链污染,通过分析其发生原理、常见利用路径(如通过constructor.prototype)以

weixin_34174105的博客 340

置顶必读(3) |《滚雪球学SpringBoot》· 高质量专栏介绍,你值得拥有!

《滚雪球学SpringBoot》 并不是普通的技术讲解合集,它是专为开发者精心设计的系统化学习路径。通过不断“滚动学习”,我们将带领你从基础入门到高阶应用,从理解每一行代码到设计和优化大规模分布式系统,最终帮助你成长为一位精通 spring架构 的工程师。

**My Coding Family** 15万+

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

You Don‘t Know JS元编程:Proxy与Reflect如何拦截对象操作(响应式原理完整剖析)

在《You Don't Know JS》系列书籍(GitHub 加速计划 youdon/You-Dont-Know-JS 开源项目)中,JavaScript 元编程的终极武器——**Proxy 代理**与 **Reflect 反射**,是理解 Vue、MobX 等框架响应式原理的关键钥匙。这篇文章带你从"拦截对象操作"讲起,一步步剖析 Proxy 与 Reflect 如何联手构建出响应式系统的底层

gitblog_00143的博客 843

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

揭秘D3.js底层原理:如何用50行代码实现动态数据可视化?

掌握前端可视化d3的核心原理,本文教你用50行代码实现动态数据图表。适用于数据看板、交互式报表等场景,基于D3.js绑定数据与DOM,流畅更新视图。方法简洁高效,助你快速上手,值得收藏。

ByteGlow的博客 317

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

鸿蒙适配实战:js_wrapping 桥接层重写与 Flutter 调用 JavaScript

跨端开发中,Flutter 与 JavaScript 代码的互操作是常见需求,尤其在迁移存量业务时,如何在鸿蒙设备上复用既有 JS 模块成为关键难题。js_wrapping 作为 Dart 与 JavaScript 之间类型安全互操作库,通过编译期代码生成和运行时包装抽象,原本依赖平台 JS 引擎作为底座,而鸿蒙环境需要重写该互操作层。本文从跨运行时通信、N-API 调用、MethodChannel 边界出发,剖析了在鸿蒙上替换 js_wrapping 底层桥接层的完整方案,涵盖属性映射、强类型回调、生命周

weixin_33095355的博客 255

Vue2与Vue3响应式系统对比与优化实践

响应式系统是现代前端框架的核心机制,通过数据绑定实现视图自动更新。其原理主要分为数据劫持和代理拦截两种实现方式,Vue2采用Object.defineProperty进行属性劫持,而Vue3则基于ES6 Proxy重构。从技术价值看,Proxy方案解决了数组监听、动态属性添加等痛点,并带来显著性能提升。在实际工程中,Vue3的惰性监听机制和编译时优化使其在处理大型应用时更具优势,特别适合后台管理系统、动态表单等复杂场景。通过对比Vue2和Vue3在数组操作、动态属性处理等方面的差异,开发者可以更好地理解响应

weixin_33736048的博客 380

Vue响应式原理与常见数据更新问题解析

响应式编程是现代前端框架的核心机制,通过数据绑定实现视图自动更新。Vue采用依赖追踪技术,在数据变化时精确更新相关DOM。其核心原理在Vue2中基于Object.defineProperty实现属性劫持,而Vue3升级为Proxy方案以解决动态属性等限制。在实际开发中,开发者常遇到数组索引赋值无效、对象属性添加不触发更新等典型问题,这源于响应式系统的实现机制。通过理解Vue.set方法、数组变异函数等解决方案,可以避免常见的数据更新陷阱。在组件开发层面,合理运用计算属性缓存、watch深度监听等特性,能有效

weixin_32520095的博客 251

Nashorn引擎:JVM上JavaScript性能优化的实战与启示

在Java虚拟机(JVM)生态中,运行动态语言如JavaScript一直面临核心挑战。JVM作为静态类型语言的运行时环境,其JIT编译、方法内联和逃逸分析等优化机制,主要针对类型稳定的场景设计。而JavaScript的动态类型特性,如变量类型可变、对象属性可动态增删,导致传统优化策略难以直接应用,性能优化成为技术难点。其技术价值在于,通过探索类型推断、调用点缓存等适配方案,为高并发服务端渲染、多语言运行时等场景提供了实践参考。Nashorn引擎作为JVM上运行JavaScript的经典案例,深入剖析了其在字

weixin_30443075的博客 321

分清JavaScript中{}和[]的每种身份:对象、数组、解构与常见陷阱

JavaScript是前端开发的核心语言,语法灵活强大,但也是许多隐性bug的来源。在JavaScript代码中,{}和[]两个基础符号在不同上下文里扮演着截然不同的角色,它们可以是对象字面量、数组字面量,也可以是代码块、解构模式或属性访问操作符。理解符号的“身份切换”是掌握JavaScript语法的关键,也是提升工程代码质量的基础。实际开发中,从接口数据的解构取值、动态属性访问到箭头函数返回对象,都高度依赖对这些语法的准确判断。掌握这些原理能有效避免运行时错误,提高代码的可读性与健壮性。本文系统性拆解{}

weixin_31179927的博客 224

HoRain云--JavaScript对象全解析:从入门到精通

JavaScript对象核心知识摘要 JavaScript对象是键值对集合,包含属性(字符串/Symbol键)和方法(函数值)。创建方式包括字面量语法、构造函数和ES6类。属性访问有点符号和方括号两种方式。对象通过原型链实现继承,可使用Object.defineProperty()定义属性特性。常用操作包括增删查改属性、遍历(for...in/Object.keys等)、对象冻结/密封。ES6新增解构赋值和扩展运算符功能。注意对象是引用类型,赋值传递引用地址。掌握原型链、属性描述符等核心概念,结合ES6新特

2401_86544677的博客 658

eslint-plugin-unicorn 的 no-unsafe-dom-html 规则深度解析:从 AVA 测试快照看 XSS 注入点的静态检测

本篇技术指南以 eslint-plugin-unicorn 仓库中的测试快照报告 [test/snapshots/no-unsafe-dom-html.js.md](https://link.gitcode.com/i/223fc701c9154656b59e6053a1c8ba2a) 为主体,结合 [规则源码](https://link.gitcode.com/i/6cd03b69caa2dc1

gitblog_00960的博客 5

Vue 3 核心原理与实战:从响应式到企业级应用

Vue 3 核心原理与实战指南 本文全面解析 Vue 3 的核心技术升级与最佳实践。重点探讨了: 响应式系统革命:采用 Proxy 替代 defineProperty,实现更高效的属性监听和惰性劫持 编译时优化:通过 Patch Flag 和静态提升技术大幅提升虚拟 DOM 性能 开发范式演进:Composition API 提供更好的逻辑复用与 TypeScript 支持 现代化工具链:推荐使用 Vite 构建工具、Pinia 状态管理和 Nuxt 3 全栈框架 文章通过代码示例和原理对比,帮助开发者从

1221

告别“神策”,Vue 3响应式系统原理与手动效应控制实战

Vue 3响应式系统全面升级,采用Proxy替代Object.defineProperty,解决了动态属性监听、数组变化追踪等痛点。本文深入剖析其核心原理,包括reactive函数实现、效应控制机制(effect)和依赖收集系统,并通过手动实现ref、computed等API展示其内部工作原理。特别介绍了嵌套effect处理、自定义调度器优化等高级特性,以及浅层响应式、批量更新等性能优化技巧。通过理解这些底层机制,开发者能更高效地使用Vue 3构建复杂应用,同时为状态管理等高级场景打下坚实基础。

570
上一篇: 误删.idea后的svn菜单找回
下一篇: .xls改为.xlsx格式文档使用Java解析报错问题分析
mmm.c
博客等级 码龄9年 117粉丝 62原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值