我刚接手另一位开发人员的项目,代码中有很多if语句:
if( value != null || value != "" || value != undefined )
{
doSomeThing();
}
虽然好,但到处使用时会有点混乱。有没有更好,更整洁的方式来写这个?我在想这个
if( value.length > 0 || value != undefined )
{
doSomeThing();
}
你们都在想什么?
由于
斯蒂芬
答案 0 :(得分:9)
几乎就是这样,但是if( value.length > 0 || value != undefined )
当值为null
value.length
时会发生运行时错误TypeError:错误#1009,因为您试图访问{{1}上的属性价值。
所以你必须在之前检查该值是非空的,例如:
null
或其他更短的形式:
if (value!=null&&value.length>0) {doSomeThing();}
一个注意事项:
除非值的类型为if ((value||"").length>0) {doSomeThing();}
,否则它不能取值未定义,它将为*
。
null
答案 1 :(得分:3)
我喜欢写更积极的陈述。程序员的陈述检查某些东西 not null ,但他的意思是; 如果存在:
如果是数组或字符串,我使用它:
if ( value && value.length > 0 ) doSomething();
但是在对象或DisplayObjects的情况下,我用它来检查它是否存在。
if ( mc ) doSomething();
在大多数情况下,这已经足够了。
答案 2 :(得分:3)
以下是您可以使用的一些时间轴代码。
import flash.display.MovieClip;
import flash.display.Sprite;
var object : Object;
var array : Array;
var number : Number;
var integer : int;
var uinteger : uint;
var string : String;
var xml : XML;
var regexp : RegExp;
var movieClip : MovieClip;
var array2 : Array = [];
var object2 : Object = {};
trace( "uninstantiated Object =", object, "Boolean cast =", Boolean( object ) );
trace( "uninstantiated Array =", array, "Boolean cast =", Boolean( array ) );
trace( "uninstantiated Number =", number, "Boolean cast =", Boolean( number ) );
trace( "uninstantiated int =", integer, "Boolean cast =", Boolean( integer ) );
trace( "uninstantiated uint =", uinteger, "Boolean cast =", Boolean( uinteger ) );
trace( "uninstantiated String =", string, "Boolean cast =", Boolean( string ) );
trace( "empty String =", "", "Boolean cast =", Boolean( "" ) );
trace( "uninstantiated XML =", xml, "Boolean cast =", Boolean( xml ) );
trace( "uninstantiated RegExp =", regexp, "Boolean cast =", Boolean( regexp ) );
trace( "uninstantiated MoveClip =", movieClip, "Boolean cast =", Boolean( movieClip ) );
trace( "instantiated Array with length 0 XML =", array2, "Boolean cast =", Boolean( array2 ) );
trace( "instantiated Object with no properties =", object2, "Boolean cast =", Boolean( object2 ) );
trace( "uninstantiated index of instantiated array =", array2[4], "Boolean cast =", Boolean( array2[4] ) );
trace( "uninstantiated property of instantiated object =", object2[ "color" ], "Boolean cast =", Boolean( object2[ "color" ] ) );
try
{
//will throw an error
trace( "uninstantiated property of uninstatinated class =", movieClip.x, "Boolean cast =", Boolean( movieClip.x ) );
}
catch ( e : Error ) {}
/*
output:
uninstantiated Object = null Boolean cast = false
uninstantiated Array = null Boolean cast = false
uninstantiated Number = NaN Boolean cast = false
uninstantiated int = 0 Boolean cast = false
uninstantiated uint = 0 Boolean cast = false
uninstantiated String = null Boolean cast = false
empty String = Boolean cast = false
uninstantiated XML = null Boolean cast = false
uninstantiated RegExp = null Boolean cast = false
uninstantiated MoveClip = null Boolean cast = false
instantiated Array with length 0 XML = Boolean cast = true
instantiated Object with no properties = [object Object] Boolean cast = true
uninstantiated index of instantiated array = undefined Boolean cast = false
uninstantiated property of instantiated object = undefined Boolean cast = false
As you can see, in general, you can just test for instantiation by using
if ( variableName ) ...
But this will fail if you want to think of instantiated-but-empty Arrays and Objects
as false. Note that it will also fail, generating an error, if you check for properies
of uninitialized classes, e.g.
var sprite : Sprite;
if ( sprite.x ) trace( "found x" ); //error, because sprite = null and null doesn't have an x property.
You can write a more liberal test like this:
*/
function exists( value : * ) : Boolean
{
var result : Boolean = true;
if ( ! value ) return false;
if ( value is Array && ! value.length ) return false;
if ( value.constructor.toString() == "[class Object]" )
{
result = false;
for each ( var prop in value ) { result = true; break; }
}
return result;
}
//tests
trace( "exists( object ) =", exists( object ) );
trace( "exists( array ) =", exists( array ) );
trace( "exists( number ) =", exists( number ) );
trace( "exists( integer ) =", exists( integer ) );
trace( "exists( uinteger ) =", exists( uinteger ) );
trace( "exists( string ) =", exists( string ) );
trace( "exists( '' ) =", exists( "" ) );
trace( "exists( xml ) =", exists( xml ) );
trace( "exists( regexp ) =", exists( regexp ) );
trace( "exists( movieClip ) =", exists( movieClip ) );
trace( "exists( array2 ) =", exists( array2 ) );
trace( "exists( object2 ) =", exists( object2 ) );
trace( "exists( array2[4] ) =", exists( array2[4] ) );
trace( "exists( object2[ 'color' ] ) =", exists( object2[ "color" ] ) );
var sprite : Sprite = new Sprite();
trace( "INSTANTIATED: exists( sprite ) = ", exists( sprite ) );
var object3 : Object = { color : 0xFFFFFF };
trace( "INSTANTIATED OBJECT WITH PROPERTY: exists( object3 ) =", exists( object3 ) );
var array3 : Object = [ 1 ];
trace( "INSTANTIATED ARRAY WITH LENGTH: exists( array3 ) =", exists( array3 ) );
/*
output:
exists( object ) = false
exists( array ) = false
exists( number ) = false
exists( integer ) = false
exists( uinteger ) = false
exists( string ) = false
exists( '' ) = false
exists( xml ) = false
exists( regexp ) = false
exists( movieClip ) = false
exists( array2 ) = false
exists( object2 ) = false
exists( array2[4] ) = false
exists( object2[ 'color' ] ) = false
INSTANTIATED: exists( sprite ) = true
INSTANTIATED OBJECT WITH PROPERTY: exists( object3 ) = true
INSTANTIATED ARRAY WITH LENGTH: exists( array3 ) = true
One more note: be careful with ints and uints. They are always initialized. Whereas other variables
point to null, undefined or NaN until you give them values, ints and uints are automatically intialized
to zero. There is not way to have an int that doesn't point to a value:
var num : Number;
var i : int;
trace( num ); // NaN
trace( i ); //0
In general, that's okay, because 0 == false:
var i : int;
if ( i ) trace( "false" ); //false
But I've mixed myself up before with code like this:
var color : int = getColorValueFromXML();
if ( color ) drawCircleWithColor( color );
In the above code, I only want to draw a circle if color is initialized.
However, color will ALWAYS bee initialized, to zero if not to anything else.
But what if getColorValueFromXML() returns 0x00000. We think of that as the
color black. But I see a black circle, because 0x000000 is also the same
as 0. And, in a conditional, 0 parses as false:
if ( 0x000000 ) drawCircleWithColor(); //drawCircleWithColor won't run!
*/