(翻译)使用javascript中的proxy(代理)

463 阅读1分钟

我最近一直在研究javascript中的proxy,我对它的能力感到惊讶。Proxy允许你改变语言的基本结构(像objectarraysfunctions..)

下面是使用javascript代理的几个例子。

对象冻结

我们可以使用几行简单的代码来阻止对对象的改变操作,这本质上是冻结对象

 const hero = {
   name: 'Saitama',
   age: 25,
   class: 'B',
   race: 'Human',
   heroName: 'Caped Baldy',
 };

 const Freeze = obj =>
   new Proxy(obj, {
     set: function(target, key, value) {
       throw Error("You can't change values this object has been frozen");
     },
   });

 const saitama = Freeze(hero);
 saitama.name = 'Garuro';   // This will throw error

你也可以冻结arraysMapWeakMapSet

追踪对象变化

Proxy能改追踪对象的变化,这本质上是维护历史记录

 const createHistory = obj => {
   let history = [JSON.parse(JSON.stringify(obj))];
   const proxiedObject = new Proxy(obj, {
     set: function(target, key, value) {
       history.push({ ...target, [key]: value });
       Reflect.set(target, key, value);
     },
   });
   return [history, proxiedObject];
 };

 const [history, proxiedObject] = createHistory(hero);
 proxiedObject.name = 'Genos';
 proxiedObject.class = 'C';

 console.log(history);

历史对象将包含对对象所做更改的快照

 [
   {
     name: 'Saitama',
     age: 25,
     class: 'B',
     race: 'Human',
     heroName: 'Caped Baldy'
   },
   {
     name: 'Genos',
     age: 25,
     class: 'B',
     race: 'Human',
     heroName: 'Caped Baldy'
   },
   {
     name: 'Genos',
     age: 25,
     class: 'C',
     race: 'Human',
     heroName: 'Caped Baldy'
   }
 ]

同样,你也可以跟踪函数被应用触发器调用的次数

不区分大小写的属性访问

const caseInsensitive = obj =>
   new Proxy(obj, {
     get: function(target, key) {
       // 为了简单起见,我假设属性的键值默认为小写
       return Reflect.get(target, key.toLowerCase());
     },
   });

 const proxiedObject = caseInsensitive(hero);
 console.log(proxiedObject.name); // saitama
 console.log(proxiedObject.NAME); // saitama

处理不存在的属性

你可以通过下面的代码轻松的处理未定义的属性

 const FetchValue = obj =>
   new Proxy(obj, {
     get: function(target, key) {
       if (target.hasOwnProperty(key)) {
         return [Reflect.get(target, key), true];
       }
       return [null, false];
     },
   });


 const proxiedObject = FetchValue(hero);

 const [name, nameExist] = proxiedObject.name;
 const [city, cityExist] = proxiedObject.city;

 if (nameExist) {
   console.log(name);
 }

 if (cityExist) {
   console.log(city); //因为city属性不存在,所以不执行
 }

更多的使用Proxy的例子在这个,你可以找到更多很棒的用法 github.com/mikaelbr/aw…

原文链接

Using javascript proxy