GWT中的Javascript instanceof&typeof(JSNI)

raf*_*lry 3 javascript gwt types jsni

我在GWT中尝试通过JSNI使用一些对象时遇到了一个奇怪的问题.假设我们有定义函数的javscript文件:

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');
}
Run Code Online (Sandbox Code Playgroud)

而我们想要调用这个函数用户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") );
}-*/;
Run Code Online (Sandbox Code Playgroud)

问题是:

  • 为什么instanceof说明会一直回来false
  • 为什么typeof总会回来"object"
  • 如何传递这些对象以便正确识别它们?

T.J*_*der 7

instanceof不应该在你的例子可以返回false所有的时间,除非你从不同的窗口测试对象,因为从一个窗口的数组是不是对的实例Array不同窗口的构造函数.

instanceof当你需要测试特定的东西并且你在一个窗口内操作时,使用是很好的(你必须要知道scunliffe指出的字符串原语与String对象的东西).请注意,您需要注意您的订单,因为数组是instanceof Object(以及Array); 这适用于Strings和所有其他对象.

有一个替代方案没有窗口问题,switch如果您正在进行调度,它可以很容易地用于语句等:

function classify(arg) {
    return Object.prototype.toString.call(arg);
}
Run Code Online (Sandbox Code Playgroud)

这看起来很奇怪,但它的作用是使用原型toString上的函数,该函数Object具有已定义的行为(而不是使用您正在测试的实际对象可能具有的任何覆盖,这可能具有不同的行为).所以给定这个功能:

function show(arg) {
    alert(classify(arg));
}
Run Code Online (Sandbox Code Playgroud)

你会得到这些结果:

show({});               // [object Object]
show("a");              // [object String]
show(new String("a"));  // [object String]
show([]);               // [object Array]
show(/n/);              // [object RegExp]
show(function() { });   // [object Function]
Run Code Online (Sandbox Code Playgroud)

并且无论您使用字符串原语还是String实例,无论您正在测试的对象来自哪个窗口,您都将获得这些结果.