深入理解 Proxy 和 Object.defineProperty

在JavaScript中,对象是一种核心的数据结构,而对对象的操作也是开发中经常遇到的任务。在这个过程中,我们经常会使用到两个重要的特性:ProxyObject.defineProperty。这两者都允许我们在对象上进行拦截和自定义操作,但它们在实现方式、应用场景和灵活性等方面存在一些显著的区别。本文将深入比较ProxyObject.defineProperty,包括它们的基本概念、使用示例以及适用场景,以帮助读者更好地理解和运用这两个特性。

1. Object.defineProperty

1.1 基本概念

Object.defineProperty 是 ECMAScript 5 引入的一个方法,用于直接在对象上定义新属性或修改已有属性。它的基本语法如下:

javascript 代码解读复制代码Object.defineProperty(obj, prop, descriptor);

其中,obj是目标对象,prop是要定义或修改的属性名,descriptor是一个描述符对象,用于定义属性的特性。

1.2 使用示例

javascript 代码解读复制代码// 定义一个简单的对象


const person = {};

// 使用 Object.defineProperty 定义属性 'name'
Object.defineProperty(person, 'name', {
  value: 'John',
  writable: true,
  enumerable: true,
  configurable: true,
});

console.log(person.name); // 输出: John

// 尝试修改 'name' 属性
person.name = 'Doe';

console.log(person.name); // 输出: Doe

在上面的示例中,我们使用Object.defineProperty定义了一个名为name的属性,并设置了该属性的值、可写性、可枚举性和可配置性。

2. Proxy

2.1 基本概念

Proxy 是 ECMAScript 6 引入的一个对象,它允许我们创建一个代理对象,用来拦截对目标对象的各种操作。Proxy的基本语法如下:

javascript 代码解读复制代码const proxy = new Proxy(target, handler);

其中,target是目标对象,handler是一个用于定制代理行为的对象。

2.2 使用示例

javascript 代码解读复制代码// 定义一个简单的对象


const person = {
  name: 'John',
  age: 30,
};

// 创建一个 Proxy 对象
const personProxy = new Proxy(person, {
  get(target, prop) {
    console.log(`Getting ${prop}`);
    return target[prop];
  },
  set(target, prop, value) {
    console.log(`Setting ${prop} to ${value}`);
    target[prop] = value;
  },
});

console.log(personProxy.name); // 输出: Getting name

personProxy.age = 31; // 输出: Setting age to 31


在上面的示例中,我们通过Proxy对象创建了一个代理对象personProxy,并通过getset拦截器实现了对目标对象person的属性访问和修改的监控。

3. 区别与比较

3.1 实现方式

  • Object.defineProperty: 它是通过直接在对象上定义或修改属性的方式实现的,属于静态定义。
  • Proxy: 它是通过创建一个代理对象,在这个代理对象上设置拦截器来实现的,属于动态代理。

3.2 支持的操作

  • Object.defineProperty: 主要用于单个属性的定义和修改,支持的拦截点有限。
  • Proxy: 支持对目标对象的各种操作进行拦截,包括属性的读取、设置、删除、枚举等。

3.3 应用场景

  • Object.defineProperty: 适用于对已有对象进行属性的定义或修改,适合静态场景。
  • Proxy: 适用于对对象进行动态代理,对目标对象的操作进行灵活控制,适合需要更多自定义行为的场景。

3.4 性能

  • Object.defineProperty: 在大规模应用时,由于是静态定义,性能相对较好。
  • Proxy: 由于是动态代理,可能存在一些性能开销,但在一些场景下能够提供更灵活的操作。

4. 结语

在实际开发中,选择使用Proxy还是Object.defineProperty取决于具体的需求。如果只需要对对象的属性进行简单的定义或修改,且不需要过多的自定义行为,可以选择使用Object.defineProperty。而如果需要更灵活、更强大的拦截和代理能力,以及对对象操作的细粒度控制,那么Proxy则是更好的选择。在使用时,根据项目需求权衡它们的优缺点,选择更合适的工具来提高开发效率和代码质量。

Read more

使用本地大模型调用代码,根本就是一场骗局!

使用本地大模型调用代码,根本就是一场骗局!

通过大模型调用其他工具到底可不可行?ChatGPT 或许能轻松搞定一切,但同样的需求落在本地大模型上,恐怕就要打个问号了。 法国开发工程师 Emilien Lancelot 尝试了多款号称具备工具调用功能的 agent 框架,来看看本地大模型到底能不能完成任务,但结果就像他总结的“一无所获”。是什么让这位工程师失望了? 用 AutoGPT,得会点“糊弄学” AutoGPT 是款貌似强大的框架,提供很酷的 CLI 外加 Flutter UI,能够通过浏览器创建 agent。其主要功能是处理用户的文档、音频、视频等本地内容。 但是……它主要依靠 ChatGPT 或其他专有大模型服务来完成繁重工作,至少给我们的感觉是如此。 我们必须“唬弄”AutoGPT 才能使用 Ollama 端点,让其误认为是 ChatGPT。 ## OPENAI_API_KEY - OpenAI API

By Ne0inhk
详细说明Encoder-only架构的特点以及他和encoder decoder的区别和联系

详细说明Encoder-only架构的特点以及他和encoder decoder的区别和联系

Poe Encoder-only 架构的特点 Encoder-only 模型只使用 Transformer 的编码器部分,专注于对输入序列的理解和表征学习。这类模型通常被用在需要对输入文本进行深度理解的任务上,如文本分类、问答和语义匹配。以下是 Encoder-only 架构的核心特点: 1. 双向上下文建模 * 特点:Encoder-only 模型通过自注意力机制(Self-Attention)同时关注输入序列的前后文。 * 优势:相比单向模型(如 Decoder-only),它可以更全面地捕捉输入序列的全局语义,适合需要理解复杂上下文的任务。 * 实现方式:在训练过程中,不对输入序列进行因果掩码(Causal Masking),允许模型在任何位置访问序列的所有位置。 * 例子:BERT 的 Masked Language Model(MLM)训练任务通过随机遮盖部分单词,依赖左侧和右侧的信息来预测被遮盖的词,即双向建模的典型体现。 2. 适用于理解任务 * 特点:Encoder-only 模型专注于理解输入序列,而不生成输出序列,因此适合处理分类、

By Ne0inhk
手把手教学,DeepSeek-R1微调全流程拆解

手把手教学,DeepSeek-R1微调全流程拆解

手把手教学,DeepSeek-R1微调全流程拆解 原创 极客见识  2025年02月09日 09:02 广东 DeepSeek 通过发布其开源推理模型 DeepSeek-R1 颠覆了 AI 格局,该模型使用创新的强化学习技术,以极低的成本提供与 OpenAI 的 o1 相当的性能。 更令人印象深刻的是,DeepSeek 已将其推理能力提炼成几个较小的模型。这篇文章,我们将使用其蒸馏版本之一引导大家完成 DeepSeek-R1 的整个微调过程。 本文章将演示了如何微调其中一个模型(使用我们自己的自定义思维链数据集),然后保存和部署微调后的模型。 高级推理模型微调 DeepSeek 简介 DeepSeek-R1 是由深度求索(DeepSeek)公司开发的突破性推理模型。DeepSeek-R1 基于 DeepSeek-V3-Base(总共 671B 个参数,每次推理 37B 处于活动状态)构建,使用强化学习 (RL) 在提供最终答案之前生成思路链

By Ne0inhk