Object.defineProperty(obj, prop, descriptor)
Object.defineProperty(obj, prop, descriptor)
| 作用到Vue2
M-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)
| 作用到Vue3
M-V-VM 数据绑定原理
,Proxy
是ES6
中引入的一个功能强大的对象,它允许你创建一个代理对象,以便你可以拦截并重定义对象的基本操作,例如访问属性、赋值、删除属性等.
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"