【问题标题】:Javascript instanceof & typeof in GWT (JSNI)GWT (JSNI) 中的 Javascript instanceof 和 typeof
【发布时间】:2011-02-25 23:50:13
【问题描述】:

我在尝试通过 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');
}

而我们要调用这个函数的用户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") );
}-*/;

问题是:

  • 为什么instanceof指令总是返回false
  • 为什么typeof总是返回"object"
  • 如何传递这些对象以便正确识别它们?

【问题讨论】:

  • "string"(字符串字面量)和 new String("string")(String 对象)是有区别的。此外,任何不是文字的东西都是对象(IE 中的某些情况除外),所以对象测试应该排在最后,尤其是。如果你使用 return 语句。
  • 感谢您的评论,$wnd.test(new String("Some text"));在这种情况下也是如此。

标签: javascript gwt types jsni


【解决方案1】:

既然其他所有问题似乎都已得到解答,那就让我得到这个:

如何传递这些对象以便正确识别它们?

GWT 会自动为字符串、整数等原始类型执行此操作。因此您可以只写:

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

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

请参阅the docs 了解一些额外说明。

对于数组,有一堆包装类:JsArrayJsArrayBooleanJsArrayIntegerJsArrayNumberJsArrayString

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

【讨论】:

    【解决方案2】:

    instanceof 不应在您的示例中一直返回 false 除非您正在测试来自不同窗口的对象,因为来自一个窗口的数组不是 另一个窗口的Array 构造函数的实例。

    当您需要测试特定事物并且您在一个窗口中操作时,使用instanceof 非常棒(您必须注意字符串原语与 scunliffe 指出的字符串对象事物)。请注意,您需要小心您的订单,因为数组是 instanceof Object(以及 Array);这适用于Strings 和所有其他对象。

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

    function classify(arg) {
        return Object.prototype.toString.call(arg);
    }
    

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

    function show(arg) {
        alert(classify(arg));
    }
    

    你会得到这些结果:

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

    无论您要测试的对象来自哪个窗口,也无论您使用的是字符串原语还是 String 实例,您都会得到这些结果。

    【讨论】:

    • 简洁令人印象深刻!
    【解决方案3】:

    您的测试函数总是返回 false,因为您没有提供 return 语句...而 String 在 JavaScript 中很有趣...如果您使用 new String("asdf"); 那么使用 instanceof 将起作用,如果您只是创建一个字符串"asdf" 那么你需要使用 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);
      }
    }
    

    (注意还有其他类型...日期、数字、自定义对象等)

    【讨论】:

      猜你喜欢
      • 2013-01-04
      • 2013-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多