代码之家  ›  专栏  ›  技术社区  ›  janko

在使用typeof进行检查时,没有调用window.external上的参数方法

  •  13
  • janko  · 技术社区  · 16 年前

    我试图在 System.Windows.Forms.WebBrowser 控制。预计javascript代码将通过 window.external 反对。在调用上的方法之前 窗口.外部 ,javascript应该检查方法是否存在。如果不存在,则代码应调用泛型回退方法。

    // basic idea
    if (typeof(window.external.MyMethod) != 'undefined') {
        window.external.MyMethod(args);
    } else {
        window.external.Generic("MyMethod", args);
    }
    

    但是,使用 typeof 似乎已经调用了该方法。也就是说,如果 MyMethod 接受任何正数的参数,上面的代码都可以正常工作;但是,如果 我的方法 是无参数方法,则表达式 typeof(window.external.MyMethod) 不会检查其类型,但也会调用它。

    这种行为有什么办法吗?我能逃脱这个表情吗 window.external.MyMethod 防止方法调用发生?

    6 回复  |  直到 16 年前
        1
  •  9
  •   Eric Lippert    16 年前

    我还没有调试过你的确切情况,但我相信我的超能力可以计算出这里发生了什么。

    jscript语言区分了 使用 功能性的 提到 是的。当你说

    x = f;
    

    也就是说“给变量x分配一个对f所标识的函数的引用”。它 提及 相比之下,

    x = f();
    

    使用 它的意思是“调用由f标识的函数并将返回值赋给x”。

    简而言之,jscript中的函数本质上就是我们所认为的 委托类型的属性 在C语言中。

    有些语言没有这种区别。在vbscript中,如果你说 x = f f是一个函数,这意味着调用该函数,与 x = f() . vbscript在语法上并没有对函数的使用和提及进行很强的区分。

    这一切的实现方式都是使用com;具体地说,我们使用ole自动化。当分派对象的字段以获取其值时,jscript引擎将传递表示“property get”或“method invoke”的标志,具体取决于它是使用还是提到。

    但是假设您要调度的对象是在预期它将从vb调用的情况下编写的。也许是写的 在VB中 . 一个vb对象说“哦,我知道你在问我这个方法的价值”是完全合理合法的。因为我不明白提到一个方法和使用它之间的区别,所以不管传递哪个标志,我都会调用它”。

    我不知道是否有解决办法,但我愿意赌一美元 被调用的对象假设调用方需要vb语义。

        2
  •  6
  •   Mark Hall    14 年前

    我找到这个了

    if ('MyMethod' in window.external)
    

    不调用MyMethod

        3
  •  0
  •   Sean Kinsey    16 年前

    试试这个

    /* Methods for feature testing
     * From http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
     */
    function isHostMethod(object, property){
        var t = typeof object[property];
        return t == 'function' ||
        (!!(t == 'object' && object[property])) ||
        t == 'unknown';
    }
    
    function isHostObject(object, property){
        return !!(typeof(object[property]) == 'object' && object[property]);
    }
    
    if (isHostObject(window.external, "MyMethod")) {....
    
        4
  •  0
  •   funkybro    12 年前

    这种效果可以在桌面Internet Explorer中看到。脚本,如:

    for (var i in window) {
        console.log('window.' + i + ' = ' + window[i]);
    }
    

    一旦失败 external 已到达。

    看来 window.external 不是普通的javascript对象,而是vbscript对象。

    所以像这样的陈述 窗口.外部 window['external'] 因此是vbscript语句 --就像埃里克说的, 窗口.外部 在vbscript中等于 window.external() .

    非常混乱。这似乎也是唯一一个在Internet Explorer上以这种方式运行的对象。

    对于使用IE Mobile的跨浏览器移动Web应用程序 window.external.Notify() 要在Windows Phone 8上与本机通信,但它也希望设置 document.location 在ios上,测试 window.external.Notify 似乎是合乎逻辑的——但不是因为这个原因。

    我还没有找到防止这种情况发生的方法;在指定 type="text/javascript" script 标签。

        5
  •  0
  •   Dirk Bester    12 年前

    因此,唯一的选择就是解决办法: 1)不要使用0参数函数。 2)做一个检查函数(取一个参数)来检测是否有外部调用。

    if (typeof(window.external.HasExternal(null)) != 'undefined')
    

    并检查外部函数是否全部存在而不是函数。 3)对于每个你想要的无参数函数,要么让它使用一个假参数,要么为它添加一个1参数检查函数,如果外部代码在它支持的函数中有所不同。

        6
  •  -1
  •   Fyodor Soikin    16 年前

    我真的不确定它是否有用,但是试着 window.external["MyMethod"] .

    如果没有帮助,请尝试将此值存储在变量中,然后检查该变量的类型。看看有没有帮助。