代码之家  ›  专栏  ›  技术社区  ›  Tor Valamo

是否有方法捕获访问不存在的属性或方法的尝试?

  •  17
  • Tor Valamo  · 技术社区  · 16 年前

    例如,此代码:

    function stuff() {
      this.onlyMethod = function () {
        return something;
      }
    }
    
    // some error is thrown
    stuff().nonExistant();
    

    有没有一种方法可以像PHP那样做呢 __call

    function stuff() {
      this.onlyMethod = function () {
        return something;
      }
      // "catcher" function
      this.__call__ = function (name, params) {
        alert(name + " can't be called.");
      }
    }
    
    // would then raise the alert "nonExistant can't be called".
    stuff().nonExistant();
    

    也许我该多解释一下我在做什么。

    该对象包含另一个对象,该对象具有应可直接通过该对象访问的方法。但是这些方法对于每个对象都是不同的,所以我不能仅仅路由它们,我需要能够动态地调用它们。

    我知道我可以让它里面的物体成为主物体的属性 stuff.obj.existant()

    4 回复  |  直到 16 年前
        1
  •  10
  •   Anurag    16 年前

    有一种方法可以为不存在的方法上的调用定义泛型处理程序,但它是非标准的。签出 noSuchMethod getting support 为了它。

    要使用它,请在任何对象上定义此方法:

    var a = {};
    
    a.__noSuchMethod__ = function(name, args) {
        console.log("method %s does not exist", name);
    };
    
    a.doSomething(); // logs "method doSomething does not exist"
    

    但是,如果您想要一个跨浏览器方法,那么简单的try catch blocks就可以:

    try {
        a.doSomething();
    }
    catch(e) {
        // do something
    }
    

    如果您不想在整个代码中编写try-catch,那么可以向主对象添加一个包装器,所有函数调用都通过该包装器进行路由。

    function main() {
        this.call = function(name, args) {
            if(this[name] && typeof this[name] == 'function') {
                this[name].call(args);
            }
            else {
                // handle non-existant method
            }
        },
        this.a = function() {
            alert("a");
        }
    }
    
    var object = new main();
    object.call('a') // alerts "a"
    object.call('garbage') // goes into error-handling code
    
        2
  •  17
  •   Minifyre Nicolas NZ    9 年前

    好吧,看来有了和声(ES6),就会有一种方法,而且比其他方法更复杂 programing languages

    obj  = new Proxy({}, 
            { get : function(target, prop) 
                { 
                    if(target[prop] === undefined) 
                        return function()  {
                            console.log('an otherwise undefined function!!');
                        };
                    else 
                        return target[prop];
                }
            });
    obj.f()        ///'an otherwise undefined function!!'
    obj.l = function() {console.log(45);};
    obj.l();       ///45
    

    代理将把处理程序未处理的所有方法转发到普通对象中。所以它就像它不在那里一样,你可以通过代理修改目标。还有更多的处理程序,甚至有一些用于修改原型获取,以及用于任何属性访问的设置程序yes!。

    正如您所想象的,现在并不是所有浏览器都支持这个功能,但是在Firefox中,您可以很容易地使用代理界面,只需转到 MDN docs

    如果能在这上面添加一些语法上的糖分,我会更高兴,但是无论如何,在一种已经强大的语言中拥有这种能力是很好的。祝你今天愉快!:)

    我没有复制rosettacodejs条目,我更新了它。

        3
  •  2
  •   MasterAM    16 年前

    看来你对JS很在行。 不幸的是,我不知道语言中有这样的特性,而且我很确定它不存在。在我看来,最好的选择是使用统一的接口并对其进行扩展,或者扩展对象继承的原型(然后可以在继续进行方法调用之前使用instanceof),或者使用有点麻烦的“&&'运算符以避免访问不存在的属性/方法:

    obj.methodName && obj.methodName(art1,arg2,...);
    

        4
  •  1
  •   fmsf    16 年前

    您还可以检查该方法是否存在。

    if(a['your_method_that_doesnt_exist']===undefined){
    //method doesn't exist
    }