最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript instanceof & typeof in GWT (JSNI) - Stack Overflow

programmeradmin4浏览0评论

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:

  • why instanceof instructions will always return false?
  • why typeof will always return "object" ?
  • how to pass these objects so that they were recognized properly?

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:

  • why instanceof instructions will always return false?
  • why typeof will always return "object" ?
  • how to pass these objects so that they were recognized properly?
Share Improve this question edited May 31, 2010 at 14:36 rafalry asked May 31, 2010 at 13:27 rafalryrafalry 2,6706 gold badges24 silver badges39 bronze badges 2
  • 1 there is a difference between "string" (a string literal) and new String("string") (a String object). besides, anything that is not a literal is an Object (except some cases in IE), so the Object test should e last, esp. if you use return statements. – Dormilich Commented May 31, 2010 at 13:35
  • Thanks for your ment, $wnd.test( new String("Some text") ); does the same in this case. – rafalry Commented May 31, 2010 at 14:09
Add a ment  | 

3 Answers 3

Reset to default 7

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 Strings 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 ing from and regardless of whether you use a string primitive or a String instance.

Since everything else seem to have been answered let me get this one:

how to pass these objects so that they were recognized properly?

GWT does this automagically for primitive types like Strings, Integers, etc. So you can write just:

public static native String test1()/ *-{
   return "adfasdf";
}-*/;

public static native int test2()/ *-{
   return 23;
}-*/;

See the docs for some extra notes.

For arrays, there are a bunch of wrapper classes: JsArray, JsArrayBoolean, JsArrayInteger, JsArrayNumber, JsArrayString.

public static native JsArrayString test3()/ *-{
   return ['foo', 'bar', 'baz'];
}-*/;

your test function always returns false because you do not supply a return statement... and String is funny in JavaScript... if you use new String("asdf"); then using instanceof will work, if you just create a string with "asdf" then you will need to use typeof.

function test(arg){
  if (arg instanceof Array){
    return 'Array';
  } else if(arg instanceof String || typeof(arg) == 'String'){
    return 'String';
  } else if (arg instanceof Object){
    return 'Object';
  } else {
    return typeof(arg);
  }
}

(note there are other types... Date, Number, Custom Objects etc.)

发布评论

评论列表(0)

  1. 暂无评论