I've encountered an curious problem while trying to use some objects through JSNI in GWT. Let's say we have javscript file with the function defined:
test.js:
function test(arg){
var type = typeof(arg);
if (arg instanceof Array)
alert('Array');
if (arg instanceof Object)
alert('Object');
if (arg instanceof String)
alert('String');
}
And the we want to call this function user JSNI:
public static native void testx()/ *-{
$wnd.test( new Array(1, 2, 3) );
$wnd.test( [ 1, 2, 3 ] );
$wnd.test( {val:1} );
$wnd.test( new String("Some text") );
}-*/;
The questions are:
instanceof
instructions will always return false
?typeof
will always return "object"
?instanceof
shouldn't be returning false all the time in your example unless you're testing objects from a different window, because an array from one window is not an instance of the Array
constructor of a different window.
Using instanceof
is great when you need to test for a specific thing and you're operating within one window (you do have to be aware of the string primitive vs. String object thing that scunliffe pointed out). Note that you need to be careful of your order, since an array is an instanceof
Object
(as well as Array
); this applies to String
s and all other objects as well.
There's an alternative that doesn't have the window issue and which can readily be used for switch
statements and the like if you're doing dispatch:
function classify(arg) {
return Object.prototype.toString.call(arg);
}
That looks odd, but what it does is use the toString
function on the Object
prototype, which has a defined behavior (rather than using any override that the actual object you're testing may have, which may have different behavior). So given this function:
function show(arg) {
alert(classify(arg));
}
you'll get these results:
show({}); // [object Object]
show("a"); // [object String]
show(new String("a")); // [object String]
show([]); // [object Array]
show(/n/); // [object RegExp]
show(function() { }); // [object Function]
and you'll get those results regardless of what window the object you're testing is coming from and regardless of whether you use a string primitive or a String
instance.