我可以决定调用不存在的对象方法时会发生什么吗?

Ben*_*aum 3 javascript

我的代码看起来像这样:

obj.foo(); // obj might, or might not have a `foo` method.
Run Code Online (Sandbox Code Playgroud)

我想知道是否可以覆盖obj.foo在我的代码中调用时发生的事情,例如:

obj.foo = function(){ alert ("Hello"); });
obj.onCallNonExistentMethod = function(){ // I know this is imaginary syntax
    alert("World");
}
obj.foo(); // alerts "Hello"
delete obj.foo;
obj.foo(); // alerts "World" , would TypeError without the method missing handler.
Run Code Online (Sandbox Code Playgroud)

据我所知,在Ruby中可能是method_missingconst_missing类似的东西.

我可以覆盖在JavaScript中调用不存在的对象方法时发生的事情吗?如果可以,我该怎么办?

目标是验证我提供给用户的API,以便他们可以安全地使用API​​,我可以更清楚地警告他们错误.

Ben*_*aum 5

两年前本杰明,你不太了解行为打字的概念吗?

幸运的是,你很快就会发现,自从编写这个问题以来,界面在JavaScript中并不是结构性的,甚至还写了一个库来解决你在这里提到的确切问题,只是从不使用它.

那么,回答你的问题:

  • 是的,完全可以做到这一点.
  • 您可能不应该为您提供的案例.

怎么做

如果您只需要通过Proxy API支持真正(非常真实)的新浏览器,这是完全可行的.

var realObject = { foo: function(){ alert("Bar"); }); // our fooable api
var api = new Proxy({}, {
    get: function(target, name){
        if(name in target){ // normal API call
            return target[name]; 
        }
        // return whatever you want instead of the method:
        return function(){ alert("Baz"); });
    }
});
api.foo(); //alerts Bar
api.bar(); //alerts Baz
api.IWillNotBuyThisRecordItIsScratched(); // alerts Baz
Run Code Online (Sandbox Code Playgroud)

所以,虽然浏览器支持非常不稳定,但它

为什么你不应该

接口传达行为,在诸如拼写错误之类的情况下,可以(并且应该)通常由静态分析工具(如jshint或ternjs)捕获.

检查拼写错误的工具根本不足以传达JavaScript中的行为,类型检查被认为是反模式,通常 - 在JavaScript,Ruby和Python等语言中,您知道您将获得的类型.