【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"
相关文章
|
1月前
|
设计模式 JavaScript 前端开发
js中new和object.creat区别
【10月更文挑战第29天】`new` 关键字和 `Object.create()` 方法在创建对象的方式、原型链继承、属性初始化以及适用场景等方面都存在差异。在实际开发中,需要根据具体的需求和设计模式来选择合适的方法来创建对象。
|
1月前
|
设计模式
在实际开发中,什么时候应该使用 `new` 关键字,什么时候应该使用 `Object.create()` 方法?
【10月更文挑战第29天】`new` 关键字适用于创建具有特定类型和初始化逻辑的对象实例,以及实现基于原型链的继承;而 `Object.create()` 方法则适用于基于现有对象创建相似对象、避免构造函数的副作用、创建具有特定原型链的对象等场景。在实际开发中,需要根据具体的需求和设计模式来选择合适的方法来创建对象,以实现更高效、更灵活的代码结构。
|
2月前
|
JavaScript 前端开发 UED
为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty
Vue 3.0 采用 Proxy 替代 Object.defineProperty,主要因为 Proxy 提供了更全面、高效的数据拦截能力,支持对更多操作进行拦截和自定义处理,同时减少了对对象的限制,提升了框架性能和开发体验。
|
4月前
|
JavaScript 前端开发 开发者
Vue.js 响应式变革来袭!结合热点技术,探索从 Object.defineProperty 到 Proxy 的奇妙之旅,触动你的心
【8月更文挑战第30天】在 Vue.js 中,响应式系统自动追踪并更新数据变化,极大提升了开发体验。早期通过 `Object.defineProperty` 实现,但存在对新旧属性处理及数组操作的局限。Vue 3.0 引入了 `Proxy`,克服了上述限制,提供了更强大的功能和更好的性能。实践中,可根据项目需求选择合适的技术方案,并优化数据操作,利用懒加载等方式提升性能。
48 0
|
5月前
|
存储 算法 Java
Object o = new Object()在内存中占几个字节
Object o = new Object()在内存中占几个字节
|
7月前
|
缓存 前端开发 JavaScript
理解 Proxy 和 Object.defineProperty:提升你的 JavaScript 技能(下)
理解 Proxy 和 Object.defineProperty:提升你的 JavaScript 技能(下)
理解 Proxy 和 Object.defineProperty:提升你的 JavaScript 技能(下)
|
7月前
|
JavaScript 前端开发 测试技术
理解 Proxy 和 Object.defineProperty:提升你的 JavaScript 技能(上)
理解 Proxy 和 Object.defineProperty:提升你的 JavaScript 技能(上)
理解 Proxy 和 Object.defineProperty:提升你的 JavaScript 技能(上)
|
7月前
|
JavaScript 前端开发 测试技术
Proxy vs Object.defineProperty:哪种对象拦截机制更适合你?
Proxy vs Object.defineProperty:哪种对象拦截机制更适合你?
|
7月前
|
JavaScript 前端开发 数据安全/隐私保护
Proxy 与 Object.defineProperty 优劣对比
Proxy 与 Object.defineProperty 优劣对比
164 0
|
7月前
|
JavaScript 数据安全/隐私保护 开发者
常见的vue面试中的proxy和object.defineProperty的区别
常见的vue面试中的proxy和object.defineProperty的区别
下一篇
DataWorks