2

问题涉及在调用其中的方法或变量之前检查变量是否为空:

if(order && order.reference && order.reference.quote)
{
   var length:int = order.reference.quote.findLength();
}

如果有一个函数可以与任何对象一起检查到最后一个对象变量的空指针,那不是很好吗:

IE

     // This would check first if order, then order.reference, then order.reference.quote      
    //was null
    if(NullUtil.notNull(order.reference.quote))
    {
        .....
    }

有任何想法吗?

4

2 回答 2

3

其他一些语言使用存在访问器运算符,例如?.(请参阅CoffeeScript

如果您不太担心性能,可以执行以下操作:

function notNull(object:*, properties:String):Boolean
{
    if (object == null) return false;
    var props:Array = properties.split(".")
    for(var i:uint = 0; i < props.length; i++)
    {
        if(object[props[i]] == null) return false;
        object = object[props[i]]
    }

    return true;
}

然后将其用于:notNull(order, "reference.quote");

但这不是很漂亮,但你可以用一些魔法把它清理一下Proxy

例如,考虑以下代码:

import flash.utils.Proxy;
import flash.utils.flash_proxy;

dynamic class Existential extends Proxy {

    private var _object:*;


    public function Existential(object:*) {
        _object = object;
    }

    flash_proxy override function getProperty(name:*):* {
        var object:* = _object;

        if (object == null) return null;

        var props:Array = name.toString().split("$");

        for(var i:uint = 0; i < props.length; i++)
        {
            if(object[props[i]] == null) return null;
            object = object[props[i]]
        }

        return object;
    }
}

然后,您可以使用它来包装其他对象并使用$而不是.作为临时存在的 getter 来访问它们。

    obj = {};
    eObj = new Existential(obj);
    eObj.what$is$this // null

    obj = { what: { "is":  { "this": 1 } } } ;
    eObj = new Existential(obj);
    eObj.what$is$this  // 1 

但我想性能会很糟糕,我不想将它用于任何性能关键的生产代码。但它可能会给你一些想法。

于 2013-04-23T16:23:45.097 回答
0

我会用try..catch.

try
{
   length = order.reference.quote.findLength();
}
catch(e:ReferenceError){}

优点:

  • 避免代码中的条件。
  • 相同的代码适用于任何对象和任何深度。

缺点:

  • 与您的代码不完全相同。例如,如果其中一个属性是引发 ReferenceError 的 getter,则您的代码将引发错误,但此代码不会。
  • 使用try..catch引入了一些开销。
  • 调试起来有点困难。
于 2013-04-23T17:07:47.723 回答