use*_*291 48 javascript ruby metaprogramming
在Ruby中,我认为你可以调用一个尚未定义的方法,并捕获被调用方法的名称,并在运行时处理此方法.
Javascript可以做同样的事情吗?
Luc*_*lho 44
method_missing不适合JavaScript,因为它在Python中不存在:在两种语言中,方法只是恰好是函数的属性; 和对象通常具有不可调用的公共属性.与Ruby对比,其中对象的公共接口是100%方法.
JavaScript中需要一个钩子来捕获对缺失属性的访问,无论它们是否是方法.Python有它:看__getattr__特殊方法.
Mozilla 的__noSuchMethod__提议引入了另一种与它们混杂的语言的不一致性.
JavaScript的前进方向是代理机制(也在ECMAscript Harmony中),它更接近于用于自定义属性访问的Python协议,而不是Ruby的method_missing.
lmm*_*des 28
您正在解释的ruby功能称为"method_missing" http://rubylearning.com/satishtalim/ruby_method_missing.htm.
这是一个全新的功能,仅在某些浏览器中出现,如Firefox(在蜘蛛猴Javascript引擎中).在SpiderMonkey中,它被称为"__noSuchMethod__" https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/NoSuchMethod
请阅读Yehuda Katz的这篇文章http://yehudakatz.com/2008/08/18/method_missing-in-javascript/,了解即将实施的更多细节.
您可以使用Proxy类。
var myObj = {
someAttr: 'foo'
};
var p = new Proxy(myObj, {
get: function (target, methodOrAttributeName) {
// target is the first argument passed into new Proxy, aka. target is myObj
// First give the target a chance to handle it
if (Object.keys(target).indexOf(methodOrAttributeName) !== -1) {
return target[methodOrAttributeName];
}
// If the target did not have the method/attribute return whatever we want
// Explicitly handle certain cases
if (methodOrAttributeName === 'specialPants') {
return 'trousers';
}
// return our generic method_missing function
return function () {
// Use the special "arguments" object to access a variable number arguments
return 'For show, myObj.someAttr="' + target.someAttr + '" and "'
+ methodOrAttributeName + '" called with: ['
+ Array.prototype.slice.call(arguments).join(',') + ']';
}
}
});
console.log(p.specialPants);
// outputs: trousers
console.log(p.unknownMethod('hi', 'bye', 'ok'));
// outputs:
// For show, myObj.someAttr="foo" and "unknownMethod" called with: [hi,bye,ok]
Run Code Online (Sandbox Code Playgroud)
您将使用p代替myObj.
您应该小心,get因为它会拦截p. 因此,p.specialPants()会导致错误,因为specialPants返回字符串而不是函数。
真正发生的事情unknownMethod相当于以下内容:
var unk = p.unkownMethod;
unk('hi', 'bye', 'ok');
Run Code Online (Sandbox Code Playgroud)
这是可行的,因为函数是 javascript 中的对象。
如果您知道所需的参数数量,则可以在返回的函数中正常声明它们。
例如:
...
get: function (target, name) {
return function(expectedArg1, expectedArg2) {
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11963 次 |
| 最近记录: |