代理模式容易和实践
#javascript #reactivity #proxypattern

代理对象可以在我们与对象进行交互时确定行为,例如,当我们获得值或设置值时。

我们有一个帐户对象,代表我的数据帐户:

const account = {
  name: "Julio",
  isPremium:false,
  isLogged: true
}

用户应该无法更改登录属性或服务类型或为任何属性分配空值。我们还必须检查用户是否试图访问不存在的对象的属性,如果是,请告知用户。在这里,使用代理是有意义的,这基本上是第二个对象,负责监视原始对象上的交互。像足球运动员或管理秘书一样。

我们希望与代理对象进行交互,而不是直接与此对象进行交互。在JavaScript中,我们可以通过创建代理的新实例来轻松创建一个新的代理。

const accountProxy = new Proxy(account, {});

代理的第二个参数是代表处理程序的对象。在处理程序对象中,我们可以根据交互的类型来定义特定行为。尽管您可以将许多方法添加到代理处理程序中,但两个最常见的方法是获取和设置:

获取:尝试访问属性时被调用
集:试图修改属性时被调用

我们将与AccountProxy进行交互,而不是直接与帐户对象进行交互。

我们向帐户proxy AccountProxy添加了两个处理程序。当我们尝试修改属性时,第一个,即设定器,将采取行动。通过在代理上调用集合方法,我们希望代理注册上一个值和属性的新值。第二个是getter,当访问属性时将起作用。当在代理上调用GET方法时,我们希望代理注册键和属性的价值,并通过日志告知我们。

const accountProxy = new Proxy(account, {
  get: (obj, prop) => {
    console.log(`The value of ${prop} is ${obj[prop]}`);
  },
  set: (obj, prop, value) => {
    console.log(`Changed ${prop} from ${obj[prop]} to ${value}`);
    obj[prop] = value;
  }
});
accountProxy.name // The value of name is Julio
accountProxy.isPremium = true // Changed isPremium from false to true

正如我们之前提到的,通过使用我们的代理我们要:

用户不应更改登录属性或服务类型
或为任何属性分配空值
并检查用户是否试图访问不存在的对象的属性,如果是,请告知用户

const account = {
  name: "Julio",
  isPremium:false,
  isLogged:true
}
const accountProxy = new Proxy(account, {
  get: (obj, prop) => {
    if (!obj[prop]) {
      console.log(
        `This property doesn't exist on the target object`
      );
    } else {
      console.log(`The value of ${prop} is ${obj[prop]}`);
    }
  },
  set: (obj, prop, value) => {
    if (prop === "name" && typeof value !== "string") {
      console.log(`You can only pass string values for name property.`);
    } else if (prop === "name" && !value.length) {
      console.log(`You need to provide a valid name.`);
    } else if(prop === "isPremium"  && typeof value === "boolean"){
      console.log(`You can't modify ${prop} from ${obj[prop]}`);
    }
    else if(prop === "isLogged"  && typeof value === "boolean"  ){
      console.log(`You can't modify ${prop} from ${obj[prop]}`);
    }
  }
});
accountProxy.name= "" // You need to provide a valid name
accountProxy.noExistProp // This property doesn't exist on the target object
accountProxy.isPremium = true // You can't modify isPremium from false

代理是增加对对象行为的控制的有力方法。代理可以具有各种用例:它可以帮助验证,格式化,通知或调试。

过度使用代理对象或在每个处理程序方法上执行重型操作很容易对应用程序的性能产生负面影响。最好不要将代理用于绩效至关重要的代码。

在此处,在Vue Mastery(与Evan You和Gregg Pollack)中查看this free video中,Vue 3如何实现代理模式以创建其反应性系统。很棒ð

希望您发现这篇文章有用。