JavaScript语言教程

使用Javascript ES6的Proxy实现元编程

  使用ecmascript6 中的Proxy可以实现元编程,以以前不可能的方式定义JS对象,下面是Mozilla的一个小案例:

var proxy;

 

var handler = { 

    has: function (name) {

        return name == 'foo';

    },

    get: function (rcvr, name) {

        if (name != 'foo')

            return undefined;

        print(proxy !== rcvr);

        return "bye";

    },

};

 

proxy = Proxy.create(handler);

 

var c = Object.create(proxy);

 

print(c.foo); // prints: 'true' (from "proxy !== rcvr") and 'bye' (from "c.foo"). 

// In this example, the get trap rcvr argument is the c object while proxy is its prototype

如果你熟悉Java,这非常类似Java中的动态代理模式,Spring的AOP/IOC框架都是基于动态代理实现的在这个案例我们得到的c这个对象其实是原来真正c原型对象的代理,并不不是真正的c对象,是一个代理人,原型和代理人之间关系类似明星和经纪人之间关系,具体可参考代理模式

Pipe实现

我们可以使用Proxy实现很酷的Pipe管道化:

var pipe = (function () {

 

    var pipe;

 

    return function (value) {

        pipe = [];

        return Object.create(Proxy.create({

            get: function (pipeObject, fnName) {

                if (fnName == "get")

                    return pipe.reduce(function (val, fn) { return fn(val); }, value);

 

                pipe.push(window[fnName]);

                return pipeObject;

            }

        }));

    }

}());

 

var double        = function (n) { return n*2 }, 

    pow           = function (n) { return n*n },

    reverseInt    = function (n) { return n.toString().split('').reverse().join('')|0 };

 

 

var pipedExample = pipe(3) . double . pow . reverseInt . get 

console.log(pipedExample); //63 

注意倒数第二行pipedExample的赋值方式,是不是很像一个个水管衔接在一起呢?

 

查询代理

使用代理Proxy我们能创建一个查询代理,如果过滤语法,可以过滤从仓储查询的JSON:

var ChristmasList = Repository([

 

    {

        name: "Daniel",

        age: 12,

        wants: "a dog",

    },

 

 

    {

        name: "Julia",

        age: 8,

        wants: "a bottle of rum"

    },

 

 

    {

        name: "Vitaly",

        age: Infinity,

        wants: "a dog"

    },

 

    {

        name: "Ina",

        age: 20,

        wants: "Vitaly"

    }

]);

 

 

ChristmasList.wants['a dog'].get; // [ {age: 12, name: "Daniel",wants: "a dog"}, {age: Infinity, name: "Vitaly", wants: "a dog"} ] 

ChristmasList.age['<']['12'].get; // {name: "Julia", age: 8, wants: "a bottle of rum"} 

ChristmasList.wants['a dog'].age[">"]["12"].get; // {name: "Vitaly", age: Infinity, wants: "a dog"}; 

ChristmasList.wants[ 

    ChristmasList.wants['a dog'].age[">"]["12"].get.name

].get // {name: "Ina", age: 20, wants: "Vitaly"}

更多Cool的Proxy应用见:Github repository. 

学习Javascript ES6几个重要特性

NodeJs入门之事件驱动