zoukankan      html  css  js  c++  java
  • ECMAScript 6 proxies

    在ECMAScript 5里面,可以通过(writable 和 configurable)内部属性把属性设置为不可修改和不可删除的,可以通过(Object.preventExtensions() )让对象不允许被拓展新的属性,可以通过(Object.freeze())让对象的所有属性变为只读和不可删除的,同时也不能添加新属性,或者(Object.seal() )等。

     
    "use strict";
    var person = {
        name: "Nicholas"
    };
    Object.seal(person);
    person.age = 20;    // Error!
     
    上面的代码会触发错误,因为对象被密封了,不允许添加新属性
    但是在非strict模式下,不会出现错误提示,即使属性无法添加,也不会有任何提示(通常访问不存在的对象属性只会返回undefined),这就会在调试上带来麻烦
     
    当读从对象读取一个属性值的时候,会触发一个内部的[[Get]]操作来获取属性值,这是一个内部的不可改变的行为,但是通过 proxies 可以拦截javascript engine对[[Get]]的调用,转而调用自定义的函数
    var proxy = new Proxy({ name: "Nicholas" }, {
        get: function(target, property) {
            if (property in target) {
                return target[property];
            } else {
                return 35;
            }
        }
    });
     
    console.log(proxy.time);        // 35
    console.log(proxy.name);        // "Nicholas"
    console.log(proxy.title);       // 35
     
    改造一下便可以成为一个让对象不存在属性被访问时触发错误的函数
    function createDefensiveObject(target) {
        return new Proxy(target, {
            get: function(target, property) {
                if (property in target) {
                    return target[property];
                } else {
                    throw new ReferenceError("Property "" + property + "" does not exist.");
                }
            }
        });
    }
     
    使用方式: 
    var person = {
        name: "Nicholas"
    };
     
    var defensivePerson = createDefensiveObject(person);
     
    console.log(defensivePerson.name);        // "Nicholas"
    console.log(defensivePerson.age);         // Error!
     
    其他常规操作不受影响
    defensivePerson.age = 13;
    console.log(defensivePerson.age);         // 13
    console.log("name" in defensivePerson);               // true
    console.log(defensivePerson.hasOwnProperty("name"));  // true
     
     
    通过对设置内部[[Set]],可以让属性添加的时候判断类型
    function createTypeSafeObject(object) {
     
        return new Proxy(object, {
              set: function(target, property, value) {
                  var currentType = typeof target[property],
                       newType = typeof value;
     
                  if (property in target && currentType !== newType) {
                      throw new Error("Property " + property + " must be a " + currentType + ".");
                  } else {
                      target[property] = value;
                  }
              }
        });
    }
     
    上面两个方法都可以安全用到构造函数里面,因为proxies是透明的,不影响其他代码
    function Person(name) {
        this.name = name;
        return createTypeSafeObject(this);
    }
     
    var person = new Person("Nicholas");
     
    console.log(person instanceof Person);    // true
    console.log(person.name);                 // "Nicholas"
  • 相关阅读:
    23种设计模式之外观模式
    HashMap系列之底层数据结构
    HashMap系列之基本概念
    轻松搞定荷兰国旗问题
    服务治理:Spring Cloud Eureka
    Spring Cloud简介
    简单了解什么是微服务架构
    字符串和时间
    调用shell命令
    s3操作
  • 原文地址:https://www.cnblogs.com/chuangweili/p/5165976.html
Copyright © 2011-2022 走看看