导入(Import)导出(Export)的内存模型及原理

embedded/2025/1/2 18:40:19/
  1. 导入(Import)的内存模型及原理

    • 内存布局

      • 当使用import语句(如import MyTreeTableWrapper from '@/service/prd/test/MyTreeTableWrapper.js';)时,JavaScript引擎会在内存中为导入的模块创建一个模块环境记录(Module Environment Record)。这个记录包含了模块导出的绑定(bindings)信息。
      • 在模块加载过程中,JavaScript引擎会解析被导入的模块文件。对于像MyTreeTableWrapper这样的导入,它会查找模块内部定义的变量、函数、类等,并在模块环境记录中创建相应的引用。
    • 指针关系

      • 导入的模块实际上是通过引用(指针)来访问的。例如,当你在当前模块中使用MyTreeTableWrapper时,你并不是复制了整个MyTreeTableWrapper模块的内容到当前模块的内存空间,而是创建了一个指向被导入模块的指针。这个指针指向被导入模块的模块环境记录,这样当你访问MyTreeTableWrapper中的内容时,实际上是通过这个指针找到被导入模块中的相应定义。
    • 内存管理

      • 模块只被加载和解析一次,无论它被导入多少次。这意味着在内存中只有一份模块代码的实例。如果多个模块导入同一个模块,它们共享这个模块在内存中的实例,通过各自的模块环境记录中的引用来访问。这有助于节省内存,避免不必要的代码重复加载。
  2. 导出(Export)的内存模型及原理

    • 内存布局

      • 在定义模块(如MyTreeTableConstructor模块)时,当使用export关键字(例如export default MyTreeTableConstructor;),JavaScript会将被导出的内容标记为可被外部访问的。对于默认导出(default),它在模块内部是一个特殊的绑定。在模块的内存环境中,这个被导出的内容(这里是MyTreeTableConstructor函数)被存储在模块特定的内存区域。
    • 指针关系

      • 当模块被导出时,其他模块通过导入获取的是对这个导出内容的引用(指针)。以MyTreeTableConstructor为例,当其他模块导入这个函数时,它们得到的是一个指向MyTreeTableConstructor函数在其原模块内存中的指针。这使得在调用MyTreeTableConstructor时,实际上是在调用原始模块中定义的函数,而不是创建一个副本。
    • 内存管理

      • 被导出的内容在模块的生命周期内存在于模块的内存空间中。如果模块被卸载(在某些支持动态模块加载和卸载的环境中),相关的内存资源可能会被回收,但只要模块存在于内存中(例如在一个长期运行的应用程序中),其导出的内容就可供其他模块通过导入使用。

总的来说,JavaScript的导入和导出机制通过引用(指针)来管理模块间的交互,以提高内存使用效率并确保模块的独立性和可维护性。

