在一些javascript实现中有一个noSuchMethod功能(Rhino,SpiderMonkey)
proxy = {
__noSuchMethod__: function(methodName, args){
return "The " + methodName + " method isn't implemented yet. HINT: I accept cash and beer bribes" ;
},
realMethod: function(){
return "implemented" ;
}
}
js> proxy.realMethod()
implemented
js> proxy.newIPod()
The newIPod method isn't implemented yet. HINT: I accept cash and beer bribes
js>
Run Code Online (Sandbox Code Playgroud)
我想知道,有没有办法为房产做类似的事情?我想编写可以在属性和方法上分派的代理类.
CMS*_*CMS 61
目前只有一个现有的东西可以实际上做你想要的,但不幸的是没有广泛实施:
目前只有两种可用的实现方式,最新的Firefox 4测试版(自FF3.7预发布以来一直存在)和服务器端JavaScript的节点代理 - Chrome和Safari目前正在开发它 - .
这是一个早期的提案为ECMAScript中的下一个版本,它是可以让你实现API 虚拟化的对象(代理),您可分配各种陷阱 -callbacks-,在不同的情况下被执行,你得到完全控制在这个时候 - 在ECMAScript 3/5只有主机对象可以做.
要建立一个代理对象,你必须使用的Proxy.create
方法,因为你有兴趣在set
和get
陷阱,我离开你一个非常简单的例子:
var p = Proxy.create({
get: function(proxy, name) { // intercepts property access
return 'Hello, '+ name;
},
set: function(proxy, name, value) { // intercepts property assignments
alert(name +'='+ value);
return true;
}
});
alert(p.world); // alerts 'Hello, world'
p.foo = 'bar'; // alerts foo=bar
Run Code Online (Sandbox Code Playgroud)
Proxy API是如此新颖,甚至没有在Mozilla开发人员中心记录,但正如我所说,自Firefox 3.7预发行版以来已经包含了一个有效的实现.
该Proxy
对象在全局范围内可用,并且该create
方法可以采用两个参数,一个handler
对象,它只是一个包含名称为要实现的陷阱的属性的对象,以及一个可选proto
参数,使您能够指定一个对象.你的代理继承自.
可用的陷阱是:
// TrapName(args) Triggered by
// Fundamental traps
getOwnPropertyDescriptor(name): // Object.getOwnPropertyDescriptor(proxy, name)
getPropertyDescriptor(name): // Object.getPropertyDescriptor(proxy, name) [currently inexistent in ES5]
defineProperty(name, propertyDescriptor): // Object.defineProperty(proxy,name,pd)
getOwnPropertyNames(): // Object.getOwnPropertyNames(proxy)
getPropertyNames(): // Object.getPropertyNames(proxy)
delete(name): // delete proxy.name
enumerate(): // for (name in proxy)
fix(): // Object.{freeze|seal|preventExtensions}(proxy)
// Derived traps
has(name): // name in proxy
hasOwn(name): // ({}).hasOwnProperty.call(proxy, name)
get(receiver, name): // receiver.name
set(receiver, name, val): // receiver.name = val
keys(): // Object.keys(proxy)
Run Code Online (Sandbox Code Playgroud)
除了提案之外,我见过的唯一资源是以下教程:
编辑:更多信息即将发布,Brendan Eich最近在JSConf.eu会议上发表了演讲,你可以在这里找到他的幻灯片:
以下是如何获得类似于__noSuchMethod__的行为
首先,这是一个简单的对象,有一个方法:
var myObject = {
existingMethod: function (param) {
console.log('existing method was called', param);
}
}
Run Code Online (Sandbox Code Playgroud)
现在创建一个Proxy,它将捕获对属性/方法的访问权限,并将现有对象添加为第一个参数.
var myObjectProxy = new Proxy(myObject, {
get: function (func, name) {
// if property or method exists, return it
if( name in myObject ) {
return myObject[name];
}
// if it doesn't exists handle non-existing name however you choose
return function (args) {
console.log(name, args);
}
}
});
Run Code Online (Sandbox Code Playgroud)
现在尝试一下:
myObjectProxy.existingMethod('was called here');
myObjectProxy.nonExistingMethod('with a parameter');
Run Code Online (Sandbox Code Playgroud)
适用于Chrome/Firefox/Opera.在IE中不起作用(但已经在Edge中工作).还在移动Chrome上测试过.
代理的创建可以是自动化的,也是不可见的,即如果使用Factory模式来构建对象.我这样做是为了创建可以直接从主线程调用内部函数的worker.由于这个名为Proxy的酷炫新功能,使用工作人员现在可以如此简单.有史以来最简单的工人实施:
var testWorker = createWorker('pathTo/testWorker.js');
testWorker.aFunctionInsideWorker(params, function (result) {
console.log('results from worker: ', result);
});
Run Code Online (Sandbox Code Playgroud)