在 Ruby 中,我认为您可以调用尚未定义的方法,但仍可以捕获所调用方法的名称,并在运行时处理此方法。
Javascript 可以做同样的事情吗?
在 Ruby 中,我认为您可以调用尚未定义的方法,但仍可以捕获所调用方法的名称,并在运行时处理此方法。
Javascript 可以做同样的事情吗?
method_missing不适合 JavaScript,原因与 Python 中不存在的原因相同:在两种语言中,方法只是碰巧是函数的属性;和对象通常具有不可调用的公共属性。与 Ruby 相比,对象的公共接口是 100% 的方法。
JavaScript 中需要的是一个钩子来捕获对缺失属性的访问,无论它们是否是方法。Python 有它:请参阅__getattr__特殊方法。
Mozilla的__noSuchMethod__提议在充满它们的语言中引入了另一个不一致之处。
JavaScript 的前进方向是Proxy 机制(也在ECMAscript Harmony 中),它更接近于自定义属性访问的 Python 协议,而不是 Ruby 的method_missing。
您正在解释的 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/,了解有关即将实施的更多详细信息。
目前没有,没有。有一个关于 ECMAScript Harmony 的提议,称为proxies,它实现了一个类似的(实际上,更强大的)功能,但是 ECMAScript Harmony 还没有出现,并且可能不会在几年内出现。
我为 javascript 创建了一个库,让您可以method_missing
在 javascript 中使用:https : //github.com/ramadis/unmiss
它使用 ES6 代理来工作。这是一个使用 ES6 类继承的示例。但是,您也可以使用装饰器来实现相同的结果。
import { MethodMissingClass } from 'unmiss'
class Example extends MethodMissingClass {
methodMissing(name, ...args) {
console.log(`Method ${name} was called with arguments: ${args.join(' ')}`);
}
}
const instance = new Example;
instance.what('is', 'this');
> Method what was called with arguments: is this
您可以使用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]
您将使用p
代替myObj
.
您应该小心,get
因为它会拦截p
. 因此,p.specialPants()
会导致错误,因为specialPants
返回的是字符串而不是函数。
真正发生的事情unknownMethod
等同于以下内容:
var unk = p.unkownMethod;
unk('hi', 'bye', 'ok');
这是有效的,因为函数是 javascript 中的对象。
如果您知道期望的参数数量,则可以在返回的函数中将它们声明为正常的。
例如:
...
get: function (target, name) {
return function(expectedArg1, expectedArg2) {
...