// 创建一个类来作为MyTreeTable的构造函数
import {defineComponent, h} from "vue";
import TreeTable from "primevue/treetable";
import Column from "primevue/column";class MyTreeTableWrapper {constructor(properties) {// 创建一个新的MyTreeTable组件实例const MyTreeTableInstance = defineComponent({validProperties: ['mytreeData', 'property2', 'property3'],name: 'MyTreeTable',components: {TreeTable,Column},//在Vue 3的setup函数中,this是未定义的,因为setup函数是在组件实例被创建之前执行的,因此没有this上下文。setup() {// 接受外部的赋值let  non_TreetableData_object_param_list=[];let  treeData=[];const to_TransformData=()=> {treeData = transformData(non_TreetableData_object_param_list);};const transformData=  (data)=> {const transform = (arr, parentKey = '') => {return arr.map((item, index) => {const newKey = parentKey? `${parentKey}-${index}` : `${index}`;const newItem = {key: newKey,data: {id_cases: item.id_cases,id_param: item.id_param,object_Name: item.object_Name,type: item.type,desc: item.desc,is_object: item.is_object,required: item.required,rule: item.rule},children: item.children? transform(item.children, newKey) : []};return newItem;});};return transform(data);};const  displayNameBasedOnId= (typeId)=> {const typeMap = [{ name: "文本", id: 1 },{ name: "日期", id: 2 },{ name: "文本域", id: 3 },{ name: "数值", id: 4 },{ name: "文件", id: 5 },{ name: "限选项", id: 6 },{ name: "其他", id: 7 }];for (let i = 0; i < typeMap.length; i++) {if (typeMap[i].id === typeId) {return typeMap[i].name;}}return "未定义类型";};if (properties) {for (let prop in properties) {if (['mytreeData', 'property2', 'property3'].includes(prop)) {non_TreetableData_object_param_list = properties[prop];to_TransformData();}}}return () =>h(TreeTable, { value: treeData, tableStyle: 'min - width: 50rem' }, [h(Column, { field: 'object_Name', header: '分类名称', expander: true }),h(Column, { field: 'is_object', header: '分类类型' }),h(Column, { field: item => displayNameBasedOnId(item.type), header: '参数类型' }),h(Column, { field: 'required', header: '是否必须' }),h(Column, { field: 'desc', header: '描述' })]);}});return MyTreeTableInstance;}
}
export default MyTreeTableWrapper;

import MyTreeTableWrapper  from '@/service/prd/test/MyTreeTableWrapper.js';
// // 使用示例
const MyTreeTable1 = new MyTreeTableWrapper({mytreeData:PrdServiceFunCasesInputParameters.zwgetPrdServiceFunCasesInputParameters(),
});
    <Card><template #content><MyTreeTable2></MyTreeTable2></template></Card>
  1. 导入模块时的压栈顺序

    • 当执行import MyTreeTableWrapper from '@/service/prd/test/MyTreeTableWrapper.js';

      • 首先,JavaScript引擎会将MyTreeTableWrapper.js文件加载到内存中。这个过程涉及到文件系统的读取操作(如果是在浏览器环境下,可能是从服务器获取文件内容)。
      • 然后,开始解析文件内容。在解析MyTreeTableWrapper类的定义时,会将类的结构(包括构造函数、内部的方法等)压入执行上下文的解析栈中。对于其中的import语句(如import {defineComponent, h} from "vue";import TreeTable from "primevue/treetable";以及import Column from "primevue/column";),会先暂停当前文件的解析,去加载和解析被导入的模块。
      • import {defineComponent, h} from "vue"为例,引擎会查找vue模块(假设已安装并在模块查找路径内),加载并解析它,将defineComponenth函数的定义压入栈中(或者是创建引用指向它们在vue模块中的定义)。同样的过程也会发生在TreeTableColumn的导入过程中。
  2. 实例化类时的压栈顺序

    • 当执行const MyTreeTable1 = new MyTreeTableWrapper({mytreeData:PrdServiceFunCasesInputParameters.zwgetPrdServiceFunCasesInputParameters()});

      • 首先,会将MyTreeTableWrapper类的构造函数压入执行栈。在构造函数内部:
        • 当执行const MyTreeTableInstance = defineComponent({...})时,defineComponent函数被调用,它内部的逻辑开始执行,相关的函数定义(如setup函数内部定义的to_TransformDatatransformDatadisplayNameBasedOnId等)会被压入执行栈进行解析和执行。
        • setup函数中,当执行if (properties) {...}循环时,根据传入的属性进行操作。如果涉及到函数调用(如to_TransformData函数中的transformData函数调用),这些函数也会被压入执行栈。
        • setup函数中的return () => h(TreeTable, {...})语句执行时,h函数被调用,它内部的逻辑会被压入执行栈,包括对TreeTableColumn组件的渲染逻辑处理。
      • 最后,当MyTreeTableWrapper类的构造函数执行完毕,返回MyTreeTableInstance,这个结果被赋值给MyTreeTable1,此时相关的临时变量(如在构造函数内部定义的局部变量)会从执行栈中弹出,但MyTreeTable1会持有对返回结果的引用。

总体而言,代码的压栈顺序遵循JavaScript的模块加载、解析和函数调用的执行顺序,从外层的模块导入到内层的类实例化和组件构建相关的函数调用。


http://www.ppmy.cn/embedded/150217.html

相关文章

移动机器人推动制造业向自动化转升级

这位客户&#xff0c;作为一家制造业巨头&#xff0c;坐拥多个仓库及错综复杂的生产体系&#xff0c;在制造业智能化浪潮中勇立潮头&#xff0c;展现了非凡的数字化与智能化转型决心。 在启动智能化升级之初&#xff0c;客户进行了多方调研和比较&#xff0c;最终选择富唯智能…

新品:SA628F39大功率全双工音频传输模块

SA628F39是一款高集成度的8W大功率全双工无线数据语音一体通话模块&#xff0c;专为高效、稳定的远程通信设计。该模块内置高速微控制器、高性能射频芯片、功率放大器、ESD静电保护和硬件看门狗芯片&#xff0c;具备反接保护、过流过压保护和防死机保护等多重安全功能&#xff…

js高阶-ES6

let 和 const 声明&#xff1a;引入了块级作用域的变量声明方式&#xff0c;let 声明的变量只在其所在的块级作用域内有效&#xff0c;而 const 声明的变量是只读的。箭头函数&#xff1a;提供了更简洁的函数定义方式&#xff0c;并且自动绑定 this 上下文。模板字符串&#xf…

算法基础五:归并排序

一&#xff1a;定义&#xff1a; 归并排序算法是在分治算法基础上设计出来的一种排序算法&#xff0c;它可以对指定序列完成升序&#xff08;由小到大&#xff09;或降序&#xff08;由大到小&#xff09;排序。 二&#xff1a;基本思路 归并排序算法实现排序的思路是&#x…

zentao ubuntu上安装

#下载ZenTaoPMS-21.2-zbox_amd64.tar.gz&#xff08;https://www.zentao.net/downloads.html&#xff09; https://dl.zentao.net/zentao/21.2/ZenTaoPMS-21.2-zbox_amd64.tar.gzcd /opt tar -zxvf ZenTaoPMS-21.2-zbox_amd64.tar.gz#启动 /opt/zbox/zbox start /opt/zbox/zbox…

FreeACS:开源TR-069 ACS解决方案

FreeACS&#xff1a;开源TR-069 ACS解决方案 项目地址:https://gitcode.com/gh_mirrors/fr/freeacs 项目介绍 FreeACS是一款基于MIT许可证的开源TR-069 ACS&#xff08;自动配置服务器&#xff09;解决方案。作为市场上最完整的免费TR-069 ACS之一&#xff0c;FreeACS允许用…

【每日学点鸿蒙知识】子窗口方向、RichEdit不居中、本地资源缓存给web、Json转对象丢失方法、监听状态变量数组中内容改变

1、HarmonyOS 应用新建子窗口设置显示方向未生效&#xff1f; 子窗口getPreferredOrientation获取到的是横向 设置没问题&#xff0c;但是ui显示还是纵向的 直接设置主窗口的方向即可。参考demo&#xff1a; import window from ohos.window;Entry Component struct Index {…

基于 Paimon x Spark 采集分析半结构化 JSON 的优化实践

摘要&#xff1a;本文整理自 阿里巴巴 A 数据湖架构师康凯老师和 Paimon PMC Member 毕岩老师在11月15日 Apache Spark & Paimon Meetup&#xff0c;助力 Lakehouse 架构生产落地上的分享。 文章介绍了阿里巴巴 A 业务基于 Variant 类型的 JSON 链路优化&#xff0c;并从技…