【Object.defineProperty() | new Proxy()】操作Object

简介: 【Object.defineProperty() | new Proxy()】操作Object

Object.defineProperty(obj, prop, descriptor)

Object.defineProperty(obj, prop, descriptor) | 作用到 Vue2M-V-VM 数据绑定原理, Js底层方法,我们可以定义属性的特性(如可写、可枚举、可配置等),以及获取和设置属性值的行为.

  • obj:要定义属性的对象.
  • prop:要定义或修改的属性名.
  • descriptor:属性的描述符对象,用于定义属性的特性.
  • value:属性的值.
  • writable:属性是否可写(true 或 false).
  • enumerable:属性是否可枚举(true 或 false).
  • configurable:属性是否可配置(true 或 false).
  • get:获取属性值的函数,当属性被访问时调用.
  • set:设置属性值的函数,当属性被赋值时调用.
var obj = {};
Object.defineProperty(obj, 'name', {
  value: 'John',
  writable: false,
  enumerable: true,
  configurable: false
});
console.log(obj.name); // 输出: John
obj.name = 'Mike'; // 不会改变属性的值,因为 writable 特性为 false
console.log(obj.name); // 输出: John

Getter | Setter | Descriptor 搭配

var obj = {}; // 定义 obj
Object.defineProperty(obj, 'password', { // 被定义的属性
  enumerable: true, // 可以进行枚举操作
  configurable: true, // 可以进行配置
  get: function() { // getter 方法
    if (this.password) { // 如果设置了密码
      return this.password; // return
    } else { // 如果没有设置密码
      return "Password is not set"; // 返回 Password is not set
    }
  },
  set: function(value) { // setter 方法
    if (typeof value === 'string') { // 若设置的值为 String 类型
      this.password = value; // 赋值给 password
      this.passwordLastModified = new Date(); // 设置密码最后的修改时间
    } else { // 如果不为 String 类型
      console.log('Password must be a string'); // return err
    }
  }
});
obj.password = "newPassword123"; // 设置 string 密码
console.log(obj.password); // 输出: newPassword123
obj.password = 12345; // 输出: Password must be a string
for (var key in obj) {
  console.log(key); // 输出: password, passwordLastModified
}
delete obj.password; // 在 obj 中删除 password 属性
console.log(obj.password); // 输出: Password is not set

Proxy

new Proxy(target, handler) | 作用到 Vue3M-V-VM 数据绑定原理, ProxyES6 中引入的一个功能强大的对象,它允许你创建一个代理对象,以便你可以拦截并重定义对象的基本操作,例如访问属性、赋值、删除属性等.

  • target:要代理的目标对象.
  • handler:一个对象,其属性是用来定制代理行为的拦截器。拦截器是一组函数,用来定义在代理对象上对各种操作进行拦截和自定义处理的行为.
  • 🎐get(target, property, receiver):拦截属性的读取操作,可以定义在目标对象上访问属性时的自定义行为.
  • target:代理的目标对象,即被代理的对象.
  • property:被访问的属性名.
  • receiver:最初被调用的对象,通常是代理对象或继承代理对象的对象.
  • 🎐set(target, property, value, receiver):拦截属性的设置操作,可以定义在目标对象上设置属性时的自定义行为.
  • target:代理的目标对象,即被代理的对象.
  • property:被设置的属性名.
  • value:被设置的属性值.
  • receiver:最初被调用的对象,通常是代理对象或继承代理对象的对象.
  • 🎐apply(target, thisArg, argumentsList):拦截函数的调用操作,可以定义在目标对象上调用函数时的自定义行为.
  • target:代理的目标对象,即被代理的函数.
  • thisArg:被调用时的上下文对象.
  • argumentsList:一个类数组对象,表示传递给函数的参数列表.
  • 🎐construct(target, argumentsList, newTarget):拦截构造函数的调用操作,可以定义在目标对象上使用 new 操作符时的自定义行为
  • target:代理的目标对象,即被代理的构造函数.
  • argumentsList:一个类数组对象,表示传递给构造函数的参数列表.
  • newTarget:最初被调用的构造函数.
  • 🎐has(target, property):拦截 in 操作符,可以定义在目标对象上使用 in 操作符时的自定义行为.
  • target:代理的目标对象,即被代理的对象.
  • property:检查是否存在的属性名.
  • 🎐deleteProperty(target, property):拦截 delete 操作符,可以定义在目标对象上使用 delete 操作符时的自定义行为.
  • target:代理的目标对象,即被代理的对象.
  • property:被删除的属性名.
  • 🎐getOwnPropertyDescriptor(target, property):拦截 Object.getOwnPropertyDescriptor() 操作,可以定义在目标对象上获取属性描述符时的自定义行为.
  • target:代理的目标对象,即被代理的对象.
  • property:被删除的属性名.
// 创建一个简单的对象
let target = {
  message: "Hello"
};
// 创建一个 Proxy 对象
let proxy = new Proxy(target, {
  get: function(target, property, receiver) {
    console.log(`正在访问属性: ${property}`);
    return target[property];
  },
  set: function(target, property, value, receiver) {
    console.log(`正在设置属性: ${property} 值为: ${value}`);
    target[property] = value;
    return true;
  }
});
// 通过 Proxy 对象访问和设置属性
console.log(proxy.message); // 访问属性: message 输出: Hello
proxy.message = "World"; // 设置属性: message 值为: World
console.log(proxy.message); // 访问属性: message 输出: World

Getter | Setter | Apply

const calculator = {
  add: function(a, b) {
    return a + b;
  },
  subtract: function(a, b) {
    return a - b;
  },
  multiply: function(a, b) {
    return a * b;
  },
  divide: function(a, b) {
    return a / b;
  }
};
const calculatorProxy = new Proxy(calculator, {
  get(target, property, receiver) {
    console.log("访问属性:", property);
    return target[property];
  },
  set(target, property, value, receiver) {
    console.log("设置属性:", property, " 值:", value);
    if (typeof value !== "number") {
      throw new TypeError("属性值必须为数字");
    }
    target[property] = value;
  },
  apply(target, thisArg, argumentsList) {
    console.log("调用函数:", target.name);
    return target.apply(thisArg, argumentsList);
  }
});
console.log(calculatorProxy.add(2, 3)); // 输出 "调用函数: add" 和结果 "5"
calculatorProxy.multiply = 10; // 输出 "设置属性: multiply 值: 10"
console.log(calculatorProxy.multiply); // 输出 "访问属性: multiply" 和结果 "10"
相关文章
|
10月前
|
JavaScript 前端开发
JavaScript 使用对象字面量创建对象、使用new Object创建对象
JavaScript 使用对象字面量创建对象、使用new Object创建对象
81 0
|
1月前
|
JavaScript 前端开发
为什么要替换 Object.defineProperty?(Proxy 相比于 defineProperty 的优势)
为什么要替换 Object.defineProperty?(Proxy 相比于 defineProperty 的优势)
50 0
|
监控 JavaScript 索引
深入理解vue2.x中Object.defineproperty()和vue3.x中Proxy
深入理解vue2.x中Object.defineproperty()和vue3.x中Proxy
162 0
深入理解vue2.x中Object.defineproperty()和vue3.x中Proxy
|
10月前
玩转ES6(二)-Object.defineProperty和Proxy代理
玩转ES6(二)-Object.defineProperty和Proxy代理
72 0
|
11月前
|
JavaScript 前端开发
02-vue源码分析之 vue3.0为何弃用Object.defineProperty而选择Proxy
02-vue源码分析之 vue3.0为何弃用Object.defineProperty而选择Proxy
65 0
|
人工智能 编解码 自动驾驶
YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors
YOLOv7在5 FPS到160 FPS的范围内,在速度和精度方面都超过了所有已知的物体检测器,在GPU V100上以30 FPS或更高的速度在所有已知的实时物体检测器中具有最高的精度56.8% AP。
390 0
|
存储 Java
【Deprecated】Java | Object obj = new Object()占用多少字节?
【Deprecated】Java | Object obj = new Object()占用多少字节?
106 0
【Deprecated】Java | Object obj = new Object()占用多少字节?
|
数据挖掘 大数据 索引
Pandas数据分析:处理文本数据(str/object)各类操作+代码一文详解(三)
Pandas数据分析:处理文本数据(str/object)各类操作+代码一文详解(三)
212 0
Pandas数据分析:处理文本数据(str/object)各类操作+代码一文详解(三)
|
数据挖掘 大数据 测试技术
Pandas数据分析:处理文本数据(str/object)各类操作+代码一文详解(二)
Pandas数据分析:处理文本数据(str/object)各类操作+代码一文详解(二)
188 0
Pandas数据分析:处理文本数据(str/object)各类操作+代码一文详解(二)