虽然尚未最终确定,但我正在尝试使用 ES6 代理。我的目标是拥有一个构造函数(一个利用如下所示的经典继承的函数)来创建具有继承链的代理对象。
function inherit(child, parent){ //a classical inheritance pattern
var F = function(){};
F.prototype = parent.prototype;
child.prototype = new F();
child.parent = parent.prototype;
child.prototype.constructor = child;
return child;
}
以下看起来合理吗?我创建一个项目并从构造函数返回代理。任何将返回对实例的引用(出于链接目的)的方法都必须返回对代理的引用,否则在链接时我们会丢失代理。
function Item(attrs){
this.attrs = attrs;
var proto = this.constructor.prototype;
return this.proxy = Proxy.create(new MyHandler(this), proto);
}
Item.prototype.setStatus = function(status){
//do work
return this.proxy; //we do this everywhere instead of a simple 'this'?
}
function DVD(attrs){
attrs.type = 'DVD';
return Item.call(this, attrs);
}
inherit(DVD, Item);
var negotiator = new DVD({title: 'The Negotiator'}); //returns proxy
目标是构造可能是经典继承链产物的代理对象(通过'new'关键字)。
下一期。考虑一下如果我用 Backbone.Events 扩展我的 Item 原型会发生什么。那些导入的方法将返回this
而不是this.proxy
. 为了解决这个问题,我必须包装所有返回的导入方法this
以便返回proxy
。这似乎很痛苦且容易出错。使用 Proxy 抽象涉及大量布线,这对我来说似乎不太正确。
虽然我喜欢代理概念,但我关心它的实用性。也许我错过了一些更好的实践来实现我的目标?
编辑:
这个例子过于简单,因此无法描述我为什么需要它。
最终,我使用代理的目标是允许多重继承。我希望能够将多个行为(模块)混合到给定的代理对象中。我还希望能够简单地随心所欲地分解行为。
通过使用代理,我可以让 Proxy 对象管理对方法的访问,并根据需要将信息传递给 mixins。基本上,这允许改进面向方面的编程。对于一个方面,我通常会包装和替换一个函数。有时,给定的方法会被多个方面包装和重新包装。AOP 的问题在于,一旦您以这种方式修改了一个对象,就很难仅删除一个方面,因为该方面可能已被重新包装所掩埋。
代理不会遇到这个问题。你的 mixin 可以改为放在一个数组中。代理处理对这些 mixin 中的方法的分派(甚至是多个方法,因此是多重继承)。然后,取消混合行为就像从该数组中删除一个 mixin 一样简单。
代理的问题在于,虽然方法返回对对象本身的引用是一种常见做法(出于链接目的),但您并不真正希望任何原始方法返回对该对象的引用(因此绕过代理),您希望返回代理